Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using GWT's NumberFormat class in the shared package

Tags:

java

gwt

In my GWT project my service returns an object of type Shield that I have defined. As the Shield type is being used by both the client and server, I have put the class definition in the shared package.

The Shield class uses the com.google.gwt.i18n.client.NumberFormat class (a replacement for, amongst others, java.text.DecimalFormat).

The issue is that NumberFormat can't be put in the shared package as it creates an instance of LocaleInfo using GWT.create().

Is there any way I can use com.google.gwt.i18n.client.NumberFormat from within the shared package?

like image 203
luketorjussen Avatar asked Jun 28 '11 16:06

luketorjussen


2 Answers

I've solved this problem by creating a SharedNumberFormat and then an empty client side stub for the server version that is never used.

Here's my SharedNumberFormat.java, which, you guessed it, can be used in shared code and will work fine both client and server side:

import java.text.DecimalFormat;

import com.google.gwt.core.client.GWT;
import com.google.gwt.i18n.client.NumberFormat;

/**
* The purpose of this class is to allow number formatting on both the client and server side.
*/
public class SharedNumberFormat
{
    private String pattern;

    public SharedNumberFormat(String pattern)
    {
        this.pattern = pattern;
    }

    public String format(Number number)
    {
        if(GWT.isClient())
        {
            return NumberFormat.getFormat(pattern).format(number);
        } else {
            return new DecimalFormat(pattern).format(number.doubleValue());
        }
    }
}

I then stub out the java.text.DecimalFormat implementation in my super source:

package java.text;

/**
* The purpose of this class is to allow Decimal format to exist in Shared code, even though it is never called.
*/
@SuppressWarnings("UnusedParameters")
public class DecimalFormat
{
    public DecimalFormat(String pattern) {}

    public static DecimalFormat getInstance() {return null;}
    public static DecimalFormat getIntegerInstance() {return null;}

    public String format(double num) {return null;}
    public Number parse(String num) {return null;}
}

I have extra methods in there because I use that class server side and compiler gets in a fit about it if they're not there.

Finally, don't forget to add your super-source tag to your *.gwt.xml:

<super-source path="clientStubs"/>
like image 90
Ryan Shillington Avatar answered Oct 02 '22 15:10

Ryan Shillington


In short, No.

Shared packages should only contain any logic or data types that are (AND CAN) used by both the client and the server.

The reason gwt provides their number format class is, in their words -

In some classes, the functionality of the class is too expensive to be emulated entirely, so a similar routine in another package is provided instead.

Vice versa, GWTs implementation of NumberFormat is javascript specific and of course cannot be used in the server side (Java in your case).

You will have to try and move the formatting logic out of this class and into server side (using java's NumberFormat) and client side (using gwt's NumberFormat) respectively. You can keep the rest of it in the shared package.

like image 21
Jai Avatar answered Oct 02 '22 16:10

Jai