<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Steve Hannah</title>
    <description>The latest articles on DEV Community by Steve Hannah (@shannah).</description>
    <link>https://dev.to/shannah</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F605408%2Fb5a995c8-4907-4aa3-9055-e729b3446f36.jpeg</url>
      <title>DEV Community: Steve Hannah</title>
      <link>https://dev.to/shannah</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/shannah"/>
    <language>en</language>
    <item>
      <title>jDeploy Now Has a Desktop GUI — Build, Package, and Publish Java Desktop Apps with Zero Dependencies</title>
      <dc:creator>Steve Hannah</dc:creator>
      <pubDate>Mon, 21 Apr 2025 16:22:39 +0000</pubDate>
      <link>https://dev.to/shannah/jdeploy-now-has-a-desktop-gui-build-package-and-publish-java-desktop-apps-with-zero-dependencies-44p5</link>
      <guid>https://dev.to/shannah/jdeploy-now-has-a-desktop-gui-build-package-and-publish-java-desktop-apps-with-zero-dependencies-44p5</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;TL;DR: jDeploy is now a fully self-contained desktop app with a modern GUI. It lets you build and publish Swing, JavaFX, and Codename One apps to GitHub or npm — without needing to install npm or any other tooling.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  🚀 What is jDeploy?
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.jdeploy.com" rel="noopener noreferrer"&gt;jDeploy&lt;/a&gt; is an open-source tool that makes it dead simple to package and distribute Java desktop apps.&lt;/p&gt;

&lt;p&gt;It solves the "last mile" problem for Swing and JavaFX devs by bundling your app and publishing it to GitHub Releases or npm, complete with a native installer or web-launchable version.&lt;/p&gt;

&lt;p&gt;Previously, jDeploy was a CLI tool. Now, it has a full-featured &lt;strong&gt;desktop GUI&lt;/strong&gt;, built with Swing and deployed using jDeploy itself — in true dogfooding fashion 🐶&lt;/p&gt;




&lt;h3&gt;
  
  
  ✅ What's New in the Desktop App?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Modern GUI:&lt;/strong&gt; No need to use the CLI unless you want to. Launch, create, build, and publish from a native app.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero dependencies:&lt;/strong&gt; No npm, Node, or CLI setup required. Everything is bundled.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Built-in project templates&lt;/strong&gt; for Swing, JavaFX, and Codename One.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Publish with a click&lt;/strong&gt; to GitHub Releases or npm.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IDE integration&lt;/strong&gt; (IntelliJ, NetBeans, Eclipse, VS Code).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Web Preview support&lt;/strong&gt; via CheerpJ.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secure token-based auth&lt;/strong&gt; with 2FA support for GitHub and npm.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  ⚡️ Create and Publish in Under 30 Seconds
&lt;/h3&gt;

&lt;p&gt;With the new app:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Select a project template.&lt;/li&gt;
&lt;li&gt;Enter a name and title.&lt;/li&gt;
&lt;li&gt;Press "Create".&lt;/li&gt;
&lt;li&gt;Press "Publish" (with optional build).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's it. Your app is published and shareable.&lt;/p&gt;




&lt;h3&gt;
  
  
  🖼 Web Preview with CheerpJ
&lt;/h3&gt;

&lt;p&gt;jDeploy now includes a &lt;strong&gt;"Web Preview"&lt;/strong&gt; feature powered by &lt;a href="https://leaningtech.com/cheerpj/" rel="noopener noreferrer"&gt;CheerpJ&lt;/a&gt;, which converts Java desktop apps into web apps you can run in the browser (locally or hosted).&lt;/p&gt;

&lt;p&gt;It’s still evolving, but current support includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Java 11–17&lt;/li&gt;
&lt;li&gt;Full Swing API&lt;/li&gt;
&lt;li&gt;Early JavaFX support in CheerpJ 4.0 (coming soon)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The "Swing Maven Starter" template works out of the box.&lt;/p&gt;




&lt;h3&gt;
  
  
  🔐 Auth Improvements
&lt;/h3&gt;

&lt;p&gt;Authentication for publishing has always been tricky, depending on the user's OS, npm version, or CLI environment.&lt;/p&gt;

&lt;p&gt;Now, jDeploy uses &lt;strong&gt;personal access tokens&lt;/strong&gt;, stored securely in your system keychain. It supports two-factor authentication for both GitHub and npm.&lt;/p&gt;




&lt;h3&gt;
  
  
  📦 Want to Contribute?
&lt;/h3&gt;

&lt;p&gt;Project templates live in the &lt;a href="https://github.com/shannah/jdeploy-project-templates" rel="noopener noreferrer"&gt;jdeploy-project-templates GitHub repo&lt;/a&gt;. If you have a useful template for a Java project setup, feel free to open a PR.&lt;/p&gt;

&lt;p&gt;You can also check out the &lt;a href="https://github.com/shannah/jdeploy" rel="noopener noreferrer"&gt;main GitHub repo for jDeploy&lt;/a&gt; to file issues, give feedback, or join discussions.&lt;/p&gt;




&lt;h3&gt;
  
  
  🙌 Try It Out
&lt;/h3&gt;

&lt;p&gt;If you've ever built (or plan to build) a Java desktop app, give the new jDeploy desktop app a try.&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://jdeploy.substack.com/p/a-new-chapter-for-jdeploy-the-desktop" rel="noopener noreferrer"&gt;Read the full launch post&lt;/a&gt;&lt;br&gt;&lt;br&gt;
👉 &lt;a href="https://www.jdeploy.com" rel="noopener noreferrer"&gt;Get started at jdeploy.com&lt;/a&gt;&lt;br&gt;&lt;br&gt;
👉 &lt;a href="https://github.com/shannah/jdeploy" rel="noopener noreferrer"&gt;View the source on GitHub&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;💬 I'd love to hear what you think! Drop a comment below or join the discussion on GitHub.&lt;/p&gt;

</description>
      <category>java</category>
      <category>javafx</category>
      <category>showdev</category>
      <category>tooling</category>
    </item>
    <item>
      <title>Downloading Youtube Videos with Pytube and Shellmarks
</title>
      <dc:creator>Steve Hannah</dc:creator>
      <pubDate>Wed, 22 Dec 2021 20:33:24 +0000</pubDate>
      <link>https://dev.to/shannah/downloading-youtube-videos-with-pytube-and-shellmarks-4igm</link>
      <guid>https://dev.to/shannah/downloading-youtube-videos-with-pytube-and-shellmarks-4igm</guid>
      <description>&lt;p&gt;Pytube is a great little Python utility for downloading videos from youtube as .mp4 files. It has a command-line interface that makes downloading videos as simple as entering the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;pytube https://www.youtube.com/watch?v&lt;span class="o"&gt;=&lt;/span&gt;....
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace the URL with the Youtube URL of the video you want to download.&lt;/p&gt;

&lt;p&gt;To make things even easier, I wrote a shellmarks wrapper script for this that provides an intuitive GUI form.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--69M2QjvC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aewx5njkcatm9r6k8p8p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--69M2QjvC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aewx5njkcatm9r6k8p8p.png" alt="Shellmarks dialog for pytube" width="404" height="244"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Simply paste in the URL and press “Download”, and it will download the video to your “Downloads” directory.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;Pytube installation instructions can be found &lt;a href="https://pytube.io/en/latest/user/install.html"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The TLDR of the install instructions, if you have Python 3 already installed, is to open Terminal and enter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;pytube
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If pip happens to be the python2 version, you can try&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;pip3 &lt;span class="nb"&gt;install &lt;/span&gt;pytube
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;instead.&lt;/p&gt;

&lt;p&gt;The Shellmarks installation instructions can be found here&lt;/p&gt;

&lt;p&gt;The TLDR of the install instructions, if you have npm installed, is to open Terminal and enter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; shellmarks
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I have uploaded the shellmarks wrapper script here&lt;/p&gt;

&lt;p&gt;To install it in shellmarks, begin by opening shellmarks by opening Terminal and running&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;shellmarks
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After shellmarks opens, open the menu in the upper right corner and select “Import Script from URL”&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ROyWmlnV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vomkwshepz6qbz33p6el.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ROyWmlnV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vomkwshepz6qbz33p6el.png" alt="Shellmarks menu" width="194" height="208"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You will the be prompted to enter the URL to the script:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0FJ7tMJN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ga97ryg7rgvdh4kqxc34.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0FJ7tMJN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ga97ryg7rgvdh4kqxc34.png" alt="Shellmarks import script dialog" width="473" height="171"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The URL to the raw script is &lt;/p&gt;

&lt;p&gt;&lt;a href="https://raw.githubusercontent.com/shannah/shellmarks/master/sample-scripts/pytube.sh"&gt;https://raw.githubusercontent.com/shannah/shellmarks/master/sample-scripts/pytube.sh&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Paste that URL into the field and press “OK”.&lt;/p&gt;

&lt;p&gt;This will install the script and refresh the shellmarks catalog. You should now see an entry as follows:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mFMrvAG9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/93c7dntqnx6ahfi6vfz1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mFMrvAG9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/93c7dntqnx6ahfi6vfz1.png" alt="Shellmarks catalog entry for pytube" width="768" height="318"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Press “Run” to run the script. You’ll see the dialog prompting you for the video URL you want to download.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yhSRFaNw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jmm5wzbjxlb42f0mo2op.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yhSRFaNw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jmm5wzbjxlb42f0mo2op.png" alt="Shellmarks dialog for running pytube" width="404" height="244"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Paste any youtube URL in here and press “Download”. You’ll be able to see the progress of the download in the terminal you used to open shellmarks. When the download is complete, it will open the video in your preferred movie player.&lt;/p&gt;

&lt;p&gt;NOTE: This script was developed for MacOS, and would need to be modified slightly to work on Linux or Windows.&lt;/p&gt;

&lt;p&gt;You can now access this script directly from within Shellmarks anytime. If you want to run it directly from the command-line you could also simply run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;shellmarks pytube
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  References:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://pytube.io/en/latest/"&gt;Pytube&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/shannah/shellmarks"&gt;Shellmarks Github Repo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://shannah.github.io/shellmarks/manual/"&gt;Shellmarks Manual&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Photo by &lt;a href="https://unsplash.com/@alexbemore?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Alexander Shatov&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/videos?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>tutorial</category>
      <category>bash</category>
      <category>devops</category>
    </item>
    <item>
      <title>Video: Building a Codename One Project for iOS</title>
      <dc:creator>Steve Hannah</dc:creator>
      <pubDate>Wed, 07 Apr 2021 11:46:34 +0000</pubDate>
      <link>https://dev.to/shannah/video-building-a-codename-one-project-for-ios-2j54</link>
      <guid>https://dev.to/shannah/video-building-a-codename-one-project-for-ios-2j54</guid>
      <description>&lt;p&gt;This is the third video in my series about &lt;a href="https://start.codenameone.com"&gt;our new online tool, Codename One initializr&lt;/a&gt;, which allows you to generate a Maven starter project for a native mobile app in one click. The &lt;a href="https://dev.to/shannah/online-tool-to-generate-ios-android-starter-project-k7h"&gt;first video&lt;/a&gt; showed how to generate the starter project, and run it in the Codename One simulator. The &lt;a href="https://dev.to/shannah/how-to-deploy-a-codename-one-app-on-android-5h8o"&gt;second video&lt;/a&gt; showed how to build and deploy the project on an Android device. In this video I show how to build and deploy the project on an iOS device.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/J7UJrtkXHqg"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  TLDW (Too Long Didn't Watch):
&lt;/h2&gt;

&lt;p&gt;This video starts out with my Codename One project already opened in IntelliJ. See &lt;a href="https://dev.to/shannah/online-tool-to-generate-ios-android-starter-project-k7h"&gt;this post&lt;/a&gt; for steps on how to generate this project.&lt;/p&gt;

&lt;p&gt;In the video I demonstrate two different approaches for building the iOS app.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Locally (0:55-2:45)&lt;/strong&gt; - Requires a Mac with Xcode Installed.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Using Build Server (6:45-8:35)&lt;/strong&gt; - Can be built on Windows, Linux, or Mac. With no special requirements beyond Maven and the JDK. You just need a free Codename One account.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;NOTE: I also show how to generate your iOS certificates and provisioning profiles using the Certificate Wizard (2:45-6:45), as this is required to build apps for iOS.&lt;/p&gt;

&lt;h3&gt;
  
  
  Building Locally
&lt;/h3&gt;

&lt;p&gt;The &lt;em&gt;local build&lt;/em&gt; option generates an Xcode project, which we then open and build using Xcode.&lt;/p&gt;

&lt;p&gt;To trigger this build, select "Local Builds" &amp;gt; "Xcode iOS Project":&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Rm4LiGDR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sjhannah.com/blog/wp-content/uploads/2021/04/Screen-Shot-2021-04-06-at-5.51.41-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Rm4LiGDR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sjhannah.com/blog/wp-content/uploads/2021/04/Screen-Shot-2021-04-06-at-5.51.41-AM.png" alt="Screen Shot 2021-04-06 at 5.51.41 AM" width="448" height="180" class="aligncenter size-full wp-image-583"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then press the "Run" button.&lt;/p&gt;

&lt;p&gt;It takes the ParparVM compiler a minute or two to do its thing, but when it's done, it opens the generated Xcode project in Xcode.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cLnvXnC0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sjhannah.com/blog/wp-content/uploads/2021/04/Screen-Shot-2021-04-06-at-5.55.03-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cLnvXnC0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sjhannah.com/blog/wp-content/uploads/2021/04/Screen-Shot-2021-04-06-at-5.55.03-AM.png" alt="Screen Shot 2021-04-06 at 5.55.03 AM" width="911" height="517" class="aligncenter size-full wp-image-584"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once opened, I press the "Run" button on the Xcode toolbar and wait while it compiles the project. When it is done, it opens the iOS simulator with my app running in it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--E5BOzwG_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sjhannah.com/blog/wp-content/uploads/2021/04/Screen-Shot-2021-04-06-at-5.58.05-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--E5BOzwG_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sjhannah.com/blog/wp-content/uploads/2021/04/Screen-Shot-2021-04-06-at-5.58.05-AM.png" alt="Screen Shot 2021-04-06 at 5.58.05 AM" width="317" height="665" class="aligncenter size-full wp-image-585"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Building with the Build Server
&lt;/h3&gt;

&lt;p&gt;One of the nice things about Codename One is that it provides a build server with all of the native build tools installed and up-to-date. This simplifies the process of building native apps greatly. You can build your project for iOS, Android, Mac Desktop, Windows Desktop, Windows UWP, and Javascript without requiring any special build tools installed beyond the JDK. Building for any of these targets is as simple as pressing a button, or running a Maven goal.&lt;/p&gt;

&lt;h4&gt;
  
  
  Generating Certificates
&lt;/h4&gt;

&lt;p&gt;Building for iOS requires that you have an Apple developer account. Additionally, Apple requires you to generate certificates and provisioning profiles for your apps. This is by far the most painful part of app development. To help ease the pain, Codename One provides a certificate wizard to help generate these. Before I can submit my first iOS build, I need to walk through the certificate wizard to generate these certificates. The certificate wizard process starts at approx 2:45 in the video, and runs until 6:45.&lt;/p&gt;

&lt;p&gt;To access the certificate wizard, I need to open Codename One Settings. I do this by selecting "Tools" &amp;gt; "Codename One Settings" from IntelliJ's configuration menu, then pressing the "Run" button.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YZO1mgZV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sjhannah.com/blog/wp-content/uploads/2021/04/Screen-Shot-2021-04-06-at-6.11.27-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YZO1mgZV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sjhannah.com/blog/wp-content/uploads/2021/04/Screen-Shot-2021-04-06-at-6.11.27-AM.png" alt="Screen Shot 2021-04-06 at 6.11.27 AM" width="372" height="163" class="aligncenter size-full wp-image-586"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This will open The Control Center (aka Codename One Settings, aka Codename One Preferences):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zj5Y_9zl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sjhannah.com/blog/wp-content/uploads/2021/04/Screen-Shot-2021-04-06-at-6.12.53-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zj5Y_9zl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sjhannah.com/blog/wp-content/uploads/2021/04/Screen-Shot-2021-04-06-at-6.12.53-AM.png" alt="Screen Shot 2021-04-06 at 6.12.53 AM" width="872" height="460" class="aligncenter size-full wp-image-587"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once there, I select "Device Settings" &amp;gt; "iOS" &amp;gt; "Certificate Wizard" from the navigation menu on the left.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gAPOLMc9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sjhannah.com/blog/wp-content/uploads/2021/04/Screen-Shot-2021-04-06-at-6.13.55-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gAPOLMc9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sjhannah.com/blog/wp-content/uploads/2021/04/Screen-Shot-2021-04-06-at-6.13.55-AM.png" alt="Screen Shot 2021-04-06 at 6.13.55 AM" width="207" height="530" class="aligncenter size-full wp-image-588"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This displays the login form for the certificate wizard:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qyPc20VI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sjhannah.com/blog/wp-content/uploads/2021/04/Screen-Shot-2021-04-06-at-6.15.40-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qyPc20VI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sjhannah.com/blog/wp-content/uploads/2021/04/Screen-Shot-2021-04-06-at-6.15.40-AM.png" alt="Screen Shot 2021-04-06 at 6.15.40 AM" width="644" height="330" class="aligncenter size-full wp-image-589"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;IMPORTANT: You need to use your Apple Developer account to login to this form. NOT your Codename One account.&lt;/p&gt;

&lt;p&gt;In the video I spliced out some of the waiting time. The login can take a little while, so be patient. Once logged in, it shows me a list of my registered development devices, and I can select which ones I want to be able to deploy this app to for testing and debugging.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lOtbgQiB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sjhannah.com/blog/wp-content/uploads/2021/04/Screen-Shot-2021-04-06-at-6.17.06-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lOtbgQiB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sjhannah.com/blog/wp-content/uploads/2021/04/Screen-Shot-2021-04-06-at-6.17.06-AM.png" alt="Screen Shot 2021-04-06 at 6.17.06 AM" width="653" height="506" class="aligncenter size-full wp-image-590"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The above screenshot has all of the rows greyed out. When you log in, you'll see device names and UDIDs listed on this form.&lt;/p&gt;

&lt;p&gt;Generally I select all of them. If this is your first time building an iOS app, then you may not have any devices listed yet, and you'll need to click on the "Manage Devices" button and follow the instructions there.&lt;/p&gt;

&lt;p&gt;Next, it asks me to confirm that I want to regenerate my certificates, as it has detected that I already have certificates generated in my Apple account. In my case, I say "yes", I'd like to regenerate them, but in most cases, you would select "no", to just use your existing certificates.&lt;/p&gt;

&lt;p&gt;TIP: If your certificates were generated by the certificate wizard, then a copy of them has been stored inside the &lt;em&gt;$HOME/.codenameone/iosCerts&lt;/em&gt; directory, and the wizard will use them automatically. If they weren't generated by the certificate wizard, and you choose &lt;em&gt;not&lt;/em&gt; to regenerate them, then you may need to specify the location of your certificates in the iOS Settings section.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oh-raszm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sjhannah.com/blog/wp-content/uploads/2021/04/Screen-Shot-2021-04-06-at-6.25.52-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oh-raszm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sjhannah.com/blog/wp-content/uploads/2021/04/Screen-Shot-2021-04-06-at-6.25.52-AM.png" alt="Screen Shot 2021-04-06 at 6.25.52 AM" width="648" height="290" class="aligncenter size-full wp-image-592"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, it asks whether we want to generate push certificates. In this case, since this is just a basic &lt;em&gt;Hello World&lt;/em&gt; app, we don't need push, so I leave these options OFF.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SQ-BTo56--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sjhannah.com/blog/wp-content/uploads/2021/04/Screen-Shot-2021-04-06-at-6.27.38-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SQ-BTo56--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sjhannah.com/blog/wp-content/uploads/2021/04/Screen-Shot-2021-04-06-at-6.27.38-AM.png" alt="Screen Shot 2021-04-06 at 6.27.38 AM" width="653" height="282" class="aligncenter size-full wp-image-595"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After clicking next, it will churn for a bit, and if all goes well, it will show us the message that our certificates were generated and installed successfully.&lt;/p&gt;

&lt;p&gt;Just to be sure that my settings are saved. I click on the &lt;em&gt;hamburger&lt;/em&gt; menu in the upper right, and select "Save".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--i_sv3neU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sjhannah.com/blog/wp-content/uploads/2021/04/Screen-Shot-2021-04-06-at-6.29.40-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--i_sv3neU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sjhannah.com/blog/wp-content/uploads/2021/04/Screen-Shot-2021-04-06-at-6.29.40-AM.png" alt="Screen Shot 2021-04-06 at 6.29.40 AM" width="198" height="330" class="aligncenter size-full wp-image-596"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Sending the Build
&lt;/h4&gt;

&lt;p&gt;Now that the certificates are generated, we can send the build. Back in IntelliJ, I select "Build Server" &amp;gt; "iOS Debug Build"&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5fH7iaXv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sjhannah.com/blog/wp-content/uploads/2021/04/Screen-Shot-2021-04-06-at-6.32.38-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5fH7iaXv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sjhannah.com/blog/wp-content/uploads/2021/04/Screen-Shot-2021-04-06-at-6.32.38-AM.png" alt="Screen Shot 2021-04-06 at 6.32.38 AM" width="384" height="193" class="aligncenter size-full wp-image-597"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;NOTE: If this is your first time building with the build server, you may be prompted for your Codename One username and password.&lt;/p&gt;

&lt;p&gt;I then follow the progress of the build on the Codename One website.&lt;/p&gt;

&lt;p&gt;When it's finished, I get a set of links to do things like download the .ipa, or install the app on device.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YodDaSy8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sjhannah.com/blog/wp-content/uploads/2021/04/Screen-Shot-2021-04-06-at-6.34.32-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YodDaSy8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sjhannah.com/blog/wp-content/uploads/2021/04/Screen-Shot-2021-04-06-at-6.34.32-AM.png" alt="Screen Shot 2021-04-06 at 6.34.32 AM" width="378" height="348" class="aligncenter size-full wp-image-598"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Get Started
&lt;/h2&gt;

&lt;p&gt;Getting started with your own native app is really easy. Just go to the &lt;a href="https://start.codenameone.com"&gt;Codename One initializr&lt;/a&gt;, enter your app details, and press "Download".&lt;/p&gt;

&lt;p&gt;For more information about Codename One, see &lt;a href="https://www.codenameone.com"&gt;the Codename One website&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ios</category>
      <category>java</category>
      <category>kotlin</category>
      <category>mobile</category>
    </item>
    <item>
      <title>How to Deploy a Codename One App on Android</title>
      <dc:creator>Steve Hannah</dc:creator>
      <pubDate>Tue, 06 Apr 2021 12:20:28 +0000</pubDate>
      <link>https://dev.to/shannah/how-to-deploy-a-codename-one-app-on-android-5h8o</link>
      <guid>https://dev.to/shannah/how-to-deploy-a-codename-one-app-on-android-5h8o</guid>
      <description>&lt;p&gt;In my &lt;a href="https://dev.to/shannah/online-tool-to-generate-ios-android-starter-project-k7h"&gt;last post&lt;/a&gt; I showed off the new &lt;a href="https://dev.to/shannah/online-tool-to-generate-ios-android-starter-project-k7h"&gt;Codename One initializr online tool&lt;/a&gt;, generating a Maven project, and opened it in IntelliJ.&lt;/p&gt;

&lt;p&gt;In this video I demonstrate how to build an Android app with this project.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/9ZK15NicWDQ"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  TLDW (Too Long Didn't Watch):
&lt;/h2&gt;

&lt;p&gt;Here's the gist of the video. There are two different build options for Android:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Build Server &amp;gt; Android&lt;/li&gt;
&lt;li&gt; Local Builds &amp;gt; Android Gradle Project&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In this video, I start with option 2, "Android Gradle Project". This option &lt;em&gt;does NOT&lt;/em&gt; require a Codename One account, and performs all of the build on your local machine. It &lt;em&gt;does&lt;/em&gt; require that you have Android Studio installed.&lt;/p&gt;

&lt;p&gt;I select "Local Builds" &amp;gt; "Android Gradle Project" from the Configuration menu of IntelliJ, and then press "Run".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsjhannah.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F03%2FScreen-Shot-2021-03-30-at-9.25.41-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsjhannah.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F03%2FScreen-Shot-2021-03-30-at-9.25.41-AM.png" alt="Screen Shot 2021-03-30 at 9.25.41 AM"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This generates an Android Studio project, and automatically opens it in Android studio.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsjhannah.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F03%2FScreen-Shot-2021-03-30-at-9.27.42-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsjhannah.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F03%2FScreen-Shot-2021-03-30-at-9.27.42-AM.png" alt="Screen Shot 2021-03-30 at 9.27.42 AM"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I then press "Run" in the Android Studio, and wait while it builds and installs the app on my Android Emulator.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsjhannah.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F03%2FScreen-Shot-2021-03-30-at-9.29.25-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsjhannah.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F03%2FScreen-Shot-2021-03-30-at-9.29.25-AM.png" alt="Screen Shot 2021-03-30 at 9.29.25 AM"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the second part of this video, I use the "Build Server" &amp;gt; "Android" build option, which is much simpler, and doesn't require you to install Android Studio. All you need is IntelliJ (Actually you don't even need IntelliJ, as you could just build the project using Maven), and it will use the Codename One build server to generate the Android app.&lt;/p&gt;

&lt;p&gt;After selecting "Build Server" &amp;gt; "Android" from the configuration menu, I press "Run" to start the build.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsjhannah.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F03%2FScreen-Shot-2021-03-30-at-9.30.39-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsjhannah.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F03%2FScreen-Shot-2021-03-30-at-9.30.39-AM.png" alt="Screen Shot 2021-03-30 at 9.30.39 AM"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It then redirects me to the Codename One dashboard where I can monitor the build progress and, download the app when it's done.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsjhannah.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F03%2FScreen-Shot-2021-03-30-at-9.31.37-AM-1024x288.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsjhannah.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F03%2FScreen-Shot-2021-03-30-at-9.31.37-AM-1024x288.png" alt="Screen Shot 2021-03-30 at 9.31.37 AM"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  More Background
&lt;/h2&gt;

&lt;p&gt;When we decided to &lt;a href="https://www.codenameone.com/blog/moving-to-maven.html" rel="noopener noreferrer"&gt;migrate to Maven&lt;/a&gt;, we also made the choice to add &lt;a href="https://www.codenameone.com/blog/you-can-now-build-android-and-ios-apps-locally.html" rel="noopener noreferrer"&gt;official local build targets&lt;/a&gt; so that developers are no longer reliant on the build server to build their Android and iOS apps. Building locally has always been an option, but it was difficult, and we didn't provide support for it. By adding an official local build option, we are hoping that developers who balked at Codename One because they didn't want to be reliant on us for their builds will give us another look.&lt;/p&gt;

&lt;p&gt;If you haven't heard of &lt;a href="https://www.codenameone.com" rel="noopener noreferrer"&gt;Codename One&lt;/a&gt; yet, I encourage you to check us out. In my biased opinion, we are the best game in town, if you're looking to build native mobile apps in Java or Kotlin.&lt;/p&gt;

&lt;p&gt;It only takes a minute to create and build your first project using &lt;a href="https://start.codenameone.com" rel="noopener noreferrer"&gt;Codename One initializr&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>android</category>
      <category>java</category>
      <category>kotlin</category>
    </item>
    <item>
      <title>Online Tool to Generate iOS/Android Starter Project</title>
      <dc:creator>Steve Hannah</dc:creator>
      <pubDate>Tue, 30 Mar 2021 13:56:19 +0000</pubDate>
      <link>https://dev.to/shannah/online-tool-to-generate-ios-android-starter-project-k7h</link>
      <guid>https://dev.to/shannah/online-tool-to-generate-ios-android-starter-project-k7h</guid>
      <description>&lt;p&gt;The &lt;a href="https://start.codenameone.com"&gt;Codename One initializr&lt;/a&gt; is an online tool for generating a Codename One starter project. You can select either Kotlin or Java, then you can download the project and open it in your local IDE.&lt;/p&gt;

&lt;p&gt;In this 5-minute video I use the initializr to generate a bare-bones Java project, which I open and run in IntelliJ. I also give a brief tour of the project structure and build targets.&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/XuS1-SV0RkQ"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  TLDW (Too Long Didn't Watch):
&lt;/h2&gt;

&lt;p&gt;Here's the gist. Go to &lt;a href="https://start.codenameone.com"&gt;Codename One initializr&lt;/a&gt;, select either the "Java Bare-bones Project" or "Kotlin Bare-bones Project" from the "Template" select box, and press "Download"&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FmSR0xHJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sjhannah.com/blog/wp-content/uploads/2021/03/Screen-Shot-2021-03-30-at-6.36.39-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FmSR0xHJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sjhannah.com/blog/wp-content/uploads/2021/03/Screen-Shot-2021-03-30-at-6.36.39-AM.png" alt="Screen Shot 2021-03-30 at 6.36.39 AM" width="291" height="430" class="aligncenter size-full wp-image-558"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Extract the resulting project, and open it in IntelliJ (or your preferred IDE).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vU6DpK5I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sjhannah.com/blog/wp-content/uploads/2021/03/Screen-Shot-2021-03-30-at-6.39.27-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vU6DpK5I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sjhannah.com/blog/wp-content/uploads/2021/03/Screen-Shot-2021-03-30-at-6.39.27-AM.png" alt="Screen Shot 2021-03-30 at 6.39.27 AM" width="642" height="362" class="aligncenter size-full wp-image-559"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Press "Run" and wait while Maven downloads the build dependencies. It will open the Codename One simulator with the simple "Hello World" app running.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--V4xzEvme--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sjhannah.com/blog/wp-content/uploads/2021/03/Screen-Shot-2021-03-30-at-6.41.00-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--V4xzEvme--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sjhannah.com/blog/wp-content/uploads/2021/03/Screen-Shot-2021-03-30-at-6.41.00-AM.png" alt="Screen Shot 2021-03-30 at 6.41.00 AM" width="311" height="499" class="aligncenter size-full wp-image-560"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The project is a Maven project, with the following build targets:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  iOS&lt;/li&gt;
&lt;li&gt;  Android&lt;/li&gt;
&lt;li&gt;  Mac Desktop&lt;/li&gt;
&lt;li&gt;  Windows Desktop&lt;/li&gt;
&lt;li&gt;  Javascript App&lt;/li&gt;
&lt;li&gt;  Windows UWP App,&lt;/li&gt;
&lt;li&gt;  JavaSE Desktop App&lt;/li&gt;
&lt;li&gt;  Xcode Project&lt;/li&gt;
&lt;li&gt;  Android Studio Project&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the video, I also demonstrate how to add a Button that, when clicked, opens a dialog. This is achieved by opening the &lt;em&gt;common/src/main/java/com/example/myapp/MyApp.java&lt;/em&gt; file, and adding the following to the &lt;em&gt;start()&lt;/em&gt; method:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Button btn = new Button("Click Me");
btn.addActionListener(evt-&amp;gt;{
    Dialog.show("Hello World", "You Clicked Me", "OK", null);
});
hi.add(btn);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;I'll soon be posting some follow-up videos to demonstrate how to build and deploy the project to iOS and Android devices, so watch the RSS feed or follow me (wherever you receive my posts), to be notified when these are posted.&lt;/p&gt;

&lt;h2&gt;
  
  
  More Background
&lt;/h2&gt;

&lt;p&gt;I've been working hard over the past several months to migrate Codename One from Ant to Maven. That process is &lt;a href="https://www.codenameone.com/blog/moving-to-maven.html"&gt;now complete&lt;/a&gt;, and it has enabled us to introduce a new, simpler workflow for creating Codename One projects. The &lt;a href="https://start.codenameone.com"&gt;Codename One initializr&lt;/a&gt; uses our Codename One App Project maven archetype to generate a starter project. Right now we just have two starter templates: Bare-bones projects for Java or Kotlin. We will be adding more templates soon, including some templates for full-featured apps that you can take and customize.&lt;/p&gt;

&lt;p&gt;I've very proud of this work, and I'm excited about some of the new things that it will enable.&lt;/p&gt;

&lt;p&gt;If you're a Java or Kotlin developer and you're interested in making cross-platform native mobile apps, you should give &lt;a href="https://www.codenameone.com"&gt;Codename One&lt;/a&gt; a try. You just might be surprised at how pleasant the experience is.&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>java</category>
      <category>ios</category>
      <category>android</category>
    </item>
    <item>
      <title>Farewell to TenFourFox</title>
      <dc:creator>Steve Hannah</dc:creator>
      <pubDate>Tue, 30 Mar 2021 12:24:39 +0000</pubDate>
      <link>https://dev.to/shannah/farewell-to-tenfourfox-2l0b</link>
      <guid>https://dev.to/shannah/farewell-to-tenfourfox-2l0b</guid>
      <description>&lt;p&gt;I was saddened by the &lt;a href="https://tenfourfox.blogspot.com/2020/04/the-end-of-tenfourfox-and-what-ive.html"&gt;news&lt;/a&gt; that development on &lt;a href="http://www.floodgap.com/software/tenfourfox/"&gt;TenFourFox&lt;/a&gt;, the Firefox port for Mac OS X 10.4, will be ending with its upcoming release.&lt;/p&gt;

&lt;p&gt;I keep several old Power Macs running 10.4 (which is the last version that will run Classic), and the TenFourFox browser is a staple of my "bootstrap" CD. I don't use it much, as browsing the web on these old Machines is pretty slow, but it gave me joy just knowing that somewhere out there, someone was keeping the flame of these old computers alive. I liken this feeling to knowing that my childhood home is still lived in by my parents - the feeling that if I returned to visit, everything would be there as I left it, and I could, if only for a brief moment, be a child again.&lt;/p&gt;

&lt;p&gt;To the developer behind TenFourFox, I'd like to wish you the best in your retirement. Thank you for your service all these years.&lt;/p&gt;

</description>
      <category>powerpc</category>
      <category>mac</category>
      <category>firefox</category>
      <category>retro</category>
    </item>
  </channel>
</rss>
