Multi Language Java Desktop Applications

I don’t like to work with the large files of Resource Bundles when I write multi-language desktop applications with Java Swing or JavaFX. So I wanted to use a resource file for each module in my rich client applications. I’ve written an util class which has an enum set, please see below. Now I can use this I18n helper in every module.

I18n enum with application modules:

package com.cemikta.customersfx.util;

import java.text.MessageFormat;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;

 * Resource Bundle helper.
 * <p>
 * Each module has its own resource bundle file for i18n strings. Always read
 * default locale from <code>Locale.getDefault()</code>.
 * </p>
 * <pre>
 *      I18n.MODULE_NAME.getString("stringKey");
 *      I18n.MODULE_NAME.getString("stringKey", param);
 * </pre>
 * @see ResourceBundle
 * @author Cem Ikta
public enum I18n {


    private final static Logger logger = Logger.getLogger(I18n.class.getName());
    private static final String DEFAULT_LOCATION = "i18n.";
    private final ResourceBundle resourceBundle;

    I18n(String bundleFile) {
        resourceBundle = ResourceBundle.getBundle(DEFAULT_LOCATION + bundleFile);

     * Gets a string for the given key from resource bundle.
     * @param key the key for the desired string
     * @return the string for the given key
    public String getString(String key) {
        try {
            return resourceBundle.getString(key);
        } catch (MissingResourceException ex) {
            logger.log(Level.SEVERE, null, ex);
            return "err#";
     * Gets a string for the given key from resource bundle and formats 
     * with parameters.
     * @param key the key for the desired string
     * @param params parameters for message formats
     * @return the string for the given key
    public String getString(String key, Object... params) {
        try {
            return MessageFormat.format(resourceBundle.getString(key), params);            
        } catch (MissingResourceException ex) {
            logger.log(Level.SEVERE, null, ex);
            return "err#";


Here is a sample use of I18n helper:

// set default locale english  
Locale.setDefault(new Locale("en", "EN"));  
// set default locale for German  
// Locale.setDefault(new Locale("de", "DE"));  
AppView appView = new AppView();  

Do you need a working project with multi languages? I have implemented Customers Java Swing Application Demo with I18n helper. You can get full source code from BitBucket.


* Image credit: Designed by Freepik

Base Entity Class in JPA

In JPA entities there are repeated fields and methods. Don’t repeat yourself and write a base class with @MappedSuperclass.

Base entity common fields:

id: Table id column, auto increment. In entity model with @Id annotation.

version: Version column for Optimistic Lock has default ’0′ in table and managed from your database and EntityManager. In entity model with @Version annotation.

Common methods:

hashCode() and equals() very important. If you don’t implement the methods you get problems later.

toString(): Optional method, default I use class name and id. You can override this method in your entities.

package com.cemikta.entitydemo.model;


import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import javax.persistence.Version;

 * Base entity
 * @author Cem Ikta
public abstract class BaseEntity implements Serializable {

    private static final long serialVersionUID = 1L;

    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "id", nullable = false, columnDefinition = "BIGINT UNSIGNED")
    protected Long id;

    @Column(name = "version")
    private Long version;

    public Long getId() {
        return id;

    public Long getVersion() {
        return version;

    public int hashCode() {
        int hash = 0;
        hash += (this.getId() != null ? this.getId().hashCode() : 0);

        return hash;

    public boolean equals(Object object) {
	if (this == object)
            return true;
        if (object == null)
            return false;
        if (getClass() != object.getClass())
            return false;

        BaseEntity other = (BaseEntity) object;
        if (this.getId() != other.getId() && (this.getId() == null || ! {
            return false;
        return true;

    public String toString() {
        return this.getClass().getName() + " [ID=" + id + "]";

Base entity audit fields:

It is sometimes important to know when and by whom the table data were saved. I save creation date, modification date and user informations in the table. I have String for user informations, I save only username without foreign key, then I have no relations with user table. With @PrePersist and @PreUpdate you don’t need to set the date manual every time. Set the user informations(createdBy and updatedBy) in your controllers/service but not in models! Business logic must always remain in the right place.

If you need more flexible auditing/versioning of your tables, history of changes, you can use Hibernate Envers.

package com.cemikta.entitydemo.model;

import java.util.Date;
import javax.persistence.Column;
import javax.persistence.MappedSuperclass;
import javax.persistence.PrePersist;
import javax.persistence.PreUpdate;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.validation.constraints.Size;

 * Base entity audit
 * @author Cem Ikta
public abstract class BaseEntityAudit extends BaseEntity {

    @Column(name = "created_at")
    private Date createdAt;

    @Size(max = 20)
    @Column(name = "created_by", length = 20)
    private String createdBy;

    @Column(name = "updated_at")
    private Date updatedAt;

    @Size(max = 20)
    @Column(name = "updated_by", length = 20)
    private String updatedBy;

    public Date getCreatedAt() {
            return createdAt;

    public void setCreatedAt(Date createdAt) {
            this.createdAt = createdAt;

    public String getCreatedBy() {
            return createdBy;

    public void setCreatedBy(String createdBy) {
            this.createdBy = createdBy;

    public Date getUpdatedAt() {
            return updatedAt;

    public void setUpdatedAt(Date updatedAt) {
            this.updatedAt = updatedAt;

    public String getUpdatedBy() {
            return updatedBy;

    public void setUpdatedBy(String updatedBy) {
            this.updatedBy = updatedBy;

     * Sets createdAt before insert
    public void setCreationDate() {
        this.createdAt = new Date();

     * Sets updatedAt before update
    public void setChangeDate() {
        this.updatedAt = new Date();



Sample usage of EntityBaseAudit:

If you use your table id columns with table name prefix e.g customer_id then use @AttributeOverride. Without table name prefix remove @AttributeOverride.

@Table(name = "customers")
@AttributeOverride(name = "id", column = @Column(name = "customer_id",
        nullable = false, columnDefinition = "BIGINT UNSIGNED"))
public class Customer extends BaseEntityAudit {

    // fields without id column ...

    public Customer() {

    // getter and setter ...



* Tree structure icon credit

Install JDK 8 on Ubuntu

Installing step by step Oracle JDK 8 on Ubuntu GNU/Linux:

Step 1: Download the Oracle JDK 8 tar file from here.

Step 2: Open the terminal and extract the tar file.

tar -xvzf jdk-8-linux-x64.tar.gz

Step 3: Create jvm folder in /usr/lib, if jvm folder not exist.

sudo mkdir /usr/lib/jvm

Step 4: Move extracted JDK 8 folder to this location.

sudo mv jdk1.8.0 /usr/lib/jvm/jdk1.8.0

Step 5: Install new Java source in system.

sudo update-alternatives --install /usr/bin/javac javac /usr/lib/jvm/jdk1.8.0/bin/javac 1
sudo update-alternatives --install /usr/bin/java java /usr/lib/jvm/jdk1.8.0/bin/java 1
sudo update-alternatives --install /usr/bin/javaws javaws /usr/lib/jvm/jdk1.8.0/bin/javaws 1

Step 6: Choose default Java.

sudo update-alternatives --config javac
sudo update-alternatives --config java
sudo update-alternatives --config javaws

Step 7: Test the Java version.

java -version

# java version "1.8.0"
# Java(TM) SE Runtime Environment (build 1.8.0-b132)
# Java HotSpot(TM) 64-Bit Server VM (build 25.0-b70, mixed mode)

Step 8: Verify the symlinks all point to the new Java location.

ls -la /etc/alternatives/java*

Step 9: Enable Java plugin for Mozilla Firefox (even for Chrome)

# for 64-Bit JDK
sudo ln -s /usr/lib/jvm/jdk1.8.0/jre/lib/amd64/ /usr/lib/mozilla/plugins
# for 32-Bit JDK
sudo ln -s /usr/lib/jvm/jdk1.8.0/jre/lib/i386/ /usr/lib/mozilla/plugins

Step 10: Some tools require JAVA_HOME variable. You can set JAVA_HOME variable on Ubuntu with following options (1. option recommended!)

  1. Option with /etc/environment:
    sudo gedit /etc/environment
    # add the following line, save and exit
    # Load the variables
    source /etc/environment
  2. Option with .bashrc: in your home directory
    sudo gedit .bashrc
    # add the following lines, save and exit
    export JAVA_HOME=/usr/lib/jvm/jdk1.8.0
    export PATH=$JAVA_HOME/bin:$PATH


Original post is from my old blog!

Practical Notes of RESTful API Design

Coding Style in RESTful:

JSON: JavaScript naming conventions: camelCase
Rest clients in Java: camelCase
Rest clients in Python and Ruby: snake_case

RESTful URL Mapping:

GET /customers  Retrieves a list of customers.
GET /customers/{id}  Retrieves a specific customer with id.
GET /customers/5

POST /customers  Creates a new customer.

PUT /customers/{id}  Updates customer with id.
PUT /customers/5

PATCH /customers/{id}  Partially updates customer with id.
PATCH /customers/5

DELETE /customers/{id}  Deletes customer with id.
DELETE /customers/5

RESTful URL Mapping with Relations:

GET /customers/{id}/orders  Retrieves list of orders for customer with id.
GET /customers/5/orders
GET /customers/{id}/orders/{id}  Retrieves order with id for customer with id.
GET /customers/5/orders/23

POST /customers/{id}/orders  Creates a new order in customer with id.
POST /customers/5/orders

PUT /customers/{id}/orders/{id}  Updates order with id for customer with id.
PUT /customers/5/orders/23

PATCH /customers/{id}/orders/{id}  Partially updates order with id for customer with id.
PATCH /customers/5/orders/23

DELETE /customers/{id}/orders/{id}  Deletes order with id for customer with id.
DELETE /customers/5/orders/23

RESTful URL Mapping with Parameters:


GET /customers?key=value  Retrieves list of customers with key value query parameter.
GET /customers?state=active  Here, state is a query parameter that implements a filter.


GET /customers?sort=value  Retrieves a list of customers with sort parameter.
GET /customers?sort=last_name

GET /customers?sort=value1, value2  Sort parameter with list of comma separated fields.
GET /customers?sort=last_name, created_at

GET /customers?sort=last_name&dir=DESC  Sorting with two parameters.


GET /customers/recently_registered  Simple query.
GET /customers?q=Berlin&state=active&sort=last_name&dir=DESC  Complex query with search, state, sort, dir parameters.


GET /customers?page=3&per_page=20  Paging with parameters.
GET /customers/search/name_starts_with?name=K&sort=name&dir=desc  Paging and sorting with parameters.


Original post is from my old blog!


* Image credit: Designed by Freepik

Getting Real Book Notes

I finished the book “Getting Real” from very quickly. Getting Real is a smaller, faster, better way to build software. The book was very fascinating and valuable for me. I recommend the book to software developers as well as project managers.

Important and interesting points from the book:

  • Less features, do less!
  • Build software for yourself, solve your own problems.
  • Create a tool that you’re passionate about. And passion is key.
  • Outside money is plan B (first do it myself without investor).
  • Fix Time and Budget.
  • Prioritization, Reality, Flexibility.
  • Pick a fight!
  • Keep it small and manageable so you can actually enjoy the process.
  • Don’t follow the leader.
  • The leaner you are, the easier it is to change.
  • When it comes to web technology, change must be easy and cheap. If you can’t change on the fly, you’ll lose ground to someone who can. That’s why you need to shoot for less mass.
  • Less software, less features and more organic.
  • Lets focus on what we need to focus on right now.
  • Change is your best friend. If change gets to expensive you’re dead.
  • Remember, it’s ok to keep your first version small and tight. You’ll quickly get to see if your idea has wings and, if it does, you’ll have a clean, simple base to build on.
  • Figure out your priorities earlier rather than later.
  • Let limitations guide you to creative solutions. There’s never enough to go around. Not enough time. Not enough money. Not enough people. Instead of trying to remove them, use them to your advantage.
  • Be Yourself. Differentiate yourself from bigger companies by being personal and friendly.
  • Explicitly define the one-point vision for your application. What does your application stand for? What’s it really all about?
  • Work from large to small.
  • It’s a Problem When It’s a Problem. Don’t waste time on problems you don’t have yet.
  • Find the core market for your application and focus solely on them. The customer is not always right. If you try to please everyone, you won’t please anyone.
  • Scale later. You don’t have a scaling problem yet. “Will my app scale when millions of people start using it?”
  • Make Opinionated Software. The best software has a vision. The best software takes sides.
  • Build half a product, not a half-ass product. Start off with a lean, smart app and let it gain traction. Then you can start to add to the solid foundation you’ve built.
  • It just doesn’t matter. Essentials only.
  • Start With No. Each time you say yes to a feature, you’re adopting a child. Don’t be a yes-man to all features.
  • Can you handle it? Build products and offer services you can manage.
  • Build software for general concepts and encourage people to create their own solutions.
  • Forget feature requests. Let your customers remind you what’s important. Customers want everything under the sun.
  • Ask people what they don’t want.
  • Real things lead to real reactions. Execute, build momentum and move on.
  • From idea to implementation. Go from brainstorm to sketches to HTML to coding.
  • Avoid preferences. Decide the little details so your customers don’t have to.
  • Test your app via real world usage.
  • Shrink your time.
  • People need uninterrupted time to get things done.
  • Meetings Are Toxic. Don’t have meetings.
  • Seek and Celebrate Small Victories. The most important thing in software development is motivation.
  • Actions, not words.
  • Interface first. Design the interface before you start programming.
  • Epicenter design. Start from the core of the page and build outward.
  • Context over consistency.What makes sense here may not make sense there.
  • Every letter matters. If you think every pixel, every icon, every typeface matters, then you also need to believe every letter matters.
  • One Interface. Incorporate admin functions into the public interface.
  • Less software. Keep your code as simple as possible.
  • A happy programmer is a productive programmer.  Happy programmers write simple, readable code. They take clean, expressive, readable, elegant approaches. They have fun.
  • Don’t write a functional specifications document. Don’t do dead documents. Eliminate unnecessary paperwork.
  • Build, don’t write. Documents that live separately from your application are worthless.
  • Tell me a quick story. Write stories, not details.
  • Use real words in your application.
  • Give something away for free (free module, free accounts, small applications).
  • Make it as easy as possible to get in — and get out — of your application.
  • Avoid long-term contracts, sign-up fees, etc.
  • Hollywood Launch. Go from teaser to preview to launch. Better no beta (Beta for private OK but public beta bullshit).


Original post is from my old blog!


Customers Java Swing Application Demo

I have developed the Customers Java Swing Application Demo. This application may be useful for developers who want to use Flamingo, Substance and SwingX.

Technology stack:


Model View Controller (MVC) vs Model View Presenter (MVP):

The Customers Java Swing Application Demo is built on MVC design pattern like Java Swing. MVP is also popular for Desktop and RIA. Which is best, there are many discussions. Martin Fowler has written very good explanations for GUI Architectures. You may like to read.

Models and Services:

I have written entities with NamedQueries in JPA and Hibernate. The services are very simple with Generic AbstractService.

You can get full source code and project resources from Bitbucket!

Original post is from my old blog!


* Customers Java Swing Application images and icons credits: and


New Home

Hi everybody,

I have a new homepage for my blog posts. I will write more often about application development, project management, tutorials and book reviews. My old homepage is still available.

Have fun while reading.




* Photo: Hobbiton, New Zealand Copyright © Cem Ikta