Using Template Canvas

I'm having an unusual problem when using a Template Canvas.

reportCanvas = system.gui.getWindow("My Windows/ReportViewTemplateCanvas").rootContainer.getComponent("reportCanvas")

thisRow = [randomName, reportTemplate, None, 0, 0, None, None, {}]
reportCanvas.templates = system.dataset.addRow(reportCanvas.templates, thisRow)

print("Templates row count = " + str(reportCanvas.templates.getRowCount()))

for template in reportCanvas.getAllTemplates():
----->print(template.getInstanceName())

So, I'm adding a new template to the canvas with the name randomName. After I add it with the addRow() method on the dataset, the Templates row count, as printed out, is now 1, which is expected. However, when I call reportCanvas.getAllTemplates(), it return 0 templates. If I try to call reportCanvas.getTemplate(randomName), it returns None. What's going on here?

Also, when I run it subsequent times, the Template row count is always one higher than the template names that print out in my loop, with the most recent one added missing from the list.

Thanks

2 Likes

When manipulating the list of templates, there’s asynchronous processing, partly in the background, to reconstruct the dynamic components. That can’t even begin until your script is complete, since Java Swing is single-threaded. Whatever you are trying to do, you need to defer briefly for the canvas to “catch up”.

Thanks Phil, that’s what I was afraid of. We have a series of labels that print out when specific functions are performed, and I can’t seem to find a way that will do it properly. With executeAndDistribute, it works fine except it only comes out on Gateway printers and we need it to go to the client. With bringing up a report and using the print() function, we end up loading the second or third label before the first one hits the print on the invokeLater and get several copies of the last label. I wrote my own using the printx java features which works great except the JPG or PNG copies of the reports look horrible, and the PDF version will only print out to a printer with built-in PDF.

I also tried using a template canvas and creating a new instance of a template report viewer as well as using a client tag with a tag change script, both of which had the same timing issue and either throwing a null pointer or printing multiple copies of the same label.

I’m out of ideas at this point. You got anything?? :smiley:

Gary

By defer, I meant something using a timer component or system.util.invokeLater().

Or just provide separate print button for the operator to click after the labels in your canvas look right.

If this is intended to be an unattended process, I strongly recommend adding the printers to the gateway, via whatever networking setup applies, in order to use reportAndDistribute() from a gateway script.

It’s not an unattended process. Our manufacturing machines are running a process where labels (reports, really), need to come out when materials are returned to the floor. The operator checks which materials are being returned, and the client printer prints out labels for each item being returned. I’m already using the following code, which, because of the invokeLater required, is causing collisions with labels that may have already been loaded when invokeLater is called. On the print call, I often get a NullPointer because the reportViewer to which it was referring has already closed.

	def readyToPrint():
		for count in range(copies):
			reportViewer.print(None, False)

		system.nav.closeWindow("Windows/ReportView")
		
	def waitingToPrint():
		while reportViewer.reportLoading:
			pass
		system.util.invokeLater(readyToPrint)

	system.util.invokeAsynchronous(waitingToPrint)

Thanks

You have more problems than you think. waitingToPrint() is burning an entire CPU in a loop, and it is referencing a GUI property from a non-gui thread. Your invokeAsynchronous should be an invokeLater with a short delay. Instead of looping in waitingToPrint(), you should have an if-else construct that fires another invokeLater (of itself) with a delay, or does the print operation.

Thanks, Phil. I got that code off the forums at IA, but we were questioning using the asynchronous thread just for that reason. I’ll try what you suggested and see if the invokeLater delay can solve the problem.

Best Regards,
Gary