Print

Print


How do I create a custom inspector drop down text widget with a domain of agent name strings?

 

I’m following the hexabug example program, where a drop-down menu is created to switch between rectangular or hexagonal display values, and trying to modify this to give a drop down list of agent names. I create an array in the main SimState child class of strings, and populate it in the start() method at the same time as I make the agents. Then, in the GUIState() child’s getInspector() method, I make a custom inspector with dom, get, and set methods. For the dom method, I return the String[] from my SimState child. However, this function is only called BEFORE SimState.start() is called.

 

Is there a way to create a drop down list inspector based on a String array that doesn’t exist until I hit the start button? Is there a method I can call somewhere in the GUIState after I start the simulation and my String[] foragerNames is populated?

Or is there a smarter way to do this?

Please note that selecting an agent currently does nothing (just updates the displayed value, if it were to work). Functionality will (hopefully) follow once I can figure out how to best do this.

 

Partial GUIState child code (SocialFlowMonitoringWithUI) follows:

public class AgentView {

                int forager = 0;

                public Object domAgentView() { return ((SocialFlowMonitoring)state).foragerNames; }

                public String nameAgentView() { return "Agent View"; }

                public String desAgentView() { return "Shows the current view of the selected agent."; }

                public int getAgentView() { return forager; }

                public void setAgentView(int val) {

                                forager = val;

                }

    }

       

    public Inspector getInspector()

        {

        // we'll make a fancy inspector which has a nicely arranged update button and

        // two subinspectors.  In fact the inspector doesn't need an update button --

        // there's nothing that ever changes on update.  But since the inspector

        // has been declared non-volatile, just to be consistent, we'll add an update

        // button up top to show how it's done.  First we get our two subinspectors,

        // one for the hexagon choice menu and one for the model inspector proper.

        

        final Inspector originalInspector = super.getInspector();

        final SimpleInspector hexInspector = new SimpleInspector(new HexagonChoice(), this);

        final SimpleInspector viewInspector = new SimpleInspector(new AgentView(), this);

        

        // The originalInspector is non-volatile.  It's a SimpleInspector, which shows

        // its update-button automagically when non-volatile.  We WANT it to be non-volatile,

        // but not show its update button because that just updates the inspector and nothing

        // else.  So we declare the inspector to be volatile.  It won't matter because it'll

        // NEVER receive updateInspector() calls except via the outer inspector we're

        // constructing next (which will be NON-volatile).

       

        originalInspector.setVolatile(true);

       

        // our wrapper inspector

        Inspector newInspector = new Inspector()

            {

            public void updateInspector() { originalInspector.updateInspector(); }  // don't care about updating hexInspector

            };

        newInspector.setVolatile(false);

       

        // NOW we want our outer inspector to be NON-volatile, but show an update button.

        // While SimpleInspectors add their own buttons automagically, plain Inspectors

        // do not.  Instead we have to add it manually.  We grab an update-button from

        // the inspector, put it in a box so it doesn't stretch when the inspector does.

        // And we want to move it in a bit border-wise because that's what the SimpleInspector

        // does.

               

        Box b = new Box(BoxLayout.X_AXIS)

            {

            public Insets getInsets() { return new Insets(2,2,2,2); }  // in a bit

            };

        b.add(newInspector.makeUpdateButton());

        b.add(Box.createGlue());

 

        // okay, great.  But we want the button to be up top, followed by the hex inspector,

        // and then the originalInspector taking up the rest of the room.  Sadly, there's

        // no layout manager to do that.  So we do it thus:

 

        Box b2 = new Box(BoxLayout.Y_AXIS);

        b2.add(b);

        b2.add(hexInspector);

        b2.add(viewInspector);

        b2.add(Box.createGlue());

       

        // all one blob now.  We can add it at NORTH.

 

        newInspector.setLayout(new BorderLayout());

        newInspector.add(b2,BorderLayout.NORTH);

        newInspector.add(originalInspector,BorderLayout.CENTER);

 

        return newInspector;

        }

Thanks,

John