2017-01-22

Dart for Java developers: putting it all together

Welcome back to my small series of posts about Dart for Java developers. In the previous installment I promised to actually use the Model class soon. A very simple scenario can be seen in the file main2.dart. If main2.dart is invoked from the command line, one must pass exactly three arguments:

  1. input temperature unit
  2. value of the input temperature
  3. output temperature unit
The program is quite simple. We have two import statements as we need both model.dart and converter.dart. The first one gives us (among other things) the definition of a class named Model. We instantiate it using the familiar new keyword. After that we set the unit for both input and output temperature. enumFor() is a top-level function defined in model.dart. It checks if one of the enum values ends with the string passed as the only formal parameter. Remember that we pass them to the program via the command line. So to satisfy the string comparison, we need to enter exactly degreesCelsius, degreesFahrenheit or kelvin.

The temperature value itself is converted from String to double through stringToDouble(). This function can be found in converter.dart. It uses an internationalization package named intl. This package is capable of honoring locale-specific settings like the decimal mark and the thousands separator. My example explicitly sets the locale to German, which means that english 1,234.56 has to be entered as 1.234,56. Feel free to experiment with this. Why not reading the name of the locale from the command line?

Once the model has been set up, calculateOutTemperature() can be called to do the actual computation. After that, the result can be printed from the getter outTemperatureAsString(). Dart has first-class support of getters and setters, so no method parenthesis are needed.

2017-01-15

Dart for Java Developers: The Model class

In my previous post, Dart for Java Developers: Into the code, we looked at two Dart source files, converter.dart and main.dart. Both contained so-called top level functions, that is, making code available without the need to put it in a class. Recall that each Dart file is a library. A library with a top level main() function is a script. Libraries are combined or grouped to form so-called packages. Packages can be easily distributed and reused. The Dart SDK comes with a package and asset manager called pub. Packages are described in a specification file named pubspec.yaml. It consists of, among other entries, a name, a version and a list of dependencies. For example, Temperature Converter relies on the internationalization package intl. A package can live anywhere. Some packages are on GitHub. Others reside at pub.dartlang.org. You can publish your packages there, too. Here is a description what you need to do: https://www.dartlang.org/tools/pub/publishing. The pub tool is invoked either through the plugin of your IDE (if you open a pubspec in IntelliJ you get a commands list at the top of the editor window), or from the console. If you fancy the shell, remember to include /bin in your PATH environment variable.

Now, let's turn to code. Recall that my original Temperature Converter app was written in Java using JavaFX. There is a Model class that uses Converter. So, Model has both state and behavior. The class is used as follows:

  1. Instantiate it
  2. Set the domain data (unit of input and output temperature and the temperature itself)
  3. Perform the calculation
  4. Grab the output string
  5. Back to 2.

Let's see how this looks like in Dart. We start with a library statement (which gives the library a name), followed by an import. We rely on the converter library you have encountered in the previous post. After that you see an enum definition. Compared to, for example Java, Dart enums allow less customization. Currently the string representation of the enum evaluates to enum_name.enum_value. To be able to more easily map user interface elements to enum values (you will see that later) I implemented a convenience method named enumFor(). Dart enums cannot be defined inside classes. Now let's take a look at the Model class (it's inside model.dart). Besides the lack of access level modifiers (more on that soon) the code looks comfortingly familiar. With two very welcomed exceptions. Have you spotted the get and set keywords? Dart has language level support for getters and setters.

In the next installment we will actually use the new Model class. But if you cannot wait to try it out, just grab the code from GitHub and start playing.

2017-01-11

Dart for Java Developers: Into the code

In a previous post, Dart for Java Developers: First Contact I offered you a glimpse at the language by creating a very basic project using the project creation wizard of IntelliJ IDEA. Today I would like to dig a little deeper by showing you how to rewrite a Java program in Dart. I will use a small temperature conversion app which I wrote for a series of talks about Java on mobile devices. You can find the JavaFX version on GitHub.

The program consists of four classes, a user interface definition and a resource bundle. TemperatureConverter is the main class. It loads the ui from an fxml file and instantiates a controller class called FXMLDocumentController. This controller binds ui components and actions to a model class named Model. This class holds the actual domain data and invokes code from the Converter class. It contains a couple of static methods that do the actual temperature calculation. Let us start with this one.

As you can see in the source, although doing different computations, the innards of the methods are mostly the same, that is, doing some arithmetics using the primitive double data type. The method stringToDouble() converts a string to a double value honoring locale specific settings like the decimal mark and the thousands separator. doubleToString() creates a string consisting of a double value with its fractional part omitted if it is zero, and a suffix. How could we do this in Dart?

For your convenience I set up a GitHub repository. Please take a look at converter.dart. Possibly to a bit of a surprise, it does not contain a class, but several top level functions. unitDegreesCelsius, unitDegreesFahrenheit and unitKelvin are compile time constants. _f is declared final, so its value can be assigned only once, but obviously not during compile time. I really like the compact function definition using =>, which takes an expression. If more statements are needed, the traditional body using curly braces comes into play. Also very nice is the string interpolation you can see in _doubleToString(). You can access the value of an expression inside a string by using ${expression}. If the expression is an identifier, the {} can be omitted.

To see the calculations in action I have provided main.dart. If a dart file contains a toplevel main()-function it is called a script. The following screenshot shows the execution of the program in Visual Studio Code.
Editing and running the script in Visual Studio Code

Dart programs and libraries are often distributed as packages. Packages follow certain rules regarding structure and content. You can see a bit of this in the screenshot. I might go into a little more detail in a future post. The json file you can see in the screenshot is not part of that package but helps running the program in Visual Studio Code. Want to try for yourself? Great. Just clone the repo and start playing.

2017-01-08

TKWeek 1.9.0 released to Google Play

It has been far too long since I last updated TKWeek. Finally, 1.9.0 is now available in the Play store. A remarkable new feature, in fact the hightlight of this version, are notifications about upcoming events. Here is how this looks like:

Summarized notifications on Android 7.1

Expanded notifications on Android 7.1

The notifications are bundled notifications on Android 7.1. Older versions show the traditional bigview notifications, which unfortunately cannot be expanded.

Android Wear knows stacked notifications. Here is how this looks like:

Partly visible notification

Collapsed notification stack

Expanded notification stack

2016-12-28

It is here

DSC02550

I have been writing books for ten years, and it is still exciting to get the free author’s copies, because this means that now everybody can get get the book.

2016-12-09

Dart for Java Developers: First Contact

The programming language Dart is not exactly new. So you may ask yourself, why I am writing about it right now. Partly that is because I am going to talk about Dart at OOP 2017 in Munich and I want to advertise it a little. Partly that is because I finished updating my Android book, so I have some time to spare. Well, and partly that is …just because…

In a couple of short posts I will show you how Java devs can make themselves familiar with Dart. Let us start with the development environment. IntelliJ IDEA has gained widespread attention of Java devs throughout the years. It's the IDE of choice for many of us, so why not write Dart programs using it? The first step is to download and install the plugin.

The Dart plugin for IntelliJ IDEA

Once the plugin is installed, we can begin creating a Dart project.

Creating a Dart project in IntelliJ

As you can see, two things are missing: Dartium and the Dart SDK. You can get both from https://www.dartlang.org/tools/sdk. The components can either be installed using platform-specific package managers, or manually. I just downloaded the .zip files and unpacked them in /opt. After I inserted the base directories of both Dartium and the Dart SDK, the project wizard looks like this:

The project wizard with paths to Dart SDK and Dartium

As you can see, we can now choose from a couple of project templates. Dartium, by the way, is a Chromium derivate with Dart built in. More on that later… As I would like to start from scratch, I unchecked Generate sample content. The final page of the project wizard then looks like this:

Final page of the project wizard

This gives us an empty project, so I now need to create a file, for example Demo.dart. Once I have entered the typical hello world stuff, the IDE looks like this. The program can be executed from the menu bar.

Editing and running a small Dart program

First contact… having been made.

Edited 2017/01/03: Replaced a screenshot where the path to Dartium was wrong

2016-11-08

A friendly face on all platforms

Java looks beautiful on all major platforms. Just take a look…

This is an ordinary JavaFX application:

A plain JavaFX application

Here, we see the same business logic with a native Android ui:

Native Android ui

Now, the business logic baked in a Gluon Mobile app… First, on Android:

Gluon app on Android

And now on iOS:

Gluon app on iOS

Awesome, right?

One more thing… Java business logic, with native iOS ui; built with Multi-OS Engine

Java business logic, native iOS ui

Check out the sources on GitHub.

Or, join me at TopConf Tallinn.

2016-11-07

Trouble baseline aligning RadioButtons?

Do you want to achieve something like this…

Screenshot: properly baseline aligned RadioButtons

… but keep getting something like this…

Screenshot: not properly aligned RadioButtons

Then, please check out my answer on Stack Overflow.

2016-10-29

Activating the demo user

Android 7.1 will bring us a new UserManager-method called isDemoUser(). According to the docs…

Checks if the calling app is running in a demo user. When running in a demo user, apps can be more helpful to the user, or explain their features in more detail.

But… how to I activate a demo user? If this is common knowledge, please feel free to let me know.

Winking smile

Anyway, I figured out how to activate demo mode in the Android emulator:

  1. Activate the developer options by clicking on the Build number on the About emulated device page seven times
  2. Open the Developer options page
  3. Click on Demo mode

This shows a page with the same title:

Screenshot: Demo mode settings page

2016-10-20

When a piece of cake is turning round

Not so long ago a couple of Google apps became piece of cake – sort of, that is.

Screenshot_20161020-133618

Funny to see that in Android 7.1 icons will turn round. Sorry, but I could not resist the pun.

Smile

BTW, Android Studio 2.2.2 helps creating round icons with an updated Image Asset Wizard:

Image Asset Wizard in Android Studio 2.2.2

2016-10-18

See me in Tallinn

I have been quite busy the past weeks, finishing works on the 4th edition of my book Android 7 – Das Praxisbuch für Entwickler. It will be in stores before Christmas. But there is more… In a few weeks I will be heading towards Tallinn, doing a workshop and a talk about Java on mobile devices. I am very excited to join awesome people. Click on the following teaser images to get more information about my presentations.

TopConf Tallinn 2016: Thomas Künneth, Java to go. Mobile apps with Java

TopConf Tallinn 2016: Thomas Künneth, Java on mobile devices

2016-09-28

macOS Sierra quick tip: temporarily disable MySQL Server starts

After upgrading to macOS Sierra, my MacBook Pro would no longer shut down properly but get stuck with a black screen. Turns out that the issue might be somehow related to MySQL, as unchecking Automatically Start MySQL Server on Startup fixed the issue for me after the next forced restart.

MySQL Server control panel

I am, by the way, running MySQL 5.7.12

Let me know if you experienced this issue, too.

2016-09-20

A note on updates

Android Studio updates usually imply having fun. To me this looks like this…

Project needs updating #1

Project needs updating #2

Currently, I am in the process of updating my book. I already have updated 40 of 80 samples, so this nice thing means I enjoy the fun of doing this stuf 80 more times. 40 times for re-doing, and 40 times for the remaining projects. I am excited to see Android 7.1; will bring us a new API level I am sure, implying I could update the 80 samples once more. Winking smile

2016-08-01

On editing fxml files with custom components in Scene Builder

Trying to open a .fxml file of a Gluon Mobile sample application in Scene Builder failed...



...for obvious reasons...


com.gluonhq.charm.glisten.mvc.View is no standard JavaFX control.

To make that class known to Scene Builder we just need to put it on its classpath. Right? The following screenshots describe a workaround when using NetBeans. If there are other, less archaic approaches, I'd love to hear them.

First we need the .jar file.



Now comes the interesting part. How to tell Scene Builder?

There is a config file called SceneBuilder.cfg. On my Windows machine it's situated in C:\Users\tkuen\AppData\Local\SceneBuilder\app.


Just quit Scene Builder and then put the fully qualified path right beside app.classpath=

Here is how Scene Builder will render another .fxml file contain Glisten controls. 


I do not consider myself a Scene Builder expert, so I may be missing a simpler solution. Also, it would be great to have custom components in the palette. Need to check that. Again, any hint is greatly appreciated.

Added Gluon-Port to OpenWeatherMapWeather

Yesterday I introduced you to a new repo of mine, which contains the same app for different platforms. Today I have added a Gluon port. The app as such is rather small. What is important about it is to see similarities as well as differences of the implementations.



Next on the agenda is a UWP app.

2016-07-31

Added a repo to GitHub

In preparation of my workshop during Herbstcampus in Nuremberg later this summer, I pushed a repo to GitHub. Currently the repo contains two versions of a small sample app I call OpenWeatherMapWeather. Here is what we have so far:



I will add a version using Gluon and Windows 10 soon. So stay tuned.

2016-07-26

Getting just a little more productive

Sometimes entering a command is just the fastest way to get something done. That's why Terminal or shell windows in IDEs come in so handy. Here is how it looks in Android Studio.


Just make sure all the tools you might need are found. I suggest a regular housekeeping of the PATH environment variable. For example, Android devs may wish to include $ANDROID_HOME/tools and $ANDROID_HOME/platform-tools. Java developers need $JAVA_HOME/bin. Of course, $ANDROID_HOME and $JAVA_HOME must point to the installation directories of the Android SDK and the Java Development Kit.

NetBeans offers a Terminal window, too.


There is a plugin called Terminal Extras. It helps setting a base directory upon invocation of the Terminal. You can download it through the Plugin Manager.


Just pick a project and hit Alt-.


Simple yet great.

2016-07-24

A few tipps on finetuning lubuntu

I am currently preparing a Linux installation (VirtualBox client) based on Lubuntu. Though Lubuntu (as far as I know) is not specifically focussed on developers, its beauty lies in the fact that the distro is reasonably small. In this post I will share a few tips on finetuning it regarding developer needs.

Lubuntu after a couple of small changes running inside VirtualBox
Lubuntu after a couple of small changes running inside VirtualBox

As I need a really up-to-date Java development kit, I decided to download it directly from the Oracle website. Though this is mere personal taste, I like to put it in /opt and add a symbolic link without a version. This is convenient as I encourage you to include its bin directory in PATH. Switching Java versions can then be done be changing the link, rather than modifying PATH. This brings us to the question of where to change this environment variable. I chose .xsessionrc in my home directory. Why? Well, if another user doesn't want or need a JDK, I think he shouldn't see it.

 # Java (JDK)
export JAVA_HOME=/opt/jdk1.8
export PATH="$PATH:$JAVA_HOME/bin"


As I need Android Studio and the Android SDK as well, I set it up in .xsessionrc, too.

# Android
export ANDROID_HOME=/home/workshop/android
export PATH="$PATH:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools"


ANDROID_HOME comes in handy if you plan to use Gluon Mobile. Well, and access to the tools and platform-tools directory provides quick access to, for example, adb and emulator.

I did not know that I could have installed NetBeans through apt-get, so I downloaded it from the NetBeans homepage. The installer kindly put an entry in the Lubuntu desktop menu. As I wanted this for Android Studio, as well, I added that entry on my own. Here is how to do that. Provided, you have installed Android Studio to /opt/android-studio, just create a file called studio.desktop with the following contents and save it to /usr/share/applications.

[Desktop Entry]
Encoding=UTF-8
Name=Android Studio
Exec=/bin/sh "/opt/android-studio/bin/studio.sh"
Icon=/opt/android-studio/bin/studio.png
Categories=Application;Development;Android;IDE
Type=Application
Terminal=0


Finally: I am a big fan of Sublime Text 3. Here is how to install it.

sudo add-apt-repository ppa:webupd8team/sublime-text-3
sudo apt-get update
sudo apt-get install sublime-text-installer

That's it. Happen to have any other tips regarding Lubuntu? I'd love to hear them.

2016-07-21

My upcoming workshop: Java on mobile devices

From Aug 30 til Sep 1 2016 Nuremberg once again will be home to the Herbstcampus, a conference for software developers, architects and managers focussing on Java, .Net, Mobile, Web and the enterprise.

I will have both the pleasure and honor of hosting a full-day workshop about Java on mobile devices. Titled Ménage à trois, we will be taking a closer look at how to build Android and iOS apps using Java and JavaFX. Based upon the open source project JavaFXPorts and its commercial sibling Gluon Mobile, we will build a few real-world apps and deploy them to both emulated and physical devices.

Interested? Take a look the the schedule:

Introduction of the participants
A little bit of history... Java on mobile devices
A first glimpse at the tools: emulators, simulators and virtualization

Coffee break

Setting up the development environment #2
Creating a project
Running the demo
Looking under the cover (walkthrough)

Lunch break

Gluon Mobile and its components
Using device functions #1
Artefact archeology - what finds its way on a device?
Using device functions #2

Coffee break

If something goes wrong (debugging)
What will not work (missing functions)
What's up? Profiling and performance

Coffee break

Taking a look at alternatives (including demos)
Reality check and wrap up

Sounds good? Remember the early bird offering ends tomorrow, Jul 22. Book now.

2016-07-18

Yes it works

Have you tried to deploy a JavaFX app as a Web Start app and failed? Fear no more. The issue is easy enough to fix.

When I started my app as a Web Start app, I was greeted with these two fellows:

Screenshot: Runtime Error

Screenshot: Part of a stack trace

The error message seems obvious. Java is unable to find a resource. To be more precisely, it fails to find an fxml document. The usual diagnosis is... The resource is not there. Or... you are doing that getResources() wrong. 

Nope. 

To put a long story short. Not being able to find the resource here means not being able to access it. My Web Start app was sandboxed. As soon as I requested all_permissions, everything was fine.

So, for example, in a NetBeans project just request unrestricted access. Wham!

Screenshot: Granting a Web Start app unrestricted access

2016-07-12

On analyzing Android class and package dependencies

Recently I had to analyze the class and package dependencies of an Android app. Jens Schauder maintains an awesome tool called Degraph. Its purpose is to test, visualize and manage dependencies of classes and packages in JVM byte code. So, I asked myself, why not use it?

Although the Google toolchain used to rely on standard Java byte code as an intermediate step, this may no longer be the case in the future. Its final artifact (the end of the toolchain if you like) consists of one or more Dalvik executables. If you take a look at an Android application package (.apk), you will find a file named classes.dex. Depending on the size of the app, there may be other, similarly named ones, too. As application classes as well as any dependent library are put there, I decided to use the .dex files for my dependency analysis.

The Android SDK contains a tool called dexdump. Its purpose is to provide a (nicely) readable representation of .dex files. Hence, all I needed to do was to bake a small tool that interprets dexdump output. You can find this tool here. It is written from scratch and is completely unrelated to Degraph. Still, I feel the need to credit Jens, especially for his idea to visualize the output of his tool using yEd.


You can extract classes.dex using tar xf. The screenshot shows a small portion of a dexdump output. To use it with my tool, you should create a text file as follows:

dexdump -l plain -f classes.dex > classes.txt

Let's see what DexAnalyzer can make out of it.


As you can see, by default analysis is based upon packages. The following screenshot shows how to distinguish classes and produce a file that can be opened in yEd.



I am going into more detail later. For now I encourage you to play with my tool. Please keep in mind that it is in its infancy. If you encounter any misbehavior, please feel free to let me know. Passing command line arguments seems to not work as expected if options appear after filenames. Also, please note that checked exceptions currently do not count as dependencies. I plan to add this later.