Anylogic: Create text by Java with dynamic text content - anylogic

I want to create text using Java so that I can use codes to control how many shapetext to create and auto position them, but I want to link the text content to a dynamic value that is changing (e.g. a variable storing a parameter that varies during runtime). I am using the code below to create the text, however, when I replace "Test" with a variable, the text captures the value at the initial instance and remains a static value.
Is there any way to make the content dynamic or I can only write a function to actively refresh the text content?
Also, using a function to actively update the value makes the model run slower right? I compared the runs and observe that the model runtime is significantly slower.
col_Label_EQ.add(new ShapeText(SHAPE_DRAW_2D,
true,
0,
0,
0,
0,
white,
"Test",
new Font("SansSerif",
Font.BOLD,
10),
ALIGNMENT_CENTER));
presentation.add(col_Label_EQ.get(0));

Related

How to create shapetext using Java

I am trying to create shape texts directly using codes as the number of shapetext i need may vary.
I tried using the code below, and I created the shapes in a collection (with type shapetext). When I use "traceln(text.getX());" it prints 2500 but I do not see the text anywhere on the screen. May I understand what I have done wrongly and how can I make the shapetext be shown? Do I have to add shapetexts into my network/level and initialize it?
Thank you for your help!
ShapeText text = new ShapeText(SHAPE_DRAW_2D3D, true, (double) 2500, (double) 3000, (double) 0, 0, black, "testing", new Font("SansSerif", Font.BOLD, 100), ALIGNMENT_CENTER );
You have successfully created the text, but you need to add it to the presentation to be shown
Simply add
presentation.add(text);
An alternative option if you have an undetermined amount of texts is to rather create a single text object and then replicate it as many times as you want to show it. Once you add a replication to a presentation object a local variable called index is now available for you to use in many of the fields.
Use this in the dynamic text field to get the values you want to display (like in the example below I stored the texts in a collection)
And you also use this index to change the position of the text (See what I have done in the Y coordinates)

How to insert a non-inline picture into a word document using VB6?

I am trying to insert an image into a word document using the Microsoft word 15.0 objects library included with VB^ and the only way I've seen to insert a graphics file is through this:
oDoc.Range.InlineShapes.AddPicture ("C:\Users\name\Desktop\file.jpg")
But, I want a picture that can be positioned over the text and where I want it in the document... Is there any way to do this using VB6 Code?
Word has two different ways to manage images and other embedded objects: as InlineShapes and as Shapes. The first are treated the same as characters in the text flow; the latter have text wrap foramtting and "live" in a different layer from the text.
To insert a graphics file as a Shape:
Dim shp as Word.Shape
Set shp = oDoc.Shapes.AddPicture(FileName, LinkToFile, _
SaveWithDocument, Left, Top, Width, Height, Anchor)
The AddPicture method returns a Shape object. Often, this is useful when additional properties need to be set after the object has been inserted. For example in order to specify the text wrap formatting. If no Shape object is required a Shape can be inserted without assigning to an object. In this case, leave out the parentheses:
oDoc.Shapes.AddPicture FileName, LinkToFile, _
SaveWithDocument, Left, Top, Width, Height, Anchor
While only the FileName argument is required, the last argument - Anchor - is very important if you want to control where the image is positioned when it's inserted.
It's also possible to insert as an InlineShape then use ConvertToShape in order to have a Shape object to which text wrap formatting can be applied.
Every Shape must be associated with a Range in the document. Unless otherwise specified, this will be the first character of the paragraph wherein the current selection is. I strongly recommend passing a Range to the Shapes.AddPicture method in the Anchor argument for this reason.
Note that once a Shape has been inserted there's no direct way to change the anchor position. It can be done using cut & paste. Another possibility is to use the ConvertToInlineShape method so that you can work with the Range to move the graphic, then ConvertToShape to turn it back into a Shape, but in this case a number of positioning and wrap properties may need to be reset. Here an example of using the "convert" methods:
Sub MoveShapeToOtherRange()
Dim oDoc As Word.Document
Dim shp As Word.Shape
Dim ils As Word.InlineShape
Dim rngEnd As Word.Range, rngStart As Word.Range
Set oDoc = ActiveDocument
Set rngStart = oDoc.content
rngStart.Collapse wdCollapseStart 'start of document
Set rngEnd = Selection.Range
Set shp = oDoc.shapes.AddPicture(fileName:="C:\Test\icons\Addin_Icon16x16.png", _
Top:=0, Left:=10, anchor:=rngStart)
Set ils = shp.ConvertToInlineShape
Set rngStart = ils.Range
rngEnd.FormattedText = rngStart.FormattedText
rngStart.Delete
Set ils = oDoc.InlineShapes(1)
Set shp = ils.ConvertToShape
End Sub
By default, a Shape will insert with MoveWithText activated. That means the position on the page is not set, editing will affect the vertical position. If you want the Shape to always be centered on the page, for example, set this to false. Note, however, that if the anchor point moves to a different page, the Shape will also move to that page.
On occasion, the Left and Top arguments don't "take" when adding a Shape - you may need to set these again as properties after adding it.
Ok, What I ended up doing that worked was this:
Dim a As Object
On Error Resume Next
a = oDoc.Shapes.AddPicture("C:\Users\name\Desktop\file.jpg", , , 25, 25, 25, 25)
For some reason, This places the image at the position and size. When I looked at the docs for ".AddPicture" I realized it returns a Shapes object. So I just had it store it in a throw-away object. For some reason it then would respond with an error, but would end up placing on the doc anyways. So I used:
On Error Resume Next
This skips the error. After that, the picture places as expected and the rest of the doc is made as expected
Thank you for your answers

Do I have to create a reference for each text I have in a panel, if I want to access them to modify?

I have a panel with 8 text field, 4 are used as descriptive field (what a label would do, basically), while the other 4 are modified with values.
I am creating a GameObject variable for every element that I have in the panel, using find to find the specific text element. I can leverage on the fact that each text object has only one text object attached to it, so I can address to it directly with GetComponent
panel_info = GameObject.Find("infopanel");
textfield1 = GameObject.Find("text_name");
textfield2 = GameObject.Find("text_age");
textfield3 = GameObject.Find("text_role");
textfield4 = GameObject.Find("text_field");
textfield1.GetComponent<Text>().text = "joe";
textfield2.GetComponent<Text>().text = "22";
textfield3.GetComponent<Text>().text = "striker";
textfield4.GetComponent<Text>().text = "attack";
While this works, I can't foresee myself creating 20-30 objects if a panel has more info to display.
Since I have the reference to the object Panel, is there a way to address directly the text field which is a child of the panel, using the text field name for example?
So if a panel has 4 text field, I can modify each of it addressing directly by name, and then using GetComponent<Text>().textto change the value.
You MUST NOT call GetComponent<Text>() each time you want to access/modify text.
This is an extremely basic fact about Unity.
It is immediately mentioned in the relevant manual entries.
Since you have 8 textbox and I don't know how long you update each one. It would be good if you cache all of them in the beginning of the game then use them later on without GetComponent<Text>(). This will improve performance a lot and make your frame-rate happy.
Array looks good for something like this. And you need to comment each one too.
public Text[] textBoxArray;
On the editor, Expand the "Text Box Array" and change the array Size to 8.
Now drag each GameObject with the text to the arrays in order. If you do it in order, you can easily remember their names and be able to access them in order.
For example, if the first text gameobecjt you dragged to the array is called text_name, the access it, you use textBoxArray[0]. The second text which is text_age can be accessed with textBoxArray[1]. .....
To make it easier for you later on, you should have multiple line comment that describes which array points to what.You do this so that when you return to modify your code months after, you won't have to look around in the Editor to find what points to what. For example:
/*
textBoxArray[0] = text_name
textBoxArray[1] = text_age
textBoxArray[2] = text_role
textBoxArray[3] = text_field
*/
No performance lost and that decreases the amount of code in your game.
Initializing the arrays by code instead of the Editor
Assuming you want to initialize the arrays by code instead of the Editor. You can do it in the start function like below.
public Text[] textBoxArray;
void Start()
{
//Create arrays of 8
textBoxArray = new Text[8]; //8 texts
//Cache all the Text GameObjects
textBoxArray[0] = GameObject.Find("/infopanel/text_name").GetComponent<Text>();
textBoxArray[1] = GameObject.Find("/infopanel/text_age").GetComponent<Text>();
textBoxArray[2] = GameObject.Find("/infopanel/text_role").GetComponent<Text>();
textBoxArray[3] = GameObject.Find("/infopanel/text_field").GetComponent<Text>();
}
You should notice that GameObject.Find() starts with "/" and that increases performance too as it will only search for Texts under "infopanel" instead of searching in the whole scene.
Assuming that your hierarchy is setup that all your TextMeshes are children of the panel, you could use the Transform.Find method to get each child, then it's TextMesh, and assign a value.
So, for example, if you wanted to assign the value "Joe" to the TextMesh attached to "text_name", which in turn is a child of "infopanel", you could do the following
panel_info = GameObject.Find("infopanel");
panel_info.transform.Find("text_name").GetComponent<TextMesh>().text = "Joe";

Bokeh - How to use box tool without default selections?

I have built a bokeh app that allows users to select windows in data and run python code to find and label (with markers) extreme values within these limits. For ease of interaction, I use the box select tool for the range selection. My problem arises when repeating this process for subsequent cases. After markers are placed for the results, they are rendered invisible by setting alpha to zero and another case needs to be chosen. When the new select box includes previous markers, they become visible based on the selection. How do I override this default behavior? Can markers be made unselectable? or can I add code to the customJS to hide them after they are selected?
Thanks in advance for any help!
There are a few possible approaches. If you just want non-selected glyphs to "disappear" visually, you can set a policy to do that as described here:
http://docs.bokeh.org/en/latest/docs/user_guide/styling.html#selected-and-unselected-glyphs
Basically, for bokeh.plotting, pass
nonselection_fill_alpha=0.0,
nonselection_line_alpha=0.0,
as arguments to your plot.circle call or whatever. Or if you are using the low level bokeh.models interface, something like:
renderer.nonselection_glyph = Circle(fill_alpha=0.0, line_alpha=0.0)
But be aware (I think you already are) that the invisible markers are still there, and still selectable if the user happens to draw a box over them with the selection tool.
If you truly want only a subset of the data to be visible and selectable after a selection, I'd say you want to replace the data in the column data source wholesale with the subset in your selection callback.

Reference Table to fill calendar form

In Access 2010, I've built a calendar Form that I want to be able to display who is off in a given month.
Each box of the calendar obviously represents a different day. I've got a table called "Separated" set up that ultimately stores the associate name and the date they are off -- one day per record.
Here's what I've done so far to try to test it on just one of the boxes (representing a day):
Private Function fillDays()
Dim rsNames As DAO.Recordset
Set rsNames = CurrentDb.OpenRecordset("SELECT * FROM Separated")
If Not rsNames.EOF Then
b0.Text = rsNames![Associate]
End If
Set rsNames = Nothing
End Function
I get the following debug note:
"Run-Time Error '2185"
"You can't reference a property or method for a control unless the control has the focus."
The debugger highlights the line with "b0.text = rsNames![Associate]
Is there some whay that I need to reference an index number from my "Separated" table?... or perhaps using a query method of some sort would be more effecient.
Assuming b0 is a textbox, the error you are getting is due to the fact that you can't use it's Text property when said textbox hasn't got the focus.
As stated in MSDN, «While the control has the focus, the Text property contains the text data currently in the control; the Value property contains the last saved data for the control. When you move the focus to another control, the control's data is updated, and the Value property is set to this new value. The Text property setting is then unavailable until the control gets the focus again» (emphasis mine).
Try using Value (help here) instead:
b0.Value = rsNames![Associate]