There are two main toolkits for GUI development in Java, SWT and Swing. While either can be used for dialog creation, Deducer has a number of specialized Swing components specifically focused on statistical GUI creation. This page assumes a basic familiarity with Swing, and will take you through the process of building a dialog to create a scatter plot. There are many Swing tutorials available, including one written by Sun.
RDialog extends Swing's JDialog, and makes it easy to create a dialog with memory. Memory is an important aspect of a statistical analysis dialog, because it is rare that the user has specified all of the analysis options correctly the first time. Anytime a Deducer widget is added to the dialog via add
, it's state is tracked, and saved when the dialog is successfully completed. Then when the dialog is re-opened, it sets the widgets' states to their saved value. This is all done transparently. The only thing that the programmer needs to do is inform RDialog when it is successfully competed.
Important Methods:
By default RDialog uses AnchorLayout as it's layout manager. Though this can be changed. The classes are located at:
import org.rosuda.JGR.layout.AnchorConstraint; import org.rosuda.JGR.layout.AnchorLayout;
Widgets are easy to use Swing components provided by Deducer.
Class | Description |
---|---|
org.rosuda.deducer.widgets.VariableSelectorWidget | Filterable list of the variables in a data frame |
org.rosuda.deducer.widgets.VariableListWidget | A list of variables selected from a VariableSelectorWidget |
org.rosuda.deducer.widgets.SingleVariableWidget | A list of a single variable selected from a VariableSelectorWidget |
org.rosuda.deducer.widgets.ButtonGroupWidget | A group of radio buttons |
org.rosuda.deducer.widgets.CheckBoxesWidget | A group of check boxes |
|org.rosuda.deducer.widgets.ComboBoxWidget | A drop down list |
org.rosuda.deducer.widgets.SliderWidget | A slider |
org.rosuda.deducer.widgets.TextAreaWidget | An area to input text |
Auto-generated Documentation for each of these is available: Widget JavaDocs.
Widgets can be added just as any other component.
SliderWidget slider = new SliderWidget("Alpha level",new String[]{"Transparent","Opaque"}); anRDialog.add(slider, new AnchorConstraint(610, 978, 840, 460, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL));
In the above code, a new slider is added to the RDialog anRDialog
. In this case, anRDialog
uses AnchorLayout
, so the slider is added with an AnchorConstraint
. Each of the numbers represents the distance from either the left or the top of the dialog for each side of the slider (top, right, bottom and left). Because all of the constraints are AnchorConstraint.ANCHOR_REL
, the numbers represent relative positions going from 1 (left/top edge) to 1000 (right/ bottom edge). When the dialog is resized, the slider will be resized proportionally. The constraint can also be AnchorConstraint.ANCHOR_ABS
, in which case the number associated with that side is the absolute number of pixels between the component's edge, and that of the dialog.
variableSelector = new VariableSelectorWidget(); anRDialog.add(variableSelector, new AnchorConstraint(12, 428, 900, 12, AnchorConstraint.ANCHOR_ABS, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_ABS));
The above code creates a new variable selector. Because the top and left constraints are AnchorConstraint.ANCHOR_ABS
, there are 12 pixels between the left side of the dialog, and the left side of the selector. Similarly, there are 12 pixels between the top of the selector and the top of the dialog, regardless of how the dialog is resized.
Finally, the constraint can be AnchorConstraint.ANCHOR_NONE
, in which case the position of the side is determined by the preferred size of the component (set with setPreferredSize
).
We can make a scatter plot dialog easily using the above tools. We will extend RDialog
. We will also implement ActionListener
so that we can respond to the user pressing the buttons at the bottom of the dialog.
package example; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JOptionPane; import org.rosuda.JGR.layout.AnchorConstraint; import org.rosuda.deducer.Deducer; import org.rosuda.deducer.widgets.*; public class PlotRDialog extends RDialog implements ActionListener{ private VariableSelectorWidget variableSelector; private SingleVariableWidget yaxis; private SingleVariableWidget xaxis; private SliderWidget slider; public void initGUI(){ super.initGUI(); variableSelector = new VariableSelectorWidget(); this.add(variableSelector, new AnchorConstraint(12, 428, 900, 12, AnchorConstraint.ANCHOR_ABS, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_ABS)); variableSelector.setPreferredSize(new java.awt.Dimension(216, 379)); variableSelector.setTitle("Data"); yaxis = new SingleVariableWidget("y axis",variableSelector); this.add(yaxis, new AnchorConstraint(121, 978, 327, 460, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL)); yaxis.setPreferredSize(new java.awt.Dimension(276, 63)); xaxis = new SingleVariableWidget("x axis",variableSelector); this.add(xaxis, new AnchorConstraint(337, 978, 540, 460, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL)); xaxis.setPreferredSize(new java.awt.Dimension(276, 63)); slider = new SliderWidget("Alpha level",new String[]{"Transparent","Opaque"}); this.add(slider, new AnchorConstraint(610, 978, 840, 460, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL)); slider.setPreferredSize(new java.awt.Dimension(187, 44)); slider.setDefaultModel(new Integer(100)); this.setTitle("Scatter Plot"); setOkayCancel(true,true,this); //put Run, Reset, Cancel buttons in place, and register this as it's listener addHelpButton("pmwiki.php"); //Add help button pointing to main manual page this.setSize(555, 445); } public void actionPerformed(ActionEvent e) { String cmd = e.getActionCommand(); if(cmd=="Run"){ String xvar = xaxis.getSelectedVariable(); String yvar = yaxis.getSelectedVariable(); String data = variableSelector.getSelectedData(); String alpha = new Double(((double) slider.getValue())/100.0).toString(); if(yvar==null || xvar==null || data==null){ JOptionPane.showMessageDialog(this, "You must specify both an x and y variable"); return; } String command = "qplot("+xvar+", "+yvar+", data="+data+",alpha=I("+alpha+"))"; Deducer.execute(command); //execute command as if it had been entered into the console this.setVisible(false); completed(); //dialog completed }else if(cmd=="Cancel") this.setVisible(false); else if(cmd=="Reset") reset(); } }
The first method (initGUI
) overrides the the RDialog
method, and is used to set up the four widgets. The actionPerformed
method is called when the "Run", "Cancel" or "Reset" buttons are pressed. When "Run" is pressed, an call to qplot
in the ggplot2
package is constructed. It is then executed using Deducer.execute
.
The above Class is present in the DeducerPlugInExample
package, and can be viewed with:
R> library(DeducerPlugInExample) R> scatter <- new(J("example.PlotRDialog")) R> scatter$run()