/* * Copyright (c) 2013 Patrick Meyer * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.itemanalysis.jmetrik.stats.irt.equating; import com.itemanalysis.jmetrik.dao.DatabaseAccessObject; import com.itemanalysis.jmetrik.dao.DatabaseType; import com.itemanalysis.jmetrik.dao.DerbyDatabaseAccessObject; import com.itemanalysis.jmetrik.dao.JmetrikDatabaseFactory; import com.itemanalysis.jmetrik.gui.ItemParameterTableDialog; import com.itemanalysis.jmetrik.model.SortedListModel; import com.itemanalysis.jmetrik.sql.DataTableName; import com.itemanalysis.jmetrik.sql.DatabaseName; import com.itemanalysis.jmetrik.stats.irt.linking.IrtLinkingThetaDialog; import com.itemanalysis.jmetrik.workspace.JmetrikPreferencesManager; import com.itemanalysis.psychometrics.data.VariableAttributes; import org.apache.log4j.Logger; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.sql.Connection; import java.util.ArrayList; public class IrtEquatingDialog extends JDialog { // Variables declaration - do not modify private JPanel buttonPanel; private JButton cancelButton; private JButton formXItemButton; private JButton formXPersonButton; private JButton formYItemButton; private JButton formYPersonButton; private JPanel itemParamPanel; private JRadioButton logisticRadioButton; private ButtonGroup methodButtonGroup; private JPanel methodPanel; private JRadioButton normalRadioButton; private JRadioButton observedScoreRadioButton; private JButton okButton; private JPanel outputPanel; private JTextField outputTextField; private JPanel personParamPanel; private JButton resetButton; private ButtonGroup scaleButtonGroup; private JPanel scalePanel; private JLabel tableNameLabel; private JRadioButton trueScoreRadioButton; // End of variables declaration // private SelectTableDialog itemDialogX = null; // private SelectTableDialog itemDialogY = null; private ItemParameterTableDialog itemDialogX = null; private ItemParameterTableDialog itemDialogY = null; private IrtLinkingThetaDialog thetaDialogX = null; private IrtLinkingThetaDialog thetaDialogY = null; private DataTableName tableX = null; private DataTableName tableY = null; private DataTableName tableXtheta = null; private DataTableName tableYtheta = null; private static String FORMX = "Form X"; private static String FORMY = "Form Y"; private Connection conn = null; private DatabaseAccessObject dao = null; private DatabaseName dbName = null; private SortedListModel<DataTableName> tableListModel = null; private boolean canRun = false; private IrtEquatingCommand command = null; static Logger logger = Logger.getLogger("jmetrik-logger"); public IrtEquatingDialog(JFrame parent, Connection conn, DatabaseName dbName, SortedListModel<DataTableName> tableListModel){ super(parent, "IRT Score Equating", true); this.conn = conn; this.dbName = dbName; this.tableListModel = tableListModel; initComponents(); setResizable(false); setLocationRelativeTo(parent); JmetrikPreferencesManager preferencesManager = new JmetrikPreferencesManager(); String dbType = preferencesManager.getDatabaseType(); JmetrikDatabaseFactory dbFactory; if(DatabaseType.APACHE_DERBY.toString().equals(dbType)){ dao = new DerbyDatabaseAccessObject(); dbFactory = new JmetrikDatabaseFactory(DatabaseType.APACHE_DERBY); }else if(DatabaseType.MYSQL.toString().equals(dbType)){ //not yet implemented }else{ //default is apache derby dao = new DerbyDatabaseAccessObject(); dbFactory = new JmetrikDatabaseFactory(DatabaseType.APACHE_DERBY); } //prevent running an analysis when window close button is clicked this.addWindowListener(new WindowAdapter(){ @Override public void windowClosing(WindowEvent e){ canRun = false; } }); } private void initComponents() { scaleButtonGroup = new ButtonGroup(); methodButtonGroup = new ButtonGroup(); itemParamPanel = new JPanel(); formXItemButton = new JButton(); formXItemButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if(itemDialogX==null){ itemDialogX = new ItemParameterTableDialog(IrtEquatingDialog.this, conn, dao, tableListModel, "Select Form X Items"); // itemDialogX = new SelectTableDialog(IrtEquatingDialog.this, dbName, tableListModel); } itemDialogX.setVisible(true); // if(itemDialogX.canRun()){ // tableX = itemDialogX.getSelectedTable(); // } } }); formYItemButton = new JButton(); formYItemButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if(itemDialogY==null){ itemDialogY = new ItemParameterTableDialog(IrtEquatingDialog.this, conn, dao, tableListModel, "Select Form Y Items"); // itemDialogY = new SelectTableDialog(IrtEquatingDialog.this, dbName, tableListModel); } itemDialogY.setVisible(true); // if(itemDialogY.canRun()){ // tableY = itemDialogY.getSelectedTable(); // } } }); personParamPanel = new JPanel(); formXPersonButton = new JButton(); formXPersonButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if(thetaDialogX==null){ thetaDialogX = new IrtLinkingThetaDialog(IrtEquatingDialog.this, conn, dao, tableListModel, FORMX); } thetaDialogX.setVisible(true); } }); formXPersonButton.setText("Select Form X"); formXPersonButton.setEnabled(false); formYPersonButton = new JButton(); formYPersonButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if(thetaDialogY==null){ thetaDialogY = new IrtLinkingThetaDialog(IrtEquatingDialog.this, conn, dao, tableListModel, FORMX); } thetaDialogY.setVisible(true); } }); formYPersonButton.setText("Select Form Y"); formYPersonButton.setEnabled(false); scalePanel = new JPanel(); logisticRadioButton = new JRadioButton(); logisticRadioButton.setActionCommand("logistic"); normalRadioButton = new JRadioButton(); normalRadioButton.setActionCommand("normal"); methodPanel = new JPanel(); trueScoreRadioButton = new JRadioButton(); trueScoreRadioButton.setActionCommand("true"); observedScoreRadioButton = new JRadioButton(); observedScoreRadioButton.setActionCommand("observed"); outputPanel = new JPanel(); tableNameLabel = new JLabel(); outputTextField = new JTextField(); buttonPanel = new JPanel(); okButton = new JButton(); okButton.addActionListener(new OkActionListener()); cancelButton = new JButton(); resetButton = new JButton(); resetButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { reset(); } }); setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); setTitle("IRT Score Equating"); itemParamPanel.setBorder(BorderFactory.createTitledBorder("Item Parameters")); formXItemButton.setText("Select Form X"); formYItemButton.setText("Select Form Y"); GroupLayout itemParamPanelLayout = new GroupLayout(itemParamPanel); itemParamPanel.setLayout(itemParamPanelLayout); itemParamPanelLayout.setHorizontalGroup( itemParamPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(itemParamPanelLayout.createSequentialGroup() .addContainerGap() .addGroup(itemParamPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) .addComponent(formXItemButton) .addComponent(formYItemButton)) .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); itemParamPanelLayout.setVerticalGroup( itemParamPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(itemParamPanelLayout.createSequentialGroup() .addContainerGap() .addComponent(formXItemButton) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addComponent(formYItemButton) .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); personParamPanel.setBorder(BorderFactory.createTitledBorder("Person Parameters")); GroupLayout personParamPanelLayout = new GroupLayout(personParamPanel); personParamPanel.setLayout(personParamPanelLayout); personParamPanelLayout.setHorizontalGroup( personParamPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(personParamPanelLayout.createSequentialGroup() .addContainerGap() .addGroup(personParamPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) .addComponent(formXPersonButton) .addComponent(formYPersonButton)) .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); personParamPanelLayout.setVerticalGroup( personParamPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(personParamPanelLayout.createSequentialGroup() .addContainerGap() .addComponent(formXPersonButton) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addComponent(formYPersonButton) .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); scalePanel.setBorder(BorderFactory.createTitledBorder("Default Scale")); scaleButtonGroup.add(logisticRadioButton); logisticRadioButton.setSelected(true); logisticRadioButton.setText("Logistic (D = 1.0)"); scaleButtonGroup.add(normalRadioButton); normalRadioButton.setText("Normal (D = 1.7)"); normalRadioButton.setToolTipText(""); GroupLayout scalePanelLayout = new GroupLayout(scalePanel); scalePanel.setLayout(scalePanelLayout); scalePanelLayout.setHorizontalGroup( scalePanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(scalePanelLayout.createSequentialGroup() .addContainerGap() .addGroup(scalePanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) .addComponent(logisticRadioButton) .addComponent(normalRadioButton)) .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); scalePanelLayout.setVerticalGroup( scalePanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(scalePanelLayout.createSequentialGroup() .addContainerGap() .addComponent(logisticRadioButton) .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(normalRadioButton) .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); methodPanel.setBorder(BorderFactory.createTitledBorder("Equating Method")); methodButtonGroup.add(trueScoreRadioButton); trueScoreRadioButton.setSelected(true); trueScoreRadioButton.setText("True score"); methodButtonGroup.add(observedScoreRadioButton); observedScoreRadioButton.setText("Observed score"); observedScoreRadioButton.setEnabled(false); GroupLayout methodPanelLayout = new GroupLayout(methodPanel); methodPanel.setLayout(methodPanelLayout); methodPanelLayout.setHorizontalGroup( methodPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(methodPanelLayout.createSequentialGroup() .addContainerGap() .addGroup(methodPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) .addComponent(trueScoreRadioButton) .addComponent(observedScoreRadioButton)) .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); methodPanelLayout.setVerticalGroup( methodPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(methodPanelLayout.createSequentialGroup() .addContainerGap() .addComponent(trueScoreRadioButton) .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(observedScoreRadioButton) .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); outputPanel.setBorder(BorderFactory.createTitledBorder("Output Table")); tableNameLabel.setText("Table Name "); GroupLayout outputPanelLayout = new GroupLayout(outputPanel); outputPanel.setLayout(outputPanelLayout); outputPanelLayout.setHorizontalGroup( outputPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(outputPanelLayout.createSequentialGroup() .addContainerGap() .addComponent(tableNameLabel) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addComponent(outputTextField) .addContainerGap()) ); outputPanelLayout.setVerticalGroup( outputPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(outputPanelLayout.createSequentialGroup() .addContainerGap() .addGroup(outputPanelLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) .addComponent(tableNameLabel) .addComponent(outputTextField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); okButton.setText("Run"); okButton.setMaximumSize(new Dimension(72, 28)); okButton.setMinimumSize(new Dimension(72, 28)); okButton.setPreferredSize(new Dimension(72, 28)); buttonPanel.add(okButton); cancelButton.setText("Cancel"); cancelButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { canRun = false; setVisible(false); } }); cancelButton.setMaximumSize(new Dimension(72, 28)); cancelButton.setMinimumSize(new Dimension(72, 28)); cancelButton.setPreferredSize(new Dimension(72, 28)); buttonPanel.add(cancelButton); resetButton.setText("Reset"); resetButton.setMaximumSize(new Dimension(72, 28)); resetButton.setMinimumSize(new Dimension(72, 28)); resetButton.setPreferredSize(new Dimension(72, 28)); buttonPanel.add(resetButton); GroupLayout layout = new GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addComponent(buttonPanel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(GroupLayout.Alignment.TRAILING, false) .addComponent(methodPanel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(itemParamPanel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addComponent(personParamPanel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addComponent(scalePanel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addGap(0, 0, Short.MAX_VALUE)) .addComponent(outputPanel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) .addComponent(personParamPanel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(itemParamPanel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(scalePanel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) .addComponent(methodPanel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(outputPanel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addComponent(buttonPanel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); pack(); }// </editor-fold> public boolean canRun(){ return canRun; } public IrtEquatingCommand getCommand(){ return command; } public void reset(){ itemDialogX = null; itemDialogY = null; thetaDialogX = null; thetaDialogY = null; trueScoreRadioButton.setSelected(true); logisticRadioButton.setSelected(true); outputTextField.setText(""); } public class OkActionListener implements ActionListener { public void actionPerformed(ActionEvent evt){ command = new IrtEquatingCommand(); try{ boolean hasItem = false; boolean hasItemX = false; boolean hasItemY = false; boolean hasThetaX = false; boolean hasThetaY = false; boolean hasObserved = false; if(itemDialogX!=null && itemDialogX.canRun()){ tableX = itemDialogX.getSelectedTable(); command.getPairedOptionList("xitem").addValue("db", dbName.toString()); command.getPairedOptionList("xitem").addValue("table", tableX.toString()); ArrayList<VariableAttributes> varInfo = itemDialogX.getSelectedVariables(); for(VariableAttributes v: varInfo){ command.getFreeOptionList("xvar").addValue(v.getName().toString()); } hasItemX = true; }else{ JOptionPane.showMessageDialog(IrtEquatingDialog.this, "Be sure you have selected Form X items.", "Error", JOptionPane.ERROR_MESSAGE); } if(itemDialogY!=null && itemDialogY.canRun()){ tableY = itemDialogY.getSelectedTable(); command.getPairedOptionList("yitem").addValue("db", dbName.toString()); command.getPairedOptionList("yitem").addValue("table", tableY.toString()); ArrayList<VariableAttributes> varInfo = itemDialogY.getSelectedVariables(); for(VariableAttributes v: varInfo){ command.getFreeOptionList("yvar").addValue(v.getName().toString()); } hasItemY = true; }else{ JOptionPane.showMessageDialog(IrtEquatingDialog.this, "Be sure you have selected Form Y items.", "Error", JOptionPane.ERROR_MESSAGE); } hasItem = (hasItemX && hasItemY); if(thetaDialogX!=null && thetaDialogX.canRun()){ tableXtheta = thetaDialogX.getTableName(); command.getPairedOptionList("xability").addValue("db", dbName.toString()); command.getPairedOptionList("xability").addValue("table", tableXtheta.toString()); command.getPairedOptionList("xability").addValue("theta", thetaDialogX.getTheta().getName().toString()); if(thetaDialogX.hasWeight()){ command.getPairedOptionList("xability").addValue("weight", thetaDialogX.getWeight().getName().toString()); }else{ command.getPairedOptionList("xability").addValue("weight", ""); } hasThetaX = true; }else{ // JOptionPane.showMessageDialog(IrtEquatingDialog.this, // "Be sure you have selected a Form X person parameter.", // "Error", // JOptionPane.ERROR_MESSAGE); } if(thetaDialogY!=null && thetaDialogY.canRun()){ tableYtheta = thetaDialogY.getTableName(); command.getPairedOptionList("yability").addValue("db", dbName.toString()); command.getPairedOptionList("yability").addValue("table", tableYtheta.toString()); command.getPairedOptionList("yability").addValue("theta", thetaDialogY.getTheta().getName().toString()); if(thetaDialogY.hasWeight()){ command.getPairedOptionList("yability").addValue("weight", thetaDialogY.getWeight().getName().toString()); }else{ command.getPairedOptionList("yability").addValue("weight", ""); } hasThetaY = true; }else{ // JOptionPane.showMessageDialog(IrtEquatingDialog.this, // "Be sure you have selected a Form Y person parameter.", // "Error", // JOptionPane.ERROR_MESSAGE); } hasObserved = (hasThetaX && hasThetaY); command.getSelectOneOption("scale").setSelected(scaleButtonGroup.getSelection().getActionCommand()); command.getSelectOneOption("method").setSelected(methodButtonGroup.getSelection().getActionCommand()); String oTable = outputTextField.getText().trim(); if("".equals(oTable)){ //output table will not be created }else{ DataTableName dbTableName = new DataTableName(oTable); command.getPairedOptionList("output").addValue("db", dbName.toString()); command.getPairedOptionList("output").addValue("table", dbTableName.toString()); } canRun = (hasItem); if(canRun){ setVisible(false); // System.out.println(command.paste()); } }catch(IllegalArgumentException ex){ logger.fatal(ex.getMessage(), ex); JOptionPane.showMessageDialog(IrtEquatingDialog.this, ex.getMessage(), "Syntax Error", JOptionPane.ERROR_MESSAGE); } } } }