May 21, 2018

Think About Your Future

Good morning,

we are a lucky bunch, you know that? In 2018, software developers in Germany earn an average of 52,000 €.1 By comparison, the average salary over all employees in Germany is 41,000 €.2 Looking at various professions, IT is considered one of the most lucrative job markets.3 In addition, management positions in IT add an above average amount to the already good salary.4

I just got my pension award and I was a bit baffled. Inflation as well as raises in salary and pensions removed, my net pension would only be 1/2 of my current net income. And I am by no means worse off than others.5 That is a steep drop in quality of live!

And here is where I consider us lucky: As a software developers (with more than average salaries), we can prepare for the future, set aside some money to support our quality of live in our pension. That is what I urge you to do!

I do not want to make any suggestions on the ways you want to invest money to add to your pension. There are experts for that and I am not one of them. I want to point out one more thing, however: the earlier you start, the better - think about compounded interest.

May 13, 2018

GitHub to NuGet with AppVeyor

AppVeyor Dashboard

Good morning,

As I have written in my last post, I now have a number of .NET projects on GitHub. As all of these are libraries, I wanted to make them easily available through NuGet (not least because I myself use them regularly and want them accessible at all times). Enter the world of continuous integration (CI) services.

There are two mayor CI service providers with great GitHub integration: Travis-CI and AppVeyor. Being a .NET developer, there is a serious downside to Travis, though: their servers run Linux and support only Mono and .NET Core. AppVeyor, however, provides Windows servers with all the .NET framework one might ever need, free for open source projects. Happy days!

Integration is easy enough: Select your GitHub project, add the NuGet deployment provider and enter your NuGet API key. For my projects, I also create a release branch and set AppVeyor up to build all branches, but push NuGet packages only for the release branch. Also, I found it necessary for some .NET Standard projects to run "dotnet restore" as pre build script in order to update all dependencies.

All in all, I can highly recommend you give AppVeyor a try - especially if you are a .NET developer.

May 11, 2018

Programmer's Digest on GitHub and NuGet

Good morning,

Programmer's Digest has found its way to GitHub and NuGet!
GitHub: https://github.com/programmersdigest
NuGet: https://www.nuget.org/profiles/programmersdigest

There, you will find a variety of open source projects (licensed under Apache License 2.0) ranging from object relational mapping over dependency injection to parsing of the SWIFT MT940/942 bank transaction format. Currently, all these projects are written in my preferred language C# and based on .NET Standard 2.0 where possible.

All projects are derived from software I am writing in my spare time and try to once and for all solve some specific problems I face again and again. As such all are actively being worked on and updated whenever the need arises. There may however be prolonged times of inactivity, when there are no known bugs and new features are not required.

Feel free to help improving these projects with bug reports, advice or even better, code. If you want to use any of these projects in your own, just grab them from NuGet.

I will in the near future present each of my projects in a separate article, explaining the hows and whys and maybe some interesting tidbits to be found in the code (and a rant or two may be incoming as well).

July 30, 2015

JavaFX with Scala

JavaFX with Scala

Good morning,

One of the big advantages of Scala is its interoperability with Java. Wouldn't it be nice to write JavaFX applications using Scala? Well, you can (otherwise this article would be short, indeed). In this article, I will show what to do to bring JavaFX and Scala to a happy union.

The goal is to write a small JavaFX application, whose UI is defined in FXML-files and can thus be created using SceneBuilder. Additionally, we want to use the comfort of dependency injection via the @FXML attribute, which thanks to the interoperability of Scala and Java is not hard to do at all. To keep things simple, we take a view first approach, i.e. the view defines the controller to use and the FXMLLoader does all the initialising.

First, we need to get JavaFX to load. Let's start just like we would in Java, by creating a class inheriting from Application.

// File: eu.derprogrammierer.jfx.FxApp.scala
package eu.derprogrammierer.jfx

import javafx.application.Application
import javafx.stage.Stage

class FxApp extends Application {
override def start(primaryStage: Stage): Unit = {
primaryStage.setTitle("Fx App")
primaryStage.show()
}
}

In this example, we set the window title and subsequently show it. Later we will also fill the window with some content.

In your average JavaFX application, there is also a static main() function which in turn calls the static launch() function on FxApp. However, since Scala does not implement static functions, we will have to use a companion object for the class FxApp instead. Companion objects do not automatically implement functions of the base class, though. Which is why the following port of the typical Java code will not work.

object FxApp extends Application {
def main (args: Array[String]): Unit = {
launch(args:_*) // Cannot resolve symbol launch
}
}

Luckily Application provides a more generic function for us to use, such that we can call launch on the Application base class and give it the type of our FxApp to specify the actual instance type.

// File: eu.derprogrammierer.jfx.FxApp.scala

...

object FxApp {
def main (args: Array[String]): Unit = {
Application.launch(classOf[FxApp], args:_*)
}
}

The application can now be started and displays an empty JavaFX(!) window. This is nice and all, but we really want to put some content into this empty window, and there is still that thing about FXML, right?

Well, before we can dive into FXML we require a controller to be used in our view. A basic controller implementation is very similar to what you would do in Java.

// File: eu.derprogrammierer.jfx.view.MainViewController.scala
package eu.derprogrammierer.jfx.view

import javafx.fxml.FXML
import javafx.scene.control.{Label}

class MainViewController {
@FXML private var testLabel: Label = _

def initialize(): Unit = {
testLabel.setText("Initialized!")
}

def handleTest(): Unit = {
testLabel.setText("Test successful!")
}
}

As you can see, our view will contain a single label named "testLabel". Its text is changed in the initialize()-method. Also, there is a handler handleTest() which changes the text. This handler is supposed to be executed when clicking a button.

Note that IntelliJ IDEA recommends changing testLabel into a "val", which does however break the JavaFX injection. It is also not possible to drop the @FXML attribute on public fields like you could do in Java. This is due to the way Scala handles public fields. A public field in Scala is actually a getter and setter method wrapped around a private field. This is not noticable for normal programming. However, when using reflection to access fields, as is done for FXML, this can have some major implications!

Main.fxml in SceneBuilder

Our controller is now in working order, so we can finally start to create a view (FXML, yessss!). To do that, we add a file "MainView.fxml" to the package "view". In SceneBuilder we drag an AnchorPane into the empty window. We place a button and a label in the middle of the pane.

Action handleTestLabel fxid

The button gets the action "handleTest" and the label gets the fx:id "testLabel" (both of which should seem familiar from the controller).

MainView Controller Class

Also, our view wants to have a controller, so we enter the complete name of our controller into the field "Controller class".

What's left to do is to load the view in the class FxApp. For this, we change the function start() as follows:

override def start(primaryStage: Stage): Unit = {
primaryStage.setTitle("Fx App")

val fxmlLoader = new FXMLLoader(getClass.getResource("view/MainView.fxml"))
val mainViewRoot: Parent = fxmlLoader.load()

val scene = new Scene(mainViewRoot)
primaryStage.setScene(scene)
primaryStage.show() }

This requires some additional imports, too:

import javafx.fxml.FXMLLoader
import javafx.scene.{Scene, Parent}

You can now run the program again and you will find the label correctly initialized. Clicking the button changes the text of the label to "Test successful!". A successful test indeed!

You now have a fully usable JavaScalaFX application. I will leave it up to the reader to make a "Hello World!" example from that.

June 24, 2015

Free Vector Icons in Material Design

Materialdesignicons.com

Good morning,

To be honest, I can't wait for 4k screens to really hit the market! However, high resolution displays, like the ones used on most phones these days, lead to a major new challenge for GUIs: free scalability to fit every resolution. Especially in regards to icons, many applications still struggle to meet this demand.

To anyone searching for vector icons which perfectly scale to any resolution or DPI, I can highly recommend materialdesignicons.com. There you will find a large variety of icons including (but not limited to) most typical application functions and widely used software icons. All icons are available in a number of formats, e.g. SVG or Web-Font and even XAML.

There are various ways to include XAML-icons in your program (materialdesignicons.com shows one for example). However, in my opinion the best way is to create a ResourceDictionary for the icons and add every icon as a DrawingImage containing a GeometryDrawing.

<DrawingImage x:Key="IconSave">
  <DrawingImage.Drawing>
    <DrawingGroup>
      <DrawingGroup.Children>
        <GeometryDrawing Brush="Black" Geometry="M15,9H5V5H15M12,19A3,3 0 0,1 9,16A3,3 0 0,1 12,13A3,3 0 0,1 15,16A3,3 0 0,1 12,19M17,3H5C3.89,3 3,3.9 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V7L17,3Z" />
      </DrawingGroup.Children>
    </DrawingGroup>
  </DrawingImage.Drawing>
</DrawingImage>

The beauty of this is the ease with which you can then use the icon anywhere in your GUI:

<MenuItem Name="Save"
Header="{x:Static ms:Resources.MainMenu_Save}">
<MenuItem.Icon>
<Image Source="{StaticResource IconSave}" />
</MenuItem.Icon>
</MenuItem>

To get the geometry path for the GeometryDrawing from a XAML icon, just right click on the icon in the meterialdesignicons preview. Select "View XAML" and it is right there in the Paths data attribute:

<Viewbox Width="48" Height="48">
<Canvas Width="24" Height="24">
<Path Data="M15,9H5V5H15M12,19A3,3 0 0,1 9,16A3,3 0 0,1 12,13A3,3 0 0,1 15,16A3,3 0 0,1 12,19M17,3H5C3.89,3 3,3.9 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V7L17,3Z" Fill="Black" />
</Canvas>
</Viewbox>

As for using the web font, you can find a great guide at materialdesignicons.com/getting-started.

As of writin this article, all icons on materialdesignicons.com are released under the SIL Open Font License, Version 1.1.