# ClientLocalizationManager error

**URL:** <https://forum.inductiveautomation.com/t/clientlocalizationmanager-error/76899>\
**Category:** Module Development\
**Created:** [July 25, 2023, 7:41pm UTC](https://forum.inductiveautomation.com/t/clientlocalizationmanager-error/76899 "2023-07-25T19:41:41Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Asjal\_Ahmad](https://avatars.discourse-cdn.com/v4/letter/a/9e8a1a/32.png) [@Asjal\_Ahmad](https://forum.inductiveautomation.com/u/Asjal_Ahmad)\
**Post date:** [July 25, 2023, 7:41pm UTC](https://forum.inductiveautomation.com/t/clientlocalizationmanager-error/76899/1 "2023-07-25T19:41:41Z")

</div>

I am writing a simple SpinnerComponent class that uses a PMISpinner:

```auto
package com.inductiveautomation.ignition.examples.ce.components;

import com.inductiveautomation.factorypmi.application.components.PMISpinner;

import javax.swing.*;
import java.awt.*;

public class SpinnerComponent extends JComponent{

    private final double MAX_VALUE = 120.0;
    private final Dimension dims = new Dimension(60, 20);

    public SpinnerComponent() {
        PMISpinner spinner = new PMISpinner();
        spinner.setSpinnerMode(PMISpinner.INT_SPINNER);
        spinner.setMaxValue(MAX_VALUE);
        spinner.setMinimumSize(dims);
    }

}

```

Test File:

```auto
import com.inductiveautomation.ignition.examples.ce.components.SpinnerComponent;
import org.junit.jupiter.api.Test;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class SpinnerComponentTest {

    @Test
    public void testSpinnerComponentDisplay() {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        SpinnerComponent spinnerComponent = new SpinnerComponent();
        frame.add(spinnerComponent);

        frame.pack();
        frame.setVisible(true);

        int displayDuration = 10000;
        Timer timer = new Timer(displayDuration, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                frame.dispose();
            }
        });
        timer.setRepeats(false);
        timer.start();

        try {
            Thread.sleep(displayDuration);
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }

    }
}

```

I am getting a weird error. This is the surfire test report:

```auto
-------------------------------------------------------------------------------
Test set: SpinnerComponentTest
-------------------------------------------------------------------------------
Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.303 sec <<< FAILURE!
SpinnerComponentTest.testSpinnerComponentDisplay() Time elapsed: 0.301 sec <<< FAILURE!
java.lang.NullPointerException: Cannot invoke "com.inductiveautomation.ignition.client.model.ClientLocalizationManager.getCurrentLocale()" because the return value of "com.inductiveautomation.ignition.client.model.ClientLocalizationManager.get()" is null
	at com.inductiveautomation.factorypmi.application.components.PMISpinner.getCurrentLocale(PMISpinner.java:109)
	at com.inductiveautomation.factorypmi.application.components.PMISpinner.<init>(PMISpinner.java:90)
	at com.inductiveautomation.ignition.examples.ce.components.SpinnerComponent.<init>(SpinnerComponent.java:15)
	at SpinnerComponentTest.testSpinnerComponentDisplay(SpinnerComponentTest.java:16)

```

I am using Windows 10 and an IntelliJ development environment. I tried editing the Custom VM options in IntelliJ with these to change the Java locale settings.

```auto
-Duser.language=en
-Duser.country=US
-Duser.variant=US

```

But it still did not work.  
Any ideas?

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [July 25, 2023, 7:50pm UTC](https://forum.inductiveautomation.com/t/clientlocalizationmanager-error/76899/2 "2023-07-25T19:50:13Z")

</div>

As the stacktrace alludes, PMISpinner's `init` is calling `getCurrentLocale`, which is attempting to reach out to the singleton ClientLocalizationManager object that is assumed to be present. There's... a lot of that kind of stuff; it's not ideal from a unit testing standpoint, but a shortcut/technical debt that's piled up over fifteen years of Vision existing.

If you _really_ need to unit test your own GUI components, I would suggest, in order of preference:

1. Don't unit test Swing GUI components.
2. Don't unit test any Swing components that contain base Vision components. There are lots of more 'pure' Swing components available in `client-api`, but by embedding _the exact same component used in Vision_, you're basically guaranteeing that you have to have a "like-for-like" environment to unit test in.
3. Mock ClientLocalizationManager...and probably other things, that are implicitly relied upon by components like PMISpinner.

The reason I suggest "don't unit test Swing GUI components" is because, in my experience, unit testing GUIs invariably ends up pointless. You spend more time maintaining test cases that don't actually guarantee you anything, when the thing you _want_ to test is business logic, which should be wrapped up in 'pure' functions. But that _is_ just my opinion 🙂

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [July 25, 2023, 8:24pm UTC](https://forum.inductiveautomation.com/t/clientlocalizationmanager-error/76899/3 "2023-07-25T20:24:36Z")

</div>

> [@Asjal\_Ahmad](#):
>
> ```auto
> public SpinnerComponent() {
> PMISpinner spinner = new PMISpinner();
> spinner.setSpinnerMode(PMISpinner.INT_SPINNER);
> spinner.setMaxValue(MAX_VALUE);
> spinner.setMinimumSize(dims);
> }
> 
> ```

Side note: Creating a local variable in your constructor of type `PMISpinner` doesn't magically make a `PMISpinner` part of your component--it will be thrown away at the end of the constructor.
