Malformed pattern error double attribute

I have an attribute of type DOUBLE on a given entity,
on the standard screens, browser and edition, it works normally.

as I am in Brazil, here the formatting of values is different, being “###.##0,00”
different from English, “###,##0.00”

however on a certain screen, which extends from the Screen, I have a grid and the field just above,
the user must select a row from the grid, and the fields above will be filled in.

but it shows the error
Caused by: java.lang.IllegalArgumentException: Malformed pattern “#.##0,###”

–Descriptor

<textField id="qtdItemField" caption="msg://quantity" width="100%" datatype="double"/>

–Controller

qtdItemField.setValue(returnOrdersTable.getSingleSelected().getInformedQuantity());

Previously, it didn’t show the error, until I activated the formatting for Brazil, as it works on other screens, I believe the correction is simple.

could someone help me?

when running the report that already operated, now it shows the same error

An error occurred while rendering band [saldoAnterior]. Template name [ModeloKardex.xlsx] Report name [Kardex do Item]
Malformed pattern "#.##0"

Error displayed when running the report

io.jmix.reports.exception.ReportingException: An error occurred while rendering band [saldoAnterior]. Template name [ModeloKardex.xlsx] Report name [Kardex do Item]
Malformed pattern "#.##0"
	at io.jmix.reports.runner.impl.ReportRunnerImpl.createReportDocumentInternal(ReportRunnerImpl.java:169)
	at io.jmix.reports.runner.impl.ReportRunnerImpl.run(ReportRunnerImpl.java:90)
	at io.jmix.reportsui.runner.impl.UiReportRunnerImpl.runAndShow(UiReportRunnerImpl.java:98)
	at io.jmix.reportsui.runner.FluentUiReportRunner.runAndShow(FluentUiReportRunner.java:185)

The change I made that started these problems was

resources / io.jmix / core / messages_pt_BR.properties
localeDisplayName.pt_BR  = Portugês
dateFormat = dd/MM/yyyy
dateTimeFormat = dd/MM/yyyy HH:mm
timeFormat = HH:mm
offsetTimeFormat = HH:mm Z
offsetDateTimeFormat = dd/MM/yyyy HH:mm Z
integerFormat = #.##0
doubleFormat = #.##0,000
decimalFormat = #.##0,00
numberDecimalSeparator = ,
numberGroupingSeparator = .

If necessary I can send the project for analysis, along with the translation files for pt_BR, which I just haven’t shared yet, because I’m making some translation adjustments

Hi @mpedrotti

In format patterns, . always designates the decimal and , the group separators.
The actual symbols for them are defined in numberDecimalSeparator and numberGroupingSeparator keys.

So try to define your formats as follows:

integerFormat = #,##0
doubleFormat = #,##0.000
decimalFormat = #,##0.00
numberDecimalSeparator = ,
numberGroupingSeparator = .

If it doesn’t help, attach a demo project.

And we will appreciate very much if you share your pt_BR translation when it’s ready!

good night,

thank you for taking the time to respond.

but as I explained, in Brazil the formatting is inverted, semicolon, the most interesting thing is that in standard screens (browse and edit) the formatting in Brazil works 100%

but not on the custom screen, so I believe there is something I need to do to make it work correctly.

below example of screens that formatting works.

I apologize for the screens being in pt_BR, but my intention is to show the result

tela_pedido
retorno_pedido
retorno_pedido_erro

the name of this screen: retorno-pedido-usuario.xml

Below is the project exported in ZIP, and the backup of the Postgresql database, which can speed up your tests.

gestaoAdministrativa.zip (626.0 KB)
bkpBancoPGA.7z (263.0 KB)

there the translation files are inside that zip, then I want to see how I can upload this translation for your evaluation

Marcos,
Please read carefully what I wrote in my previous comment and change your number formats as suggested.

Regardless of actual symbols, . always designates the decimal and , the group separators.

Good evening @krivopustov , to better understand your guidance, I set up an example project for testing and validation, and executed the formatting within the messages_pt_BR file according to your guidance.

integerFormat = #,##0
doubleFormat = #,##0.000
decimalFormat = #,##0.00
numberDecimalSeparator = ,
numberGroupingSeparator = .

1 - Tab001 and Tab002, two entities with fields defined as Double

2 - formatting defined in each attribute, Number Format, Decimal Separator and Group Separator, the screens respect the attribute definitions and not the language definition, is this result correct?

3 - if the attributes have EMPTY formatting, at this point it is interesting to select Portuguese (pt_br)

3.1 - open blank-screen first, the formatting respects the defined language, that is, pt_br

3.2 - when opening the tab001-browse screen, the formatting is in English (EN)

3.3 - after opening the previous screen, if you open the blank-screen, the formatting is in English (EN) and not the one selected by the user

4 - following this flow, I was in doubt if the tool is working correctly, because in my view it could not change the formatting according to the open screen, is this result correct?

5 - if the formatting types are defined in the attributes, wouldn’t it be a limitation for the user?

below the project, and the screens that show what I wrote above

I hope it’s easy for your understanding, because I’ve been trying to write this answer for two days.

telas.zip (482.7 KB)

testeFormato.zip (139.6 KB)

Hi Marcos,
Thank you for the detailed explanation and test project.

This is correct, if a number format is defined for the attribute, the localization formats have no effect on this attribute.

As for the wrong decimal/grouping separators in your project, it turned out to be caused by a stupid bug with object mutability, see Decimal and grouping separators in an attribute number format replace default ones set for locale · Issue #1333 · jmix-framework/jmix · GitHub.
The bug is fixed now, the fix will be available in the next patch, probably by the end of January.

Thanks again for your patience and dedication!

1 Like

I’m happy to have helped.

I will keep the EN formatting until the solution is released.

Thank you very much.

Hi,
it seems that I stumbled on this bug but I’m using Jmix 1.4.4
Is this bug still open or should I search in my code for a different explanation of this behaviour?
Actually it looks like if I declare a @DatatypeDef with a format method, the numberGroupingSeparator set in the message properties gets completely ignored.

Hi @pasquale.granato

The bug is definitely fixed, so probably you are facing a different problem.
Could you provide your datatype code here?

Hi @krivopustov ,
thanks for getting in touch.
Here’s my datatype class

package ch.supsi.isaac.formatter;

import com.google.common.base.Strings;
import io.jmix.core.metamodel.annotation.DatatypeDef;
import io.jmix.core.metamodel.annotation.Ddl;
import io.jmix.core.metamodel.datatype.Datatype;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.ParseException;
import java.util.Locale;

@DatatypeDef(
        id = "id",
        javaClass = Integer.class
)
@Ddl("int")
public class IdDatatype implements Datatype<Integer> {
    private static final String PATTERN = "#####0";

    @Override
    @Nonnull
    public String format(@Nullable Object value) {
        if (value == null)
            return "";

        return new DecimalFormat(PATTERN).format(value);
    }

    @Override
    @Nonnull
    public String format(@Nullable Object value, @Nonnull Locale locale) {
        return format(value);
    }

    @Nullable
    @Override
    public Integer parse(@Nullable String value) throws ParseException {
        if (Strings.isNullOrEmpty(value))
            return null;

        return new DecimalFormat(PATTERN).parse(value).intValue();
    }

    @Nullable
    @Override
    public Integer parse(@Nullable String value, @Nonnull Locale locale) throws ParseException {
        return parse(value);
    }

}

In order to take separator defined in properties your datatype should use FormatStringsRegistry bean. See for example DoubleDatatype.java