package org.geogebra.desktop.gui.view.data; import java.awt.BorderLayout; import java.awt.Component; import java.awt.FlowLayout; import java.awt.Font; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import java.util.ArrayList; import javax.swing.Box; import javax.swing.ButtonGroup; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JRadioButton; import javax.swing.JTextField; import javax.swing.table.DefaultTableModel; import org.geogebra.common.gui.view.data.OneVarModel; import org.geogebra.common.gui.view.data.StatisticsModel; import org.geogebra.common.kernel.Kernel; import org.geogebra.common.kernel.geos.GeoList; import org.geogebra.desktop.gui.inputfield.MyTextFieldD; import org.geogebra.desktop.main.AppD; import org.geogebra.desktop.main.LocalizationD; /** * Extended JPanel that contains interactive sub-panels for performing one * variable inference with the current data set. * * @author G. Sturr * */ public class OneVarInferencePanelD extends JPanel implements ActionListener, FocusListener, StatPanelInterface { private static final long serialVersionUID = 1L; // ggb fields private AppD app; private Kernel kernel; private DataAnalysisViewD statDialog; private StatTable resultTable; // GUI private JLabel lblHypParameter, lblTailType, lblNull, lblConfLevel, lblSigma, lblResultHeader; private JButton btnCalculate; private MyTextFieldD fldNullHyp, fldConfLevel, fldSigma; private JRadioButton btnLeft, btnRight, btnTwo; private JComboBox cbAltHyp; private JPanel testPanel, intPanel, mainPanel, resultPanel; private Box sigmaPanel; private int fieldWidth = 6; // test type (tail) // statistics // flags private boolean isIniting; private boolean isTest = true; private boolean isZProcedure; private LocalizationD loc; private final OneVarModel model; /*************************************** * Construct a OneVarInference panel */ public OneVarInferencePanelD(AppD app, DataAnalysisViewD statDialog) { isIniting = true; this.app = app; this.loc = app.getLocalization(); this.kernel = app.getKernel(); this.statDialog = statDialog; this.model = new OneVarModel(); this.setLayout(new BorderLayout()); this.createGUIElements(); this.updateGUI(); this.setLabels(); isIniting = false; } // ============================================================ // Create GUI // ============================================================ private void createGUIElements() { btnLeft = new JRadioButton(OneVarModel.tail_left); btnRight = new JRadioButton(OneVarModel.tail_right); btnTwo = new JRadioButton(OneVarModel.tail_two); ButtonGroup group = new ButtonGroup(); group.add(btnLeft); group.add(btnRight); group.add(btnTwo); btnLeft.addActionListener(this); btnRight.addActionListener(this); btnTwo.addActionListener(this); btnTwo.setSelected(true); cbAltHyp = new JComboBox(); cbAltHyp.addActionListener(this); lblNull = new JLabel(); lblHypParameter = new JLabel(); lblTailType = new JLabel(); fldNullHyp = new MyTextFieldD(app); fldNullHyp.setColumns(fieldWidth); fldNullHyp.setText("" + 0); fldNullHyp.addActionListener(this); fldNullHyp.addFocusListener(this); lblConfLevel = new JLabel(); fldConfLevel = new MyTextFieldD(app); fldConfLevel.setColumns(fieldWidth); fldConfLevel.addActionListener(this); fldConfLevel.addFocusListener(this); lblSigma = new JLabel(); fldSigma = new MyTextFieldD(app); fldSigma.setColumns(fieldWidth); fldSigma.addActionListener(this); fldSigma.addFocusListener(this); btnCalculate = new JButton(); lblResultHeader = new JLabel(); sigmaPanel = hBox(lblSigma, fldSigma); GridBagConstraints c = new GridBagConstraints(); c.gridx = 0; c.weightx = 1; c.insets = new Insets(4, 0, 0, 0); c.anchor = GridBagConstraints.WEST; GridBagConstraints tab = new GridBagConstraints(); tab.gridx = 0; tab.gridy = c.gridy; tab.weightx = 1; tab.insets = new Insets(4, 20, 0, 0); tab.anchor = GridBagConstraints.WEST; // test panel testPanel = new JPanel(new GridBagLayout()); c.gridy = GridBagConstraints.RELATIVE; testPanel.add(lblNull, c); testPanel.add(flowPanel(lblHypParameter, fldNullHyp), tab); testPanel.add(lblTailType, c); testPanel.add(cbAltHyp, tab); // CI panel intPanel = new JPanel(new GridBagLayout()); c.gridy = GridBagConstraints.RELATIVE; intPanel.add(lblConfLevel, c); intPanel.add(fldConfLevel, tab); // result panel resultTable = new StatTable(app); setResultTable(); resultPanel = new JPanel(new BorderLayout()); c.gridy = GridBagConstraints.RELATIVE; resultPanel.add(lblResultHeader, BorderLayout.NORTH); resultPanel.add(resultTable, BorderLayout.CENTER); c.weightx = 0; c.fill = GridBagConstraints.HORIZONTAL; // resultPanel.add(resultTable, c); // main panel mainPanel = new JPanel(new GridBagLayout()); this.add(mainPanel, BorderLayout.NORTH); // this.add(resultPanel, BorderLayout.CENTER); } private void updateMainPanel() { mainPanel.removeAll(); GridBagConstraints c = new GridBagConstraints(); c.gridx = 0; c.weightx = 1; c.insets = new Insets(4, 0, 0, 0); c.anchor = GridBagConstraints.WEST; GridBagConstraints tab = new GridBagConstraints(); tab.gridx = 0; tab.gridy = c.gridy; tab.weightx = 1; tab.insets = new Insets(4, 20, 0, 0); tab.anchor = GridBagConstraints.WEST; c.gridy = GridBagConstraints.RELATIVE; if (isZProcedure) { mainPanel.add(sigmaPanel, tab); } if (isTest) { mainPanel.add(testPanel, c); } else { mainPanel.add(intPanel, c); } c.weightx = 0; c.fill = GridBagConstraints.HORIZONTAL; mainPanel.add(resultPanel, c); } private void setResultTable() { ArrayList<String> nameList = model.getNameList(loc); String[] rowNames = new String[nameList.size()]; nameList.toArray(rowNames); resultTable.setStatTable(rowNames.length, rowNames, 1, null); } private void updateResultTable() { DefaultTableModel model1 = resultTable.getModel(); evaluate(); String cInt = statDialog.format(model.getMean()) + " \u00B1 " + statDialog.format(model.getMe()); switch (model.selectedPlot) { default: // do nothing break; case StatisticsModel.INFER_ZTEST: model1.setValueAt(statDialog.format(model.getP()), 0, 0); model1.setValueAt(statDialog.format(model.getTestStat()), 1, 0); model1.setValueAt("", 2, 0); model1.setValueAt(statDialog.format(model.getN()), 3, 0); model1.setValueAt(statDialog.format(model.getMean()), 4, 0); break; case StatisticsModel.INFER_TTEST: model1.setValueAt(statDialog.format(model.getP()), 0, 0); model1.setValueAt(statDialog.format(model.getTestStat()), 1, 0); model1.setValueAt(statDialog.format(model.getDf()), 2, 0); model1.setValueAt(statDialog.format(model.getSe()), 3, 0); model1.setValueAt("", 4, 0); model1.setValueAt(statDialog.format(model.getN()), 5, 0); model1.setValueAt(statDialog.format(model.getMean()), 6, 0); break; case StatisticsModel.INFER_ZINT: model1.setValueAt(cInt, 0, 0); model1.setValueAt(statDialog.format(model.getLower()), 1, 0); model1.setValueAt(statDialog.format(model.getUpper()), 2, 0); model1.setValueAt(statDialog.format(model.getMe()), 3, 0); model1.setValueAt("", 4, 0); model1.setValueAt(statDialog.format(model.getN()), 5, 0); model1.setValueAt(statDialog.format(model.getMean()), 6, 0); break; case StatisticsModel.INFER_TINT: model1.setValueAt(cInt, 0, 0); model1.setValueAt(statDialog.format(model.getLower()), 1, 0); model1.setValueAt(statDialog.format(model.getUpper()), 2, 0); model1.setValueAt(statDialog.format(model.getMe()), 3, 0); model1.setValueAt(statDialog.format(model.getDf()), 4, 0); model1.setValueAt(statDialog.format(model.getSe()), 5, 0); model1.setValueAt("", 6, 0); model1.setValueAt(statDialog.format(model.getN()), 7, 0); model1.setValueAt(statDialog.format(model.getMean()), 8, 0); break; } } // ============================================================ // Updates and Event Handlers // ============================================================ @Override public void updateFonts(Font font) { // not needed // ... font updates handled by recursive call in StatDialog } @Override public void setLabels() { lblHypParameter.setText(loc.getMenu("HypothesizedMean.short") + " = "); lblNull.setText(loc.getMenu("NullHypothesis") + ": "); lblTailType.setText(loc.getMenu("AlternativeHypothesis") + ": "); lblConfLevel.setText(loc.getMenu("ConfidenceLevel") + ": "); lblResultHeader.setText(loc.getMenu("Result") + ": "); lblSigma.setText(loc.getMenu("StandardDeviation.short") + " = "); btnCalculate.setText(loc.getMenu("Calculate")); repaint(); } /** Helper method for updateGUI() */ private void updateNumberField(JTextField fld, double n) { fld.removeActionListener(this); fld.setText(statDialog.format(n)); // fld.setCaretPosition(0); fld.addActionListener(this); } private void updateGUI() { isTest = (model.selectedPlot == StatisticsModel.INFER_ZTEST || model.selectedPlot == StatisticsModel.INFER_TTEST); isZProcedure = model.selectedPlot == StatisticsModel.INFER_ZTEST || model.selectedPlot == StatisticsModel.INFER_ZINT; updateNumberField(fldNullHyp, model.hypMean); updateNumberField(fldConfLevel, model.confLevel); updateNumberField(fldSigma, model.sigma); updateCBAlternativeHyp(); setResultTable(); updateResultTable(); updateMainPanel(); } @SuppressWarnings("unchecked") private void updateCBAlternativeHyp() { cbAltHyp.removeActionListener(this); cbAltHyp.removeAllItems(); cbAltHyp.addItem(loc.getMenu("HypothesizedMean.short") + " " + OneVarModel.tail_right + " " + statDialog.format(model.hypMean)); cbAltHyp.addItem(loc.getMenu("HypothesizedMean.short") + " " + OneVarModel.tail_left + " " + statDialog.format(model.hypMean)); cbAltHyp.addItem(loc.getMenu("HypothesizedMean.short") + " " + OneVarModel.tail_two + " " + statDialog.format(model.hypMean)); if (model.tail == OneVarModel.tail_right) { cbAltHyp.setSelectedIndex(0); } else if (model.tail == OneVarModel.tail_left) { cbAltHyp.setSelectedIndex(1); } else { cbAltHyp.setSelectedIndex(2); } cbAltHyp.addActionListener(this); } @Override public void actionPerformed(ActionEvent e) { if (isIniting) { return; } Object source = e.getSource(); if (source instanceof JTextField) { doTextFieldActionPerformed((JTextField) source); } else if (source == cbAltHyp) { if (cbAltHyp.getSelectedIndex() == 0) { model.tail = OneVarModel.tail_right; } else if (cbAltHyp.getSelectedIndex() == 1) { model.tail = OneVarModel.tail_left; } else { model.tail = OneVarModel.tail_two; } evaluate(); updateResultTable(); } } private void doTextFieldActionPerformed(JTextField source) { if (isIniting) { return; } double value = model.evaluateExpression(kernel, source.getText().trim()); if (source == fldConfLevel) { model.confLevel = value; evaluate(); updateGUI(); } else if (source == fldNullHyp) { model.hypMean = value; evaluate(); updateGUI(); } else if (source == fldSigma) { model.sigma = value; evaluate(); updateGUI(); } } @Override public void focusGained(FocusEvent e) { // nothing to do } @Override public void focusLost(FocusEvent e) { doTextFieldActionPerformed((JTextField) (e.getSource())); } public void setSelectedPlot(int selectedPlot) { model.selectedPlot = selectedPlot; updateGUI(); } @Override public void updatePanel() { // evaluate(); updateGUI(); // updateResultTable(); } // ============================================================ // Computation // ============================================================ private void evaluate() { GeoList dataList = statDialog.getController().getDataSelected(); double[] sample = statDialog.getController().getValueArray(dataList); model.evaluate(sample); } // ============================================================ // GUI Utilities // ============================================================ private static JPanel flowPanel(Component... comp) { JPanel p = new JPanel(new FlowLayout(FlowLayout.LEFT)); for (int i = 0; i < comp.length; i++) { p.add(comp[i]); } // p.setBackground(Color.white); return p; } private static Box hBox(Component... comp) { Box b = Box.createHorizontalBox(); for (int i = 0; i < comp.length; i++) { b.add(comp[i]); } return b; } }