GameModule.getPieceWindow() null

I’m working on some custom code for a module extension and I think I want access to the piece window to get some data from it, but the return value of GameModule.getPieceWindow() is null.

Looking at the source code here – github.com/vassalengine/vassal/ … indow.java – it only assigns this value on line 268 if 2 conditionals are true, one of which is a user setting so may not always be true.

if (!hidden) {
      if (firstId.equals(id) && GlobalOptions.getInstance().isUseSingleWindow()) {
        // Register as the docked PieceWindow
        GameModule.getGameModule().setPieceWindow(this);
      }
      else {
          ...
      }

I’m wondering if there is another way to get programmatic access to the piece windows for a module?

Thanks!

I haven’t done it myself, but PieceWindow contains a static field “idMgr” which is a static instance of UniqueIdManager (see UniqueIdManager.java).

So I think something like… (PieceWindow)PieceWindow.idMgr.findInstance(id) would give you the instance for a particular ID (id’s are all Strings).

And PieceWindow.getAllInstances() would return an Iterator to all the instances (this code is old, before we started using nice List<> objects for things)

Brian

Thanks for the hint! I cobbled together this code that resembles what you were pointing at.

Unfortunately, idMgr is protected so I had to do some reflection to get at it. But I can put some good error handling around this, and it’s a non-critical part of code so I’m comfortable with it!

        try {
            var idManagerField = PieceWindow.class.getDeclaredField("idMgr");
            idManagerField.setAccessible(true);
            var idManager = (UniqueIdManager) idManagerField.get(null);
            idManagerField.setAccessible(false);

            var allInstances = idManager.getAllInstances();
            while(allInstances.hasNext()) {
                var instance = allInstances.next();
                if("Game pieces".equals(instance.getConfigureName())){
                    // do something with it
                    var pieceWindow = (PieceWindow) instance;
                    var fieldOnPieceWindow = pieceWindow.getMenuTextList();
                }
            }
        } catch (IllegalAccessException | NoSuchFieldException e) {
            e.printStackTrace();
        }

Is there a reason you can’t just use the inbuilt AbstractBuildable methods?

for (final PieceWindow window : GameModule.getGameModule().getAllDescendantComponentsOf(PieceWindow.class) {
if(“Game pieces”.equals(window.getConfigureName())){

  }

}

Oh right! Why didn’t I think of that given I was literally just working with that for the folders?!?!

Brian

That code is much less reflectiony, and does work! Thanks so much!

Now I have to figure out the information I need is actually in there…