Search code examples
javajasper-reportslocalejfreechart

How to read Locale passed by Jasperreports in Chart Customizer?


(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

Solution

  • 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.