Latest posts from Codename One.
Blog

Exif Orientation Tag and Smart Downloads
On 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. More 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. ...

Dark Mode
We 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. Detecting Dark Mode Dark mode can be detected using APIs in the CN and Display classes. Specifically isDarkMode() and setDarkMode(Boolean). Notice 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. ...

Moving Away from Java FX
Codename 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. Then 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. ...

Samsung Lowers Resolution Randomly
A 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… The 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. But the odd thing was this: if the apps package name was changed the resolution went back to normal! ...

RAD Chat Room – Part 5
This is part 5 of the RAD Chatroom tutorial. You can find part 1 here, part 2 here, part 3 here and part 4 here. Adding 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. First we’ll define a new action called “capturePhoto”, and add to the the TEXT_ACTIONS category of our view node. public 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. ...

RAD Chat Room – Part 4
This is part 4 of the RAD Chatroom tutorial. You can find part 1 here, part 2 here and part 3 here. Adding 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: ...

RAD Chat Room – Part 3
This is part 3 of the RAD Chatroom tutorial. You can find part 1 here and part 2 here. Adding 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: ...

RAD Chat Room – Part 2
This is part 2 of the RAD Chatroom tutorial. You can find part 1 here. Adding a “Send” Button A “Send” 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: // 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 "SEND" 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 “embed” and where. ...

RAD Chat Room – Part 1
This 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. The finished product will look like the following: You can download the full source of this tutorial’s project here. You can also try it out yourself here. ...

Thread Errors
I 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. With the current version of Codename One we now have a new generic error handling API for easy threads: public 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. ...

Xcode 11 is now the Default
We hope you’re all keeping safe! We 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. This 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… ...

Xcode 11 Migration
Apple 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. The 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… ...