Solibri View API - Code Example

IFCViewer example

This example shows how to develop a simple view that shows a web page fetched via Google Search API based on the chosen component. The view finds the IFC class that corresponds to the component, searches Google with that keyword and then displays the resulting page.

The example consists of three files.

BrowserPanel implements the browsing functionality that is added to the root JPanel.

Googler is a thin wrapper around the Java library Google provides for using their Search API. For this part, a custom Search Engine needs to be created and API keys provided.

IfCView is responsible for implementing the required interface. It also caches the results from the Google Search API to reduce the amount of necessary calls to the API (saving money, if the usage exceeds the free tier).

package com.solibri.smc.api.view.examples;

import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.scene.Scene;
import javafx.scene.layout.Region;
import javafx.scene.paint.Color;
import javafx.scene.web.WebView;

public final class BrowserPanel extends JFXPanel {

	private static final long serialVersionUID = 1L;


	public static BrowserPanel getBrowserPanel(String url) {
		final BrowserPanel panel = new BrowserPanel();
		Platform.runLater(() -> {
			Browser browser = new Browser(panel, url);
			Scene scene = new Scene(browser, 750, 500, Color.DARKGREY);
			panel.setScene(scene);
		});
		return panel;
	}

	private BrowserPanel() {
	}

	private static class Browser extends Region {
		private final WebView browser = new WebView();

		private final BrowserPanel browserPanel;

		Browser(BrowserPanel browserPanel, String urlToLoad) {
			this.browserPanel = browserPanel;

			// disable context menu
			browser.setContextMenuEnabled(false);

			// add the web view to the scene
			getChildren().add(browser);
			browser.getEngine().setUserAgent("Solibri Desktop Client");
			browser.getEngine().load(urlToLoad);
		}
	}
}

package com.solibri.smc.api.view.examples;

import java.io.IOException;
import java.security.GeneralSecurityException;

import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.customsearch.Customsearch;
import com.google.api.services.customsearch.CustomsearchRequestInitializer;
import com.google.api.services.customsearch.model.Result;
import com.google.api.services.customsearch.model.Search;

public class Googler {

	/*
	 * Google the given string and returns the first link found.
	 */
	public static String google(String object) throws IOException, GeneralSecurityException {
		String searchQuery = "site:standards.buildingsmart.org " + object;
		String cx = "010785531079632372336:h8d5gppfmbn";

		// The API must be passed as a JVM parameter. In real code it would probably be fetched some other way.
		Customsearch cs = new Customsearch.Builder(GoogleNetHttpTransport.newTrustedTransport(), JacksonFactory.getDefaultInstance(), null)
			.setApplicationName("MyApplication")
			.setGoogleClientRequestInitializer(new CustomsearchRequestInitializer(System.getProperty("google-api-key")))
			.build();

		// Set search parameter
		Customsearch.Cse.List list = cs.cse().list(searchQuery).setCx(cx);

		// Execute search
		Search result = list.execute();
		if (result.getItems() != null) {
			for (Result ri : result.getItems()) {
				return (ri.getLink());
			}
		}

		return null;

	}
}

package com.solibri.smc.api.view.examples;

import java.awt.Color;
import java.awt.Dimension;
import java.io.IOException;
import java.lang.invoke.MethodHandles;
import java.security.GeneralSecurityException;
import java.util.HashMap;
import java.util.Map;

import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.solibri.smc.api.model.Component;
import com.solibri.smc.api.ui.View;

public final class IfcView implements View {

	private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

	@Override
	public String getUniqueId() {
		return "IFC-data-viewer";
	}

	@Override
	public String getName() {
		return "IFC Data Viewer";
	}

	private BrowserPanel browserPanel = BrowserPanel.getBrowserPanel("https://technical.buildingsmart.org/");
	private JPanel root;

	@Override
	public void initializePanel(JPanel panel) {
		this.root = panel;
		JLabel label = new JLabel("Example label");
		panel.add(label);
		browserPanel.setPreferredSize(new Dimension(0, 0));
		browserPanel.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, new Color(0xD8D8D8)));
		panel.add(browserPanel);
	}

	Map<String, String> map = new HashMap<>();

	@Override
	public void onComponentChosen(Component component) {
		String ifcclass = component.getIfcClass();
		if (!map.containsKey(ifcclass)) {
			try {
				map.put(ifcclass, Googler.google(ifcclass));
			} catch (IOException | GeneralSecurityException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		root.remove(browserPanel);
		browserPanel = BrowserPanel.getBrowserPanel(map.get(ifcclass));
		root.add(browserPanel);
		SwingUtilities.invokeLater(new Runnable() {

			@Override
			public void run() {
				browserPanel.revalidate();
				browserPanel.repaint();
				root.revalidate();
				root.repaint();
			}
		});
	}

}