==================================
HOOPS/Java Swing Programming Guide
==================================

Introduction
============

The HOOPS/Java Swing integration consists of a connection between HOOPS/3DGS and the Java/Swing 'HCanvas' GUI object. This document describes how to use the HOOPS/Java integration to build a Java/Swing application that incorporates the HOOPS/3DF components. Some familiarity with Java/Swing, HOOPS/3DGS and HOOPS/MVO is assumed. 

Developers should start by compiling and running the basic *java_simple* application as the starting point for their application. This is the primary example for Java developers wishing to incorporate the HOOPS/3DF components into new or existing Java applications. This integration uses the Java/Swing libraries. The readable source code is located in your *<hoops>/demo/java/java_simple* directory.

The *<hoops>/demo/java/java_simple_3dgs_only* directory contains some very simple applications that only uses HOOPS/3DGS, and draws into a user-created window.


Platform/Compiler Support
=========================

The HOOPS/Java integration is supported under the J2SE Development Kit 6.0 (JDK 6.0), on Windows and Linux platforms.


Compilation and Runtime Information
===================================

The following steps are required to compile and run a HOOPS/Java based application: 

.. raw:: htmlonly

	<ul>
	  <li><strong>Compiling</strong>: You must place the HOOPS/3DF and HOOPS/Java <i>.jar</i> files in your class path.  This can either be done via the command line for both compiling and running, or it can be set in the manifest file for your project. The files are:    
	  
		<ul>
		  <li>HJ<version>.jar
		  <li>HJMVO<version>.jar
		  <li>HJSTREAM<version>.jar
		  <li>HJCanvas<version>.jar
		</ul>
	  
	  <li><strong>Executing</strong>: Ensure that the following files are in your application's directory.
		<ul>
		  <li>.jar files: <strong>(discussed above) </strong>
		  <li>java wrapper libraries::      
			<ul>
			  <li>hj<version>.dll
			  <li>hjmvo<version>.dll
			  <li>hjstream<version>.dll
			</ul>
		  
		  <li>native libraries:
			<ul>
			  <li>hoops<version>_vc<MS Visual Studio Version>.dll
			  <li>hoops_mvo<version>_vc<MS Visual Studio Version>.dll
			  <li>hoops_stream<version>_vc<MS Visual Studio Version>.dll
			</ul>
		  
		  <li>AWT libraries: 
			<ul>
			  <li>jawt.dll
			  <li>java_awt_canvas<version>.dll
			</ul>
		  
		</ul>
	  
	</ul>

With the exception of *jawt.dll* (which comes from the JDK installation's *jre/bin* directory), the above files should all be located in your *<hoops>/bin/nt_<platform>_<MS Visual Studio Version>* directory. 


Component Oject Relationships
==============================

This section discusses the relationship between Java and HOOPS/3DF components. Building an application with both these toolkits minimally involves using the following objects from each component.


Java
----

A Java/Swing application would typically have a master application object and a ``JFrame`` object.


HOOPS/Java
----------

Your application should have at least one ``HJCanvas`` - typically, you would create a custom canvas derived from ``HJCanvas``. The source for the ``HJCanvas`` class can be found in the *<hoops>/Dev_Tools/hoops_java/source* directory. This will get added to the ``JFrame`` object mentioned above. 


HOOPS/MVO
---------

``HBaseModel``, ``HBaseView``, and an operator class derived from ``HBaseOperator		. Applications that want to implement selection of geometry will also need a ``HSelectionSet`` object. These objects are all connected by private data members which store pointers to other objects in the following manner: 

.. image:: images/HOOPS_java_arch.gif


Steps to Building an Application with Java/Swing and HOOPS
==========================================================

Programming with an object oriented GUI framework like Java/Swing involves creating a set of objects and defining the ways in which they are connected, the manner in which they send and receive messages, and then launching the framework's event loop. Building an application using Java/Swing and  HOOPS/3dAF specifically requires creation and initialization of:

* :ref:`Java/Swing Application objects <prog_guide/misc/swing_integration:Creating and initializing the application>` 
* :ref:`HOOPS/Java objects <prog_guide/misc/swing_integration:Creating and initializing HOOPS/Java objects>`
* :ref:`HOOPS/MVO objects <prog_guide/misc/swing_integration:Creating and Initializing HOOPS/MVO Objects>`


Creating and Initializing the Application
=========================================

A Java/Swing application typically creates a master application object which implements the function ``main()``. The *java_simple* application provides an example which also creates a custom class called ``JSimpleApplication`` and calls its ``CreateNewDocument`` method::

	public class java_simple
	{
		static public JSimpleApplicaton theApp;
		
		public static void main(String[] argv)
		{
			theApp = new JSimpleApplicaton();
			theApp.CreateNewDocument();
		}         
	}

The sample ``JSimpleApplication`` implementation includes a method called ``CreateNewDocument`` which will create a custom ``JFrame`` object::

	class JSimpleApplicaton
	{

		...
			
		public void CreateNewDocument()
		{
			new JSimpleDocument();
		}   	
	}

	class JSimpleDocument extends JFrame
	{
	}


Creating and Initializing HOOPS/Java Objects
============================================

The GUI aspect of the HOOPS/Java integration simply consists of a customized Java/Swing canvas called ``HJCanvas`` as diagrammed up above. As many ``HJCanvas`` objects can be created as needed to implement the GUI's design. Theapplication should create a custom HJCanvas class, as shown in *java_simple*::

	class SimpleHJCanvas extends HJCanvas
	{        
	}

Your custom canvas will most likely be created and attached in your custom ``JFrame`` constructor::

	class JSimpleDocument extends JFrame
	{
		private SimpleHJCanvas m_SimpleHJCanvas;
		  
		public JSimpleDocument()
		{
			...

			m_SimpleHJCanvas = new SimpleHJCanvas();
			getContentPane().add(m_SimpleHJCanvas);
			setVisible(true);
		}
	}


Creating and Initializing HOOPS/MVO Objects
===========================================

HDB
---

One global pointer to a HOOPS/MVO HDB object should be declared and initialized in the application's main class. The *java_simple* app does this in the ``JSimpleApplication`` constructor::

	class JSimpleApplicaton
	{
		...

		public JSimpleApplicaton()
		{
			m_HDB = new HDB();
			m_HDB.Init();
		}
	   
		...
	}


HBaseModel
----------

Multiple ``HBaseModel`` objects can be created as needed. The *java_simple* app creates one for every ``SimpleHJCanvas`` object (i.e., there is a one-to-one mapping of ``HBaseModel`` to ``SimpleHJCanvas`` objects) and does so in the ``SimpleHJCanvas`` constructor::

	class SimpleHJCanvas extends HJCanvas
	{
		public SimpleHJCanvas()
		{
			super();
			m_HModel = new HSimpleModel();
			m_HModel.Init();
		}
	}

    
``HBaseView``
-------------

Multiple ``HBaseView`` objects can be created as needed, with one object usually being created for each ``HJCanvas``. The ``HBaseView`` needs a valid native GUI window id passed to its constructor on object creation. This information is used to connect a HOOPS/3dGS output driver instance to ``HJCanvas``. This requires that the ``HJCanvas``, to which the ``HBaseView`` will be attached,  already exist prior to creating the ``HBaseView`` object.

The app should create the ``HBaseView`` object in an overloaded ``HJCanvas::Init`` method. This method is called by the base class ``HJCanvas`` in its ``HJCanvas::paint`` method the first time it is called, which first ensures that the widget is alive and thus the Window ID is valid and the ``HBaseView`` object can be created. The *java_simple* example::

	class SimpleHJCanvas extends HJCanvas
	{
		...

		public void Init()
		{
			if (m_HView == null)
			{
				long hnd = get_window_handle(getGraphics());
				SWIGTYPE_p_void swig;
				swig = new SWIGTYPE_p_void(hnd, true);
				
				m_HView = new HSimpleView(m_HModel, "", "opengl", "", swig);
				m_HView.Init();
				
				...
			}
		}
		
		...
	}


``HSelectionSet``
-----------------

The ``HBaseView`` class has a member ``HBaseView::m_pSelection`` that is a pointer to an ``HSelectionSet`` object. Multiple 
``HSelectionSet`` objects can be created as needed, but usually there is a one-to-one mapping of ``HSelectionSet`` to 
``HBaseView`` objects. Similar to the initial ``HBaseOperator``, the selection set object would typically be created and 
initialized in the ``HJCanvas::Init`` method. After creating it, it's important to pass its pointer into ``HBaseView`` by 
calling ``HBaseView::SetSelection``::

	class SimpleHJCanvas extends HJCanvas
	{
		...

		public void Init()
		{
			if (m_HView == null)
			{
				...
				
				m_HSelectionSet = new HSimpleSelectionSet(m_HView);
				m_HSelectionSet.Init();
				m_HView.SetSelection(m_HSelectionSet);

				...
			}
		}
	}


``HBaseOperator``
-----------------

A default operator should be created during view initialization, and made the current operator which is done by calling the ``HJCanvas::SetCurrentOperator`` utility function. This utility will set the ``HBaseView::m_pOperator`` member which is a pointer to an ``HBaseOperator``. The *java_simple* app does this in the overloaded method of ``HJCanvas::Init``:: 

	class SimpleHJCanvas extends HJCanvas
	{
		...

		public void Init()
		{
			if (m_HView == null)
			{
				...
				
				// Set the default operator
				m_HOperator = new HOpCameraManipulate(m_HView);
				m_HView.SetCurrentOperator((HBaseOperator)m_HOperator);

				...
			}
		}
	}
