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…