1

(I am basing my question on this HARDCODED example from April 2016 and am seeking an updated, dynamic answer since the "bug" has been fixed - not having the locale available in the Customizer)

/* -Hardcoded example */
getNumberInstance(Locale.US)); //"Locale.US" is hardcoded rather than using the locale set in the report

Goal: Pass Locale set in jasper reports to chart and read with chart Customizer.

  • How do I properly read the Report Locale now that the bug of it not being available has been fixed (see here)?

Problem: In the Customizer Class (written in Java) this command does not contain anything: JRParameter.REPORT_LOCALE.

public class AssetsChartMod implements JRChartCustomizer {

    public void customize(JFreeChart chart, JRChart jasperChart) {

            /* ----> */
            System.out.println( JRParameter.REPORT_LOCALE ); // PRINTS NOTHING
Alex K
  • 22,315
  • 19
  • 108
  • 236
DavidDunham
  • 1,245
  • 1
  • 22
  • 44

1 Answers1

1

Unfortunately, we can't get report's parameters from JRChart object. This would be the easiest way to get Locale from parameters map.

But we can perform this trick:

  1. Add property locale for chart at jrxml file.

The snippet of jrxml file with chart declaration:

<pie3DChart>
    <chart customizerClass="ru.alex.PieChartCustomizer" theme="aegean">
        <reportElement positionType="Float" x="0" y="0" width="100" height="100">
            <propertyExpression name="locale"><![CDATA[((java.util.Locale) ($P{REPORT_PARAMETERS_MAP}.get("REPORT_LOCALE"))).toString()]]></propertyExpression>
        </reportElement>

The property can be only of String type, this is why I performed cast at expression.

  1. At JRChartCustomizer class I'm getting the property with help of JRChart.getPropertiesMap() method.

At my case the package name was ru.alex.

public class PieChartCustomizer implements JRChartCustomizer {

    private static final String LOCALE_PROPERTY = "locale"; // the same name as at jrxml file
    private static final Locale DEFAULT_LOCALE = Locale.ENGLISH;

    @Override
    public void customize(JFreeChart chart, JRChart jasperChart) {
        PiePlot pieChart = (PiePlot) chart.getPlot();
        JRPropertiesMap map = jasperChart.getPropertiesMap();

        Locale locale = DEFAULT_LOCALE; // this is default Locale if property was not set
        if (map != null && !map.isEmpty()) {
            if (!isNullOrEmpty(map.getProperty(LOCALE_PROPERTY))) {
                locale = Locale.forLanguageTag(map.getProperty(LOCALE_PROPERTY).replace("_", "-")); // here we have Locale passed via property 'locale'. Replacement applied: en_GB -> en-GB, for example
            }
        }

        // some actions 
    }

    private static boolean isNullOrEmpty(String string) {
        return string == null || string.isEmpty();
    }
}

Voila, we got report's locale at customizer.

Alex K
  • 22,315
  • 19
  • 108
  • 236
  • Thank you Alex. What a nice example. One comment: ----locale = new Locale(map.getProperty(LOCALE_PROPERTY));---- does not actually create a usable locale element because the ----map.getProperty(LOCALE_PROPERTY)---- gives me "de_DE" (as example) but to create a new locale I need them split like ----new Locale("de", "DE")---- ...so to use it as a e.g. number formatter I have to split it first. -> ---- DecimalFormat formatter = (DecimalFormat) NumberFormat.getInstance(new Locale(part[0], part[1])); – DavidDunham Jul 03 '17 at 07:50
  • Great. FYI ---- locale = Locale.forLanguageTag(map.getProperty(LOCALE_PROPERTY).replace("_", "-")); ---- does not compile for me (even though Eclipse does not show any errors). Had to use: ---- String[] parts = map.getProperty(LOCALE_PROPERTY).split("\_"); locale = new Locale(parts[0], parts[1]); – DavidDunham Jul 03 '17 at 08:58
  • Strange, works well for me. `Locale.forLanguageTag(String)` method was introduced at jdk7. Which version of Java are you using? – Alex K Jul 03 '17 at 09:15
  • Java V: 1.8.0_101. Jasper reports v6.4.1. – DavidDunham Jul 03 '17 at 09:33