Advertisement
Guest User

Interface to R with JRI in Scala

a guest
Oct 21st, 2011
2,252
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Scala 5.01 KB | None | 0 0
  1. /**
  2.  * @author Roelof Oomen, with code from rJava examples
  3.  *
  4.  */
  5. package rinterface
  6.  
  7. import java.awt.event.WindowEvent
  8. import java.awt.event.WindowListener
  9. import java.awt.Component
  10. import java.awt.FileDialog
  11. import java.awt.Frame
  12. import java.io.BufferedReader
  13. import java.io.InputStreamReader
  14. import java.io.PrintStream
  15.  
  16. import org.rosuda.JRI.RMainLoopCallbacks
  17. import org.rosuda.JRI.Rengine
  18. import org.rosuda.javaGD.GDInterface
  19. import org.rosuda.javaGD.JGDBufferedPanel
  20.  
  21. import javax.swing.JFrame
  22. import javax.swing.WindowConstants
  23.  
  24. /**
  25.  * Callback class for R interface.
  26.  * @param out Stream to output R messages to, e.g. StdOut: System.out
  27.  */
  28. //TODO: JGR manages to have for example the R "demo()" window functioning, I don't.
  29. private class RConsole( out: PrintStream ) extends RMainLoopCallbacks {
  30.  
  31.     def rWriteConsole( re: Rengine, text: String, oType: Int ) {
  32.         out.println( text )
  33.     }
  34.  
  35.     def rBusy( re: Rengine, which: Int ) {
  36.         //TODO: Change cursor to hourglass here, but that would mean I would need to merge this class with
  37.         // the class implementing the frame with the console.
  38.         //.out.println( "rBusy(" + which + ")" )
  39.     }
  40.  
  41.     def rReadConsole( re: Rengine, prompt: String, addToHistory: Int ): String = {
  42.         out.print( prompt )
  43.         try {
  44.             val br = new BufferedReader( new InputStreamReader( System.in ) )
  45.             val s = br.readLine()
  46.             return if ( s == null || s.length() == 0 ) s else s + "\n"
  47.         } catch {
  48.             case e: Exception => out.println( "jriReadConsole exception: " + e.getMessage() )
  49.         }
  50.         return null
  51.     }
  52.  
  53.     def rShowMessage( re: Rengine, message: String ) {
  54.         out.println( "Error: \"" + message + "\"" )
  55.     }
  56.  
  57.     def rChooseFile( re: Rengine, newFile: Int ) = {
  58.         val fd = new FileDialog( new Frame(),
  59.             if ( newFile == 0 ) "Select a file" else "Select a new file",
  60.             if ( newFile == 0 ) FileDialog.LOAD else FileDialog.SAVE )
  61.         fd.setVisible( true )
  62.         var res = ""
  63.         if ( fd.getDirectory() != null )
  64.             res = fd.getDirectory()
  65.         if ( fd.getFile() != null )
  66.             res = if ( res == null ) fd.getFile() else ( res + fd.getFile() )
  67.         res
  68.     }
  69.  
  70.     def rFlushConsole( re: Rengine ) {
  71.         out.flush
  72.     }
  73.  
  74.     def rLoadHistory( re: Rengine, filename: String ) {
  75.     }
  76.  
  77.     def rSaveHistory( re: Rengine, filename: String ) {
  78.     }
  79. }
  80.  
  81. /**
  82.  * Class providing the Frame that will function as a "Java Graphics Device" in R.
  83.  * This class is not required, but can be used to extend the functionality of the
  84.  * JavaGD frame, or to embed it in another window.
  85.  */
  86. class RWindow extends GDInterface with WindowListener {
  87.  
  88.     var fGD: JFrame = null
  89.  
  90.     override def gdOpen( w: Double, h: Double ) {
  91.         if ( fGD != null ) gdClose()
  92.         fGD = new JFrame( "JavaGD" )
  93.         fGD.setDefaultCloseOperation( WindowConstants.DISPOSE_ON_CLOSE )
  94.         fGD.addWindowListener( this )
  95.         c = new JGDBufferedPanel( w, h )
  96.         fGD.getContentPane().add( c.asInstanceOf[Component] )
  97.         fGD.pack()
  98.         fGD.setVisible( true )
  99.     }
  100.  
  101.     override def gdClose() {
  102.         super.gdClose()
  103.         if ( fGD != null ) {
  104.             c = null
  105.             fGD.removeAll()
  106.             fGD.dispose()
  107.             fGD = null
  108.         }
  109.     }
  110.  
  111.     /** listener response to "Close" - effectively invokes <code>dev.off()</code> on the device */
  112.     def windowClosing( e: WindowEvent ) {
  113.         if ( c != null )
  114.             executeDevOff()
  115.     }
  116.     def windowClosed( e: WindowEvent ) {}
  117.     def windowOpened( e: WindowEvent ) {}
  118.     def windowIconified( e: WindowEvent ) {}
  119.     def windowDeiconified( e: WindowEvent ) {}
  120.     def windowActivated( e: WindowEvent ) {}
  121.     def windowDeactivated( e: WindowEvent ) {}
  122.  
  123. }
  124.  
  125. /**
  126.  * Create link to R
  127.  * @param out Stream to output R messages to, e.g. StdOut: System.out
  128.  */
  129. class RInterface( out: PrintStream ) {
  130.  
  131.     var engine: Rengine = null
  132.  
  133.     def startR: Boolean = {
  134.  
  135.         // just making sure we have the right version of everything
  136.         if ( !Rengine.versionCheck() ) {
  137.             System.err.println( "** Version mismatch - Java files don't match library version." )
  138.             false
  139.         } else {
  140.             System.out.println( "Creating Rengine" )
  141.             // 1) we don't pass the arguments from the command line
  142.             // 2) we won't use the main loop at first, we'll start it later
  143.             // (that's the "false" as second argument)
  144.             // 3) the callbacks are implemented by the TextConsole class above
  145.             //engine = new Rengine( null, false, new TextConsole() )
  146.             engine = new Rengine( Array[String]( "--vanilla" ), false, new RConsole( out ) )
  147.  
  148.             System.out.println( "Rengine created, waiting for R" )
  149.             // the engine that creates R is a new thread, so we should wait until it's ready
  150.             if ( !engine.waitForR() ) {
  151.                 System.out.println( "Cannot load R" )
  152.                 false
  153.             } else {
  154.                 true
  155.             }
  156.         }
  157.     }
  158.  
  159.     /**
  160.      * Open a Java Graphics Device in R
  161.      */
  162.     def openJavaGD {
  163.         engine.eval( "Sys.setenv('JAVAGD_CLASS_NAME'='rinterface/RWindow')" )
  164.         engine.eval( "library(JavaGD)" )
  165.         engine.eval( "JavaGD(width=1000, height=600, ps=12)" )
  166.     }
  167.  
  168.     override def finalize {
  169.         // Seems not to be called ??
  170.         if ( engine != null ) {
  171.             if ( engine.isAlive ) {
  172.                 // Non-blocking eval   
  173.                 engine.idleEval( "q(\"no\")" )
  174.             }
  175.             engine.end();
  176.         }
  177.     }
  178. }
  179.  
  180.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement