Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

Embed Java code into your native apps

Integrate a Java user interface with legacy code on Unix

  • Print
  • Feedback

Page 5 of 7

You can assume that OpenGL and glX are multithread-safe -- i.e., they can actually support concurrent access from different threads. But that is nothing more than an assumption; the reality is implementation-dependent.

You might consider implementing the locking system that you used when accessing the drawing surface, but this time, neither OpenGL nor glX provide such a mechanism. You'll need to implement it yourself, which can prove quite complicated if you're unsure which calls need lock protection.

The best solution to solving this architectural issue is simple: OpenGL and glX functions must always be called from the same thread. In your case, they should always be called from the legacy application's main thread. It seems that you return to the initial question: how do you create an OpenGL document from Java? Well, if Java cannot call OpenGL and glX directly -- that is, synchronously -- you need a messaging mechanism. You will use that messaging mechanism to send instructions from Java to your legacy application's main thread.

One messaging mechanism that comes to mind is sockets, a classical means for communicating between processes. When the different processes are located on the same system, you should have no concerns about communication reliability. In these cases, use datagram sockets. They are fast, use a light protocol, and are easy to implement. You'll use datagram sockets to communicate inside the same process but between two threads. The ActionListener Java interface acts as a socket client. It uses a socket to send messages to the legacy application thread. Listing 4 shows how to implement the client side:

Listing 4: Socket client in Java

// File SwingMenu.java
import javax.swing.*;
import java.awt.event.*;
import java.net.DatagramSocket;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.io.IOException;
class SwingMenu extends JFrame implements ActionListener {
   private int            outPort=9970;   // Must be equal to IN_PORT in
main.c
   private DatagramSocket inSocket;
   private DatagramPacket createOGLWin;
   private DatagramPacket animate;
   private native void    changeColour(int colour);
   // Method to create a socket
   private void initSocket() {
      try {
      inSocket = new DatagramSocket();
      } catch (Exception exc) {
      System.out.println("Unable to create a socket");
      System.out.println("Error: "+exc.toString());
      System.exit(99);
      }
      try {
      InetAddress localAddr = InetAddress.getLocalHost();
      String oglWinStr = new String("CreateOGLWindow");
      createOGLWin     = new DatagramPacket(oglWinStr.getBytes(),
oglWinStr.length(),
                                              localAddr, outPort);
      String animateStr = new String("Animate");
      animate           = new DatagramPacket(animateStr.getBytes(),
animateStr.length(),
                                     localAddr, outPort);
      } catch (UnknownHostException exc) {
      System.out.println("Unable to get local host address");
      System.out.println(exc.toString());
      System.exit(99);
      }
   }
   //  Method to handle button events
   public void actionPerformed(ActionEvent evt) {
      String string = evt.getActionCommand();
      if (string.equals("Red")) {
         changeColour(1);
      } else if (string.equals("Yellow")) {
         changeColour(2);
      } else if (string.equals("Create OpenGL window")) {
         try { inSocket.send(createOGLWin); }
         catch (IOException exc) {System.out.println(exc.toString()); }
      } else if (string.equals("Animate")) {
         try { inSocket.send(animate); }
         catch (IOException exc) {System.out.println(exc.toString()); }
      } else if (string.equals("Exit")) {
         System.exit(0);
      }
   }
}


Calling the DatagramSocket() constructor without any argument creates a socket and binds it to any available port on the local host. That socket sends datagram packets. You have to build those packets using the DatagramPacket class. Packets are sent to the local host through a specific port (the socket server binds its socket to this port).

  • Print
  • Feedback

Resources