简体   繁体   中英

How to replace deprecated function RectangularNode in AnyLogic?

I am trying to run an AnyLogic model developed a few years ago and I do not have access to the person who coded it. I have very limited knowledge of Java. The model is built based on data being read in from an XML file. The first step is to read the layout data from an XML file and draw the layout. It used to work fine but with AnyLogic version changes, it stopped working. I get the following error:

" (RectangularNode): The creation of space markup element isn't finished. Please use initialize() function."

The code that gets highlighted as the source of the error is:

                    ((Agent)temp).setLocation(shapeLayoutObj);

What is interesting is that couple RectangularNodes do get drawn before this error occurs. The surrounding code is given below. The above statement identified in the console window as the error source is close to the bottom of the code provided below.

/* Layout drawing */
//Initializing objects
int scale=30;
Layout layout= CMSDDocument.getDataSection().getLayout();
List<LayoutObject> layoutObj =CMSDDocument.getDataSection().getLayoutObject();
double xLoc, yLoc, width, depth; 
double xOffset = 50.0;
double yOffset = 100.0;
String layoutName;
width = layout.getBoundary().getWidth().doubleValue()*scale;
depth = layout.getBoundary().getDepth().doubleValue()*scale;
RectangularNode shapeCellArea = new RectangularNode(this, SHAPE_DRAW_2D3D, true, xOffset, yOffset, 0.0, width, depth, 0, null, Color.red, 2.0, LINE_STYLE_SOLID, POSITION_CHOICE_RANDOM, new Attractor(0,0,0));
ShapeText text = new ShapeText(SHAPE_DRAW_2D3D,true,xOffset+width/2,yOffset-20,0.0,0.0,red,"SHOP FLOOR",new Font ("Calibri", Font.BOLD , 15),TextAlignment.ALIGNMENT_CENTER);
presentation.add(shapeCellArea);
presentation.add(text);
LinkedHashMap<String,RectangularNode> floorLayout=new LinkedHashMap<String,RectangularNode>();
boolean found;
int j;
//For every layout description
for(int i= 0; i<layout.getPlacement().size();i++){
    //Getting the name and the description
    layoutName = layout.getPlacement().get(i).getLayoutElementIdentifier();
    xLoc = layout.getPlacement().get(i).getLocation().getX().doubleValue()*scale + xOffset;
    yLoc = layout.getPlacement().get(i).getLocation().getY().doubleValue()*scale + yOffset;
    found = false;
    j = 0;
    //Looking for the layout object with tthe same name as the layout description
    while (!found && j<layoutObj.size()){
        if (layoutName.equals(layoutObj.get(j).getIdentifier())) {
            //Getting layou values
            width = layoutObj.get(j).getBoundary().getWidth().doubleValue()*scale;
            depth = layoutObj.get(j).getBoundary().getDepth().doubleValue()*scale;
            RectangularNode shapeLayoutObj=null;
            //Configure the shape
            if(layoutName.contains("Mc")){
                shapeLayoutObj = new RectangularNode(this, SHAPE_DRAW_2D3D, true, xLoc, yLoc, 0.0, width, depth, 0, null, Color.black, 2.0, LINE_STYLE_DASHED, POSITION_CHOICE_BY_ATTRACTORS,new Attractor(width/2,depth/2,0));
            }
            else{
                shapeLayoutObj = new RectangularNode(this, SHAPE_DRAW_2D3D, true, xLoc, yLoc, 0.0, width, depth, 0, null, Color.black, 2.0, LINE_STYLE_DASHED, POSITION_CHOICE_RANDOM);
            }
            text = new ShapeText(SHAPE_DRAW_2D3D,true,xLoc+width/2,yLoc-15,0.0,0.0,black,layoutName,new Font ("Calibri", Font.PLAIN , 11),TextAlignment.ALIGNMENT_CENTER);
            presentation.add(shapeLayoutObj);
            presentation.add(text);
            //Associate the shape with a machine or a delay
            Iterator<ArrayList<Machine>> cell=machineList.iterator();
            boolean foundAgent=false;
            while(cell.hasNext()&&!foundAgent){
            Iterator<Machine> machines=cell.next().iterator();
                while(machines.hasNext()&&!foundAgent){
                    Machine temp=((Machine)machines.next());
                    if(temp.name.equals(layoutName)){
                        foundAgent=true;
                        ((Agent)temp).setLocation(shapeLayoutObj);
                        ShapeButton button = new ShapeButton(Main.this, true, xLoc,yLoc+depth+5,40, 20.0,controlDefault, controlDefault, 
                        true,new Font("Dialog", 0, 11 ),"Go to" ) {
                            public void action(){
                                getExperimentHost().setPresentable(temp);
                            }  
                        };
                        presentation.add(button);
                    }
                }
            }

I understand from past exchanges that AnyLogic switched from Java Swing (in AnyLogic7 when the model was developed) to a Web-based UI and wonder if this error is due to that switch. In AnyLogic help file, RectangularNode function is identified as "deprecated in version 8.4, will be removed in the next release". I am now using AnyLogic 8 Personal Learning Edition 8.5.2 and hence I figure that this function has been removed. Wish the error message said that. Wish also that the help file suggested the new function corresponding to the deprecated function. It is also confusing that "Rectangular Node" continues to show up in the current version as a space markup element on the process modeling library palette. Guess the underlying code has changed for that element.

I looked at AnyLogic help and best I could figure that "ShapeRectangle" may be the new function that I should use to replace "RectangularNode" function but the "ShapeRectangle" function doesn't allow defining attractors. And the "ShapeRectangle" function appears to correspond to Rectangle element in the Presentation Palette rather than to the Rectangular Node in Process Modeling Library.

Kindly point me in the right direction. Should I be replacing all instances of RectangularNode or is the error something else? If I should be replacing the RectangularNode function, what function should I be using instead?

A helpful colleague pointed out that: "

  1. It looks like only the RectangularNode constructors with ShapeDraw parameters are deprecated. The basic one is not.
  2. RectangularNode's parent class AreaNode has a method to add attractors.

This would lead me to think: a) you should not replace RectangularNode. ShapeRectangle is about shape but you can't just use a shape as a node. b) AreaNode, the superclass of RectangularNode, has methods to add attractors so you can use those."

Based on the advice and some trial and error, I used the following statements to replace the deprecated version of RectangularNode. The compiler no longer shows the message about the RectangularNode being deprecated.

// Replacement for above statement added below by SJ on 7/3/20
RectangularNode shapeCellArea = new RectangularNode(this);
shapeCellArea.setPos(xOffset, yOffset, 0.0);
shapeCellArea.setLineColor(Color.red);
shapeCellArea.setLineStyle(LINE_STYLE_SOLID);
shapeCellArea.setLineWidth(2.0);
shapeCellArea.setPositionChoiceMode(POSITION_CHOICE_RANDOM);
shapeCellArea.setSize(width,depth);
shapeCellArea.addAttractor(new Attractor(0,0,0));
// ShapeDrawMode SHAPE_DRAW_2D3D is default mode so don't have to set that.
// end of code added by SJ on 7/3/20

Unfortunately the above changes did not remove the error. Still trying to figure out the error message and will post it as a new question.

---------- The above progress update was posted on July 4, 2020. Additional information below added on July 17, 2020 ------------

With some onlines searches and guided by the answer to another question by @Florian at How can i create Path space markup element in Anylogic via Code , I have addressed the problem by adding all the nodes to a network, adding the network to a level, and then initializing the level. The updated code is below.

Network netwkSJ = new Network(this, "mynetwork"); 
....
LinkedHashMap<String,RectangularNode> floorLayout=new LinkedHashMap<String,RectangularNode>();

// the loop in the original question here 
// added the following statement within the loop
.......
            netwkSJ.add(shapeLayoutObj); 
            floorLayout.put(layoutName, shapeLayoutObj); 

// Commented out the statement that was generating the error in the loop
// and moved it within the new loop below
                        //((Agent)temp).setLocation(shapeLayoutObj); // statement giving error

.......

Level level = new Level(this, "myLevel", SHAPE_DRAW_2D3D, 0);
level.add(netwkSJ);
level.initialize(); // cannot be changed after initialization!

Set set = floorLayout.entrySet();
//  iterating through elements of floorLayout to link machines to corresponding layout locations
         floorLayout.forEach((Name,node) -> {
         //Associate the node with a machine 
         Iterator<ArrayList<Machine>> cell=machineList.iterator();
         boolean foundAgent=false;
         while(cell.hasNext()&&!foundAgent){
            Iterator<Machine> machines=cell.next().iterator();
                while(machines.hasNext()&&!foundAgent){
                    Machine temp=((Machine)machines.next());
                    if(temp.name.equals(Name)){
                        foundAgent=true;            
                        ((Agent)temp).setLocation(node); 
                        // System.out.println(Name + " -> " );
                            }  
                        };
                    };
            });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM