Over a million developers have joined DZone.

Rule Based Swing UI Generation

DZone's Guide to

Rule Based Swing UI Generation

· Java Zone
Free Resource

Just released, a free O’Reilly book on Reactive Microsystems: The Evolution of Microservices at Scale. Brought to you in partnership with Lightbend.

There was a requirement to generate user interfaces on fly for different use cases. It is also required to allow the end user to change the look and feel and layout
without changing the java code. I was working on prototype which involved apache velocity and jboss drools.

So, what I did, I created the velocity template which acted as a layout generator based on drools syntax. When the Usecase object was passed to the rule engine, the JPanel object was received. Here, I am going to present the simple test case to elaborate this concept.
I am sure it can play a fundamental role in creating and developing more complex scenarios. Rules.vm file is created in the templates folder as follows:

#package com.eagle.coders.drools.rules

import com.eagle.coders.drools.UseCaseObject;

import java.awt.FlowLayout;
import java.awt.GridLayout;>

import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;

#list any import classes here.

#declare any global variables here

rule "use case generation"
	no-loop true
		$u : UseCaseObject( )
		JLabel uLabel = new JLabel("userName :");
		JTextField uField = new JTextField(10);
		JPanel uPanel = new JPanel();
		uPanel.setLayout(new FlowLayout());
		JLabel uPassword = new JLabel("password :");
		JPasswordField pField = new JPasswordField(10);
		JPanel pPanel = new JPanel();
		pPanel.setLayout(new FlowLayout());
		JPanel mainPanel = new JPanel();


The UsecaseObject is a simple POJO
package com.eagle.coders.drools;

 * @author Anees
public class UseCaseObject {

	private String usecase;

	 * @return the usecase
	public String getUsecase() {
		return usecase;

	 * @param usecase the usecase to set
	public void setUsecase(String usecase) {
		this.usecase = usecase;

Now our testing class is as follows
package com.eagle.coders.drools;

import java.io.StringReader;
import java.io.StringWriter;
import java.util.Collection;

import javax.swing.JFrame;
import javax.swing.JPanel;

import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseFactory;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;
import org.drools.definition.KnowledgePackage;
import org.drools.io.Resource;
import org.drools.io.ResourceFactory;
import org.drools.runtime.StatefulKnowledgeSession;

 * @author Anees
public class TestingUsecase {

	public static void main(String[] args) {

		final KnowledgeBuilder kbuilder = KnowledgeBuilderFactory

		VelocityContext context = new VelocityContext();

		Template template = Velocity.getTemplate("templates/Rules.vm");
		// System.out.println(" THE TEMPLATE IS :: "+template.getName());

		StringWriter w = new StringWriter();
		template.merge(context, w);
		// System.out.println(" RULES :: "+ w.toString());

		Resource stringRes = ResourceFactory
				.newReaderResource(new StringReader(w.toString()));
		kbuilder.add(stringRes, ResourceType.DRL);
		// Check the builder for errors
		if (kbuilder.hasErrors()) {
			throw new RuntimeException("Unable to compile \"Rules.vm\".");
		// get the compiled packages (which are serializable)
		final Collection pkgs = kbuilder
		// add the packages to a knowledgebase (deploy the knowledge packages).
		final KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();

		final StatefulKnowledgeSession ksession = kbase
		UseCaseObject usecaseObject = new UseCaseObject();

		Collection objects = ksession.getObjects();
		Object[] objArray = objects.toArray();
		JPanel panel =(JPanel) objArray[0];
		JFrame frame = new JFrame("Testing Framework");
		frame.setSize(300, 100);

Even though this is a very simple prototype example but it can open new horizons to generate complex user interfaces.
However, more sophisticated Layout Managers like FormLayout and MigLayout must be used in Velocity Templates.
This concept will definitely help in removing the tight coupling of the user interface generation from the application.
Hopefully, this idea will help the developers to create more loosely coupled frameworks.

Strategies and techniques for building scalable and resilient microservices to refactor a monolithic application step-by-step, a free O'Reilly book. Brought to you in partnership with Lightbend.


Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}