Plotting from R into a Java JDialog with JavaGD

By | 23. Oktober 2015

Plotting from R into a Java GUI can be very painful. My problems can be watched in this video:

JavaGD

Here is source code that solves the problem after help from the mailing list:

stats-rosuda-devel@listserv.uni-augsburg.de

You should remove or adapt the lines of code containing information about the “package moneytrax”. This code does not solve general problems to get JavaGD run. In this case you may find help here and here.

First file: MyJavaGD2.java:


package moneytrax;

import org.rosuda.javaGD.GDInterface;

/**
 * From: http://rforge.net/org/doc/org/rosuda/javaGD/GDInterface.html
 * The default implementation handles most callbacks, 
 * but subclasses should override at least gdOpen(double, double) 
 * to create an instance of GDContainer c 
 * which will be used for all subsequent drawing. 
 */
public class MyJavaGD2 extends GDInterface {

    /**
     * Set c to the GDCanvas or similar back-end that we want R to plot to 
     */
    public void gdOpen(double w, double h) {
        c = Test_UI_RAnalyzeOutput.Plottest._gdc;
    }

}

Second file: Test_UI_RAnalyzeOutput.java:


package moneytrax;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JPanel;
import org.rosuda.JRI.Rengine;
import org.rosuda.javaGD.GDCanvas;
//import org.rosuda.javaGD.JGDBufferedPanel;


/**
 * Class to test drawing from R into a Java dialog.
 * The code was assembled of code snippets and hints by the mailing list
 * stats-rosuda-devel@listserv.uni-augsburg.de
 */
public class Test_UI_RAnalyzeOutput {
    
    /**
     * Create a Plottest JDialog and make it visible
     */
    public static void main(String[] args) {
        Plottest pf = new Plottest();
        pf.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
        pf.setVisible(true);
    }
    
    
    
    
    public static class Plottest extends JDialog implements ActionListener {
        
        private Rengine _re;

        private JButton _plotB;

        // This is the GDCanvas that R will be plotting to. It has to be public
        // static for MyJavaGD2 to be able to access it.
        // Three sample back-ends are included in the JavaGD sources: 
        // GDCanvas (AWT), JGDPanel (Swing) and JGDBufferedPanel (Swing with cached update). 
        public static GDCanvas _gdc;
        //public static JGDBufferedPanel _gdc;
        
        public Plottest() 
        {
          initR();
          initGUI();
        }
        
        /**
         * Init the GUI.
         * - Create a panel using the layout manager BorderLayout. 
         * - Then add to this panel a plot button and the GDCanvas (that R will be plotting to) 
         * - Add everthing to the JDialog.
         */
        private void initGUI() {
            JPanel panel = new JPanel(new BorderLayout());
            
            _plotB = new JButton("Plot");
            _plotB.addActionListener(this);
            panel.add(_plotB, BorderLayout.PAGE_START);
            
            _gdc = new GDCanvas(400, 400);
            //_gdc = new JGDBufferedPanel(400, 400);
            panel.add(_gdc, BorderLayout.PAGE_END);
            
            this.add(panel);
            this.setTitle("Plotdialog");

            this.pack();
        }

        /**
         * Initialize the R engine
         */
        private void initR() {
            String[] dummyArgs = new String[1];
            dummyArgs[0] = "--vanilla";
            _re = new Rengine(dummyArgs, false, null);
            System.out.println("Rengine created, waiting for R"); 
            if (!_re.waitForR()) {
                System.out.println("Cannot load R");
                return; 
            }
            
            
            // The next line of code is vital for correct functionality
            // From: http://rforge.net/org/doc/org/rosuda/javaGD/GDInterface.html 
            // "Any back-end that desires to display R graphics in Java can subclass this class are provide
            // its name to JavaGD package via JAVAGD_CLASS_NAME environment variable. 
            // The default implementation handles most callbacks, but subclasses should override at least 
            // gdOpen(double, double) to create an instance of GDContainer c which will be used for all 
            // subsequent drawing." 
            //
            // If the class is part of a package (e.g. my.package), this should be set to
            // Sys.setenv('JAVAGD_CLASS_NAME'='my/package/MyJavaGD')
            //
            // Attention: Sys.putenv is deprecated in favor of Sys.setenv
            
            _re.eval("Sys.setenv('JAVAGD_CLASS_NAME'='moneytrax/MyJavaGD2')");
            _re.eval("library(JavaGD)");
            

        }

        /**
         * If the plot button is pressed, tell R to open a new JavaGD device and
         * to make a simple plot.
         * 
         * For resizing e.g. to the original size of 400x400 use: 
         * _gdc.setSize(new Dimension(400, 400));
         * _gdc.initRefresh();
         */
        public void actionPerformed(ActionEvent e) 
        {
            if (e.getSource() == _plotB) 
            {
                _re.eval("JavaGD()");
                _re.eval("plot(c(1,5,3,8,5), type='l', col=2)");

                _gdc.initRefresh();
            }
        }

  }
      
}