This sample project shows the possibility of creating a report in runtime with relation and custom object database.

First, create a class of the object that will store the data:
public class ObjectCell {
	public String val;
	
	@Override
	public boolean equals(Object obj) {
		return val.equals(((ObjectCell) obj).val);
	}
	
	public String toString() {
		return val;
	}
	
	public ObjectCell(String val) {
		this.val = val;
	}
}

Next, create the parent database that extends from StiDatabase class and fill data on the connect event:
public class ParentDatabase extends StiDatabase {
	
	public ParentDatabase() {
		super("Demo.Parent"); // Database name
	}
	
	public void connect(StiDataStoreSource stiDataStoreSource, Boolean fillTable) throws StiException {
		DataTable dataTable = stiDataStoreSource.createNewTable();
		for (int i = 0; i < 5; i++) {
			DataRow dataRow = dataTable.createNewRow();
			dataRow.addCell("cId", new ObjectCell("Object" + i));
			dataRow.addCell("cName", "Parent cId: " + i);
		}
		stiDataStoreSource.setDataTable(dataTable);
	}
	
	public void disconnect() {
	}
	
	public void connect(StiDataStoreSource stiDataStoreSource) throws StiException {
		connect(stiDataStoreSource, true);
	}
}

Next, create the same child database:
public class ChildDatabase extends StiDatabase {
	
	public ChildDatabase() {
		super("Demo.Child"); // Database name
	}
	
	public void connect(StiDataStoreSource stiDataStoreSource, Boolean fillTable) throws StiException {
		DataTable dataTable = stiDataStoreSource.createNewTable();
		for (int i = 0; i < 5; i++) {
			for (int k = 0; k < 5; k++) {
				DataRow dataRow = dataTable.createNewRow();
				dataRow.addCell("cId", new ObjectCell("Object" + i));
				for (int j = 1; j < dataRow.getColumns().size(); j++) { // fill row wiht my data
					dataRow.addCell(dataRow.getColumns().get(j).getColumnName(), "Child cId: " + i + " value: " + j);
				}
			}
		}
		stiDataStoreSource.setDataTable(dataTable);
	}
	
	public void disconnect() {
	}
	
	public void connect(StiDataStoreSource stiDataStoreSource) throws StiException {
		connect(stiDataStoreSource, true);
	}
}

To display the report we need to create Java viewer. Create the JFrame, set the necessary options and add the viewer control:
public class CreateRelationsReport extends JPanel {
	
	private static final long serialVersionUID = 330448692680237867L;
	private static final Dimension FRAME_SIZE = new Dimension(800, 800);
	public static void main(final String[] args) {
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				try {
					JFrame frame = new JFrame();
					frame.add(new CreateRelationsReport(frame));
					frame.setSize(FRAME_SIZE);
					frame.setLocationRelativeTo(null);
					frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
					frame.setVisible(true);
				} catch (Throwable e) {
					StiExceptionProvider.show(e, null);
				}
			}
		});
	}
	public CreateRelationsReport(final JFrame parentFrame) throws IOException {
		setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
		setPreferredSize(FRAME_SIZE);
		StiViewerFx viewerPanel = new StiViewerFx(parentFrame);
		add(viewerPanel);

...

Next, create the new report object, then add the parent and child databases to it:
...

		StiReport report = new StiReport();
		
		StiPage page = new StiPage(report);
		report.getPages().add(page);
		page.setName(StiNameCreation.createName(report, StiNameCreation.generateName(page)));
		report.setDictionary(new StiDictionary(report));
		report.getDictionary().getDatabases().add(new ParentDatabase());
		report.getDictionary().getDatabases().add(new ChildDatabase());

...

Next, setup the custom columns in the object table sources:
...

		List<StiDataTableSource> tableSources = new ArrayList<StiDataTableSource>();
		// parent
		StiDataTableSource tSource = new StiDataTableSource("Demo.Parent", "Parent", "Parent");
		tSource.setColumns(new StiDataColumnsCollection());
		tSource.getColumns().add(
			new StiDataColumn("cId", "cId", StiSystemType.getSystemType("System.Object")));
		tSource.getColumns().add(
			new StiDataColumn("cName", "cName", StiSystemType.getSystemType("System.String")));
		tSource.setDictionary(report.getDictionary());
		report.getDictionary().getDataSources().add(tSource);
		tableSources.add(tSource);
		// child
		tSource = new StiDataTableSource("Demo.Child", "Child", "Child");
		tSource.setColumns(new StiDataColumnsCollection());
		tSource.getColumns().add(
			new StiDataColumn("cId", "cId", StiSystemType.getSystemType("System.Object")));
		for (int i = 0; i < 4; i++) {
			tSource.getColumns().add(
				new StiDataColumn("cData" + i, "cData" + i,
				StiSystemType.getSystemType("System.String")));
		}
		tSource.setDictionary(report.getDictionary());
		report.getDictionary().getDataSources().add(tSource);
		tableSources.add(tSource);

...

Add the Header band and Data bands with text boxes to the report:
...

		// Create TitleBand
		StiHeaderBand titleBand = new StiHeaderBand();
		titleBand.setHeight(0.85);
		titleBand.setName("TitleBand");
		page.getComponents().add(titleBand);
		
		// Create Title text on header
		StiText headerText = new StiText(new StiRectangle(0, 0, page.getWidth(), 0.85));
		headerText.setTextInternal("Tacticdescription");
		headerText.setHorAlignment(StiTextHorAlignment.Left);
		headerText.setName("TitleHeader");
		headerText.setFont(new StiFont("Arial", 12F, StiFontStyle.Bold));
		titleBand.getComponents().add(headerText);
		Integer nameIndex = 1;
		List<StiDataBand> dataBands = new ArrayList<StiDataBand>();
		for (StiDataTableSource tableSource : tableSources) {
			// Create Databand
			StiDataBand dataBand = new StiDataBand();
			dataBand.setDataSourceName(tableSource.getName());
			dataBand.setHeight(0.5);
			dataBand.setName("DataBand" + nameIndex);
			nameIndex++;
			page.getComponents().add(dataBand);
			
			double pos = 0;
			double columnWidth = page.getWidth() / tableSource.getColumns().size();
			
			for (StiDataColumn dataColumn : tableSource.getColumns()) {
				StiText dataText = new StiText(new StiRectangle(pos, 0, columnWidth, 0.5));
				dataText.setText("{" + tableSource.getName() + "." + dataColumn.getName() + "}");
				dataText.setName("DataText" + nameIndex.toString());
				dataText.getBorder().setSide(StiBorderSides.All);
				dataBand.getComponents().add(dataText);
				
				pos = pos + columnWidth;
				nameIndex++;
			}
			dataBands.add(dataBand);
		}

...

All components of the report are created, we can now configure the data relations:
...

		dataBands.get(1).setDataRelationName("Relation");
		dataBands.get(1).setMasterComponent(dataBands.get(0));
		
		ArrayList<String> cols = new ArrayList<String>();
		cols.add("cId");
		
		StiDataRelation rel = new StiDataRelation("Relation", tableSources.get(0), tableSources.get(1), cols, cols);
		report.getDictionary().getRelations().add(rel);

...

Finally, render the report and show it in the Java viewer:
...

		report.Render();
		
		viewerPanel.getStiViewModel().getEventDispatcher().dispatchStiEvent(
			new StiViewCommonEvent(StiViewCommonEvent.DOCUMENT_FILE_LOADED,
			new StiDocument(report), null));
	}

На скриншоте ниже Вы можете увидеть результат выполнения данного кода:

Creating Report with Relations at Runtime

Используя этот сайт, вы соглашаетесь на использование файлов Cookie для аналитики и персонализированного контента. Файлы Cookie хранят полезную информацию на вашем компьютере, чтобы помочь нам повысить эффективность и удобство использования. Для получения дополнительной информации, пожалуйста, прочтите Конфиденциальность и Использование Cookie.