Java tutorial
/* * Copyright (c) 2011 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.gui; import com.itemanalysis.jmetrik.dao.DatabaseAccessObject; import com.itemanalysis.jmetrik.graph.barchart.BarChartProcess; import com.itemanalysis.jmetrik.graph.histogram.HistogramProcess; import com.itemanalysis.jmetrik.graph.irt.IrtPlotDialog; import com.itemanalysis.jmetrik.graph.itemmap.ItemMapProcess; import com.itemanalysis.jmetrik.graph.linechart.LineChartProcess; import com.itemanalysis.jmetrik.graph.nicc.NonparametricCurveProcess; import com.itemanalysis.jmetrik.graph.piechart.PieChartProcess; import com.itemanalysis.jmetrik.graph.scatterplot.ScatterplotProcess; import com.itemanalysis.jmetrik.model.SortedListModel; import com.itemanalysis.jmetrik.model.VariableModel; import com.itemanalysis.jmetrik.scoring.BasicScoringProcess; import com.itemanalysis.jmetrik.scoring.ScoringProcess; import com.itemanalysis.jmetrik.sql.DatabaseName; import com.itemanalysis.jmetrik.stats.cmh.CmhProcess; import com.itemanalysis.jmetrik.stats.correlation.CorrelationProcess; import com.itemanalysis.jmetrik.graph.density.DensityProcess; import com.itemanalysis.jmetrik.stats.descriptives.DescriptiveProcess; import com.itemanalysis.jmetrik.stats.frequency.FrequencyProcess; import com.itemanalysis.jmetrik.stats.irt.equating.IrtEquatingProcess; import com.itemanalysis.jmetrik.stats.irt.estimation.IrtItemCalibrationProcess; import com.itemanalysis.jmetrik.stats.irt.estimation.IrtPersonScoringProcess; import com.itemanalysis.jmetrik.stats.irt.linking.IrtLinkingProcess; import com.itemanalysis.jmetrik.stats.irt.rasch.RaschAnalysisProcess; import com.itemanalysis.jmetrik.stats.itemanalysis.ItemAnalysisProcess; import com.itemanalysis.jmetrik.stats.ranking.RankingProcess; import com.itemanalysis.jmetrik.stats.scaling.TestScalingProcess; import com.itemanalysis.jmetrik.stats.transformation.LinearTransformationProcess; import com.itemanalysis.jmetrik.swing.*; import com.itemanalysis.jmetrik.sql.DataTableName; import com.itemanalysis.jmetrik.statusbar.StatusBar; import com.itemanalysis.jmetrik.utils.JmetrikFileUtils; import com.itemanalysis.jmetrik.utils.PrintUtilities; import com.itemanalysis.jmetrik.workspace.*; import com.itemanalysis.psychometrics.data.VariableAttributes; import com.itemanalysis.psychometrics.data.VariableName; import org.apache.commons.math3.util.Precision; import org.apache.log4j.Logger; import sun.print.DialogOwner; import javax.print.attribute.HashPrintRequestAttributeSet; import javax.print.attribute.PrintRequestAttributeSet; import javax.swing.*; import javax.swing.border.EmptyBorder; import javax.swing.event.HyperlinkEvent; import javax.swing.event.HyperlinkListener; import javax.swing.filechooser.FileSystemView; import javax.swing.table.JTableHeader; import javax.swing.text.DefaultEditorKit; import java.awt.*; import java.awt.event.*; import java.awt.print.PrinterException; import java.awt.print.PrinterJob; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.net.*; import java.sql.SQLException; import java.util.ArrayList; import java.util.TreeMap; public class Jmetrik extends JFrame { final static String APP_NAME = "jMetrik"; final static String VERSION = "4.0.0"; final static boolean BETA_VERSION = true; final static String RELEASE_DATE = "April 14, 2014"; final static String COPYRIGHT_YEAR = "2009 - 2015"; final static String AUTHOR = "J. Patrick Meyer"; private DataTable dataTable = null; private DataTable variableTable = null; private StatusBar statusBar = null; private Color[] rowColors = null; private Workspace workspace = null; private JList workspaceList = null; private JTabbedPane tabbedPane = null; private JmetrikFileUtils fileUtils = null; private String importExportPath = "."; private PrintRequestAttributeSet attributes = null; public final static String JMETRIK_TEXT_FILE = "com.itemanalysis.jmetrik.swing.JmetrikTextFile"; static Logger logger = Logger.getLogger("jmetrik-logger"); private JButton refreshButton = null; //Dialog components private IrtPlotDialog irtPlotDialog = null; private TreeMap<String, JDialog> dialogs = new TreeMap<String, JDialog>(); public Jmetrik() { super("jMetrik"); setPreferredSize(new Dimension(1024, 650)); setDefaultCloseOperation(EXIT_ON_CLOSE); //properly close database if user closes window this.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent we) { if (workspace != null) { workspace.closeDatabase(); } System.exit(0); } }); //add statusbar statusBar = new StatusBar(1024, 30); statusBar.setBorder(new EmptyBorder(2, 2, 2, 2)); getContentPane().add(statusBar, BorderLayout.SOUTH); //start logging startLog(); //left-right splitpane JSplitPane splitPane1 = new JSplitPane(); splitPane1.setDividerLocation(200); //setup workspace list workspaceList = new JList(); workspaceList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); workspaceList.setModel(new SortedListModel<DataTableName>()); workspaceList.addKeyListener(new DeleteKeyListener()); // workspaceList.getInsets().set(5, 5, 5, 5); //add icon to list cell renderer String urlString = "/images/spreadsheet.png"; URL url = this.getClass().getResource(urlString); final ImageIcon tableIcon = new ImageIcon(url, "Table"); workspaceList.setCellRenderer(new DefaultListCellRenderer() { @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); label.setIcon(tableIcon); return label; } }); JScrollPane scrollPane1 = new JScrollPane(workspaceList); scrollPane1.setPreferredSize(new Dimension(200, 698)); splitPane1.setLeftComponent(scrollPane1); //tabbed pane for top pane tabbedPane = new JTabbedPane(); tabbedPane.setTabPlacement(JTabbedPane.BOTTOM); //setup data table dataTable = new DataTable(); dataTable.setRowHeight(18); //change size of table header and center text JTableHeader header = dataTable.getTableHeader(); header.setDefaultRenderer(new TableHeaderCellRenderer()); JScrollPane dataScrollPane = new JScrollPane(dataTable); tabbedPane.addTab("Data", dataScrollPane); //setup variable table variableTable = new DataTable(); variableTable.setRowHeight(18); variableTable.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { super.mouseClicked(e); if (e.getClickCount() == 2) { JTable target = (JTable) e.getSource(); int row = target.getSelectedRow(); int col = target.getSelectedColumn(); if (col == 0) { if (target.getModel() instanceof VariableModel) { VariableModel vModel = (VariableModel) target.getModel(); String s = (String) vModel.getValueAt(row, col); DatabaseName db = workspace.getDatabaseName(); DataTableName table = workspace.getCurrentDataTable(); RenameVariableDialog renameVariableDialog = new RenameVariableDialog(Jmetrik.this, db, table, s); renameVariableDialog.setVisible(true); if (renameVariableDialog.canRun()) { RenameVariableCommand command = renameVariableDialog.getCommand(); workspace.runProcess(command); } } //end instanceof } //end if col==0 } //end if click count==2 }//end mouse clicked }); //change size of table header and center text JTableHeader variableHeader = variableTable.getTableHeader(); variableHeader.setDefaultRenderer(new TableHeaderCellRenderer()); variableHeader.setPreferredSize(new Dimension(30, 21)); JScrollPane variableScrollPane = new JScrollPane(variableTable); tabbedPane.addTab("Variables", variableScrollPane); splitPane1.setRightComponent(tabbedPane); getContentPane().add(splitPane1, BorderLayout.CENTER); //add status bar listener - needed to display status message that are generated within this class this.addPropertyChangeListener(statusBar.getStatusListener()); //add listener for displaying error messages - needed to display errors and exceptions this.addPropertyChangeListener(new ErrorOccurredPropertyChangeListener()); //instantiate file utilities fileUtils = new JmetrikFileUtils(); fileUtils.addPropertyChangeListener(statusBar.getStatusListener()); //set import and export path to user's documents folder JFileChooser chooser = new JFileChooser(); FileSystemView fw = chooser.getFileSystemView(); importExportPath = fw.getDefaultDirectory().toString().replaceAll("\\\\", "/"); //create and start a workspace startWorkspace(); //create menu bar and tool bar this.setJMenuBar(createMenuBar()); JToolBar toolBar = createToolBar(); toolBar.setFloatable(false); toolBar.setRollover(true); getContentPane().add(toolBar, BorderLayout.PAGE_START); pack(); } /** * Start logging. The log properties file must exist in a fixed location. * This location is teh same as that used for storing the application properties. * See also JmetrikPropertiesManager.java */ private void startLog() { JmetrikPreferencesManager prefs = new JmetrikPreferencesManager(); prefs.addPropertyChangeListener(statusBar.getStatusListener()); prefs.loadLog(); } private void closeWorkspace() { if (workspace != null) workspace.closeDatabase(); workspace = null; } private void startWorkspace() { if (workspace != null) workspace.closeDatabase(); workspace = new Workspace(workspaceList, tabbedPane, dataTable, variableTable); workspace.addPropertyChangeListener(new TableNameListener()); workspace.addPropertyChangeListener(statusBar.getStatusListener()); workspace.addPropertyChangeListener(new ErrorOccurredPropertyChangeListener()); // workspace.setRefreshButton(refreshButton); } private void openWorkspace(String dbName) { if (workspace != null) { workspace.closeDatabase(); } try { workspace.openDatabase(dbName); resetDialogs(); } catch (SQLException ex) { logger.fatal(ex.getMessage(), ex); this.firePropertyChange("error", "", "Error - Check log for details."); } } private JMenuBar createMenuBar() { final JMenuBar menuBar = new JMenuBar(); JMenuItem mItem = null; String urlString; URL url; //============================================================================================ // File Menu //============================================================================================ JMenu fileMenu = new JMenu("File"); fileMenu.setMnemonic('f'); menuBar.add(fileMenu); urlString = "/org/tango-project/tango-icon-theme/16x16/actions/document-new.png"; url = this.getClass().getResource(urlString); ImageIcon iconNew = new ImageIcon(url, "New"); mItem = new JMenuItem(new NewTextFileAction("New", iconNew)); fileMenu.add(mItem); urlString = "/org/tango-project/tango-icon-theme/16x16/actions/document-open.png"; url = this.getClass().getResource(urlString); ImageIcon iconOpen = new ImageIcon(url, "Open"); mItem = new JMenuItem(new OpenFileAction("Open...", iconOpen, new Integer(KeyEvent.VK_A))); fileMenu.add(mItem); urlString = "/org/tango-project/tango-icon-theme/16x16/actions/document-save.png"; url = this.getClass().getResource(urlString); ImageIcon iconSave = new ImageIcon(url, "Save"); mItem = new JMenuItem(new SaveAction("Save", iconSave, new Integer(KeyEvent.VK_S))); fileMenu.add(mItem); urlString = "/org/tango-project/tango-icon-theme/16x16/actions/document-save-as.png"; url = this.getClass().getResource(urlString); ImageIcon iconSaveAs = new ImageIcon(url, "Save As"); mItem = new JMenuItem(new SaveAsAction("Save As...", iconSaveAs)); fileMenu.add(mItem); urlString = "/org/tango-project/tango-icon-theme/16x16/status/folder-visiting.png"; url = this.getClass().getResource(urlString); ImageIcon iconClose = new ImageIcon(url, "Close All Tabs"); mItem = new JMenuItem(new CloseAllTabsAction("Close All Tabs...", iconClose, new Integer(KeyEvent.VK_C))); fileMenu.add(mItem); fileMenu.addSeparator(); urlString = "/org/tango-project/tango-icon-theme/16x16/actions/document-print.png"; url = this.getClass().getResource(urlString); ImageIcon iconPrint = new ImageIcon(url, "Print"); mItem = new JMenuItem(new PrintAction("Print...", iconPrint)); fileMenu.add(mItem); fileMenu.addSeparator(); // exit menu item urlString = "/org/tango-project/tango-icon-theme/16x16/actions/system-log-out.png"; url = this.getClass().getResource(urlString); ImageIcon iconExit = new ImageIcon(url, "Exit"); mItem = new JMenuItem(new ExitAction("Exit", iconExit)); fileMenu.add(mItem); //============================================================================================ // Edit Menu //============================================================================================ JMenu editMenu = new JMenu("Edit"); editMenu.setMnemonic(KeyEvent.VK_E); urlString = "/org/tango-project/tango-icon-theme/16x16/actions/edit-cut.png"; url = this.getClass().getResource(urlString); ImageIcon iconCut = new ImageIcon(url, "Cut"); mItem = new JMenuItem(new DefaultEditorKit.CutAction()); mItem.setText("Cut"); mItem.setIcon(iconCut); mItem.setMnemonic(KeyEvent.VK_X); editMenu.add(mItem); urlString = "/org/tango-project/tango-icon-theme/16x16/actions/edit-copy.png"; url = this.getClass().getResource(urlString); ImageIcon iconCopy = new ImageIcon(url, "Copy"); mItem = new JMenuItem(new DefaultEditorKit.CopyAction()); mItem.setText("Copy"); mItem.setIcon(iconCopy); mItem.setMnemonic(KeyEvent.VK_C); editMenu.add(mItem); urlString = "/org/tango-project/tango-icon-theme/16x16/actions/edit-paste.png"; url = this.getClass().getResource(urlString); ImageIcon iconPaste = new ImageIcon(url, "Paste"); mItem = new JMenuItem(new DefaultEditorKit.PasteAction()); mItem.setText("Paste"); mItem.setIcon(iconPaste); mItem.setMnemonic(KeyEvent.VK_V); editMenu.add(mItem); editMenu.addSeparator(); urlString = "/org/tango-project/tango-icon-theme/16x16/actions/edit-undo.png"; url = this.getClass().getResource(urlString); ImageIcon iconUndo = new ImageIcon(url, "Undo"); mItem = new JMenuItem(new UndoAction("Undo", iconUndo, new Integer(KeyEvent.VK_Z))); editMenu.add(mItem); urlString = "/org/tango-project/tango-icon-theme/16x16/actions/edit-redo.png"; url = this.getClass().getResource(urlString); ImageIcon iconRedo = new ImageIcon(url, "Redo"); mItem = new JMenuItem(new RedoAction("Redo", iconRedo, new Integer(KeyEvent.VK_Y))); editMenu.add(mItem); editMenu.addSeparator(); urlString = "/org/tango-project/tango-icon-theme/16x16/categories/preferences-system.png"; url = this.getClass().getResource(urlString); ImageIcon iconView = new ImageIcon(url, "Preferences"); mItem = new JMenuItem("Preferences"); mItem.setIcon(iconView); mItem.setToolTipText("Edit jMetrik preferences"); mItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { JmetrikPreferencesManager prefs = new JmetrikPreferencesManager(); prefs.addPropertyChangeListener(new ErrorOccurredPropertyChangeListener()); prefs.addPropertyChangeListener(statusBar.getStatusListener()); JmetrikPreferencesDialog propDialog = new JmetrikPreferencesDialog(Jmetrik.this, prefs); // propDialog.loadPreferences(); propDialog.setVisible(true); } }); editMenu.setMnemonic('e'); editMenu.add(mItem); menuBar.add(editMenu); //============================================================================================ // Log Menu //============================================================================================ JMenu logMenu = new JMenu("Log"); urlString = "/org/tango-project/tango-icon-theme/16x16/actions/document-properties.png"; url = this.getClass().getResource(urlString); ImageIcon iconLog = new ImageIcon(url, "View Log"); mItem = new JMenuItem(new ViewLogAction("View Log", iconLog)); logMenu.setMnemonic('l'); logMenu.add(mItem); urlString = "/org/tango-project/tango-icon-theme/16x16/mimetypes/text-x-generic.png"; url = this.getClass().getResource(urlString); ImageIcon iconCommand = new ImageIcon(url, "Script Log"); mItem = new JMenuItem(new ViewScriptLogAction("Script Log", iconCommand)); logMenu.setMnemonic('c'); logMenu.add(mItem); menuBar.add(logMenu); //============================================================================================ // Manage Menu //============================================================================================ JMenu manageMenu = new JMenu("Manage"); manageMenu.setMnemonic('m'); mItem = new JMenuItem("New Database...");//create db mItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { NewDatabaseDialog newDatabaseDialog = new NewDatabaseDialog(Jmetrik.this); newDatabaseDialog.setVisible(true); if (newDatabaseDialog.canRun()) { if (workspace == null) { // workspace = new Workspace(workspaceTree, tabbedPane, dataTable, variableTable); workspace = new Workspace(workspaceList, tabbedPane, dataTable, variableTable); workspace.addPropertyChangeListener(statusBar.getStatusListener()); workspace.addPropertyChangeListener(new ErrorOccurredPropertyChangeListener()); } workspace.runProcess(newDatabaseDialog.getCommand()); // workspace.createDatabase(newDatabaseDialog.getCommand()); } } }); manageMenu.add(mItem); mItem = new JMenuItem("Open Database..."); mItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { OpenDatabaseDialog openDbDialog = new OpenDatabaseDialog(Jmetrik.this, "Open"); JList l = openDbDialog.getDatabaseList(); workspace.setDatabaseListModel(l); openDbDialog.setVisible(true); if (openDbDialog.canRun()) { openWorkspace(openDbDialog.getDatabaseName()); } } }); manageMenu.add(mItem); urlString = "/org/tango-project/tango-icon-theme/16x16/actions/edit-delete.png"; url = this.getClass().getResource(urlString); ImageIcon iconDelete = new ImageIcon(url, "Delete"); mItem = new JMenuItem("Delete Database..."); mItem.setIcon(iconDelete); mItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { OpenDatabaseDialog selectDialog = new OpenDatabaseDialog(Jmetrik.this, "Delete"); JList l = selectDialog.getDatabaseList(); workspace.setDatabaseListModel(l); selectDialog.setVisible(true); if (selectDialog.canRun()) { int answer = JOptionPane.showConfirmDialog(Jmetrik.this, "Do you want to delete " + selectDialog.getDatabaseName() + " and all of its contents? \n" + "All data will be permanently deleted. You cannot undo this action.", "Delete Database", JOptionPane.WARNING_MESSAGE, JOptionPane.YES_NO_OPTION); if (answer == JOptionPane.YES_OPTION) { DatabaseCommand command = new DatabaseCommand(); DatabaseName dbName = new DatabaseName(selectDialog.getDatabaseName()); command.getFreeOption("name").add(dbName.getName()); command.getSelectOneOption("action").setSelected("delete-db"); DatabaseName currentDb = workspace.getDatabaseName(); if (currentDb.getName().equals(dbName.getName())) { JOptionPane.showMessageDialog(Jmetrik.this, "You cannot delete the current database.\n" + "Close the database before attempting to delete it.", "Database Delete Error", JOptionPane.WARNING_MESSAGE); } else { workspace.runProcess(command); } } } } }); manageMenu.add(mItem); manageMenu.addSeparator(); urlString = "/org/tango-project/tango-icon-theme/16x16/apps/accessories-text-editor.png"; url = this.getClass().getResource(urlString); ImageIcon iconDesc = new ImageIcon(url, "Descriptions"); mItem = new JMenuItem("Table Descriptions..."); mItem.setIcon(iconDesc); mItem.addActionListener(new TableDescriptionActionListener()); manageMenu.add(mItem); urlString = "/org/tango-project/tango-icon-theme/16x16/actions/list-add.png"; url = this.getClass().getResource(urlString); ImageIcon iconImport = new ImageIcon(url, "Import"); mItem = new JMenuItem("Import Data..."); mItem.setIcon(iconImport); mItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (workspace.databaseOpened()) { ImportDialog importDialog = new ImportDialog(Jmetrik.this, workspace.getDatabaseName(), importExportPath); importDialog.setVisible(true); if (importDialog.canRun()) { importExportPath = importDialog.getCurrentDirectory(); workspace.runProcess(importDialog.getCommand()); } } else { JOptionPane.showMessageDialog(Jmetrik.this, "You must open a database before importing data.", "No Open Database", JOptionPane.ERROR_MESSAGE); } } }); manageMenu.add(mItem); urlString = "/org/tango-project/tango-icon-theme/16x16/actions/format-indent-less.png"; url = this.getClass().getResource(urlString); ImageIcon iconExport = new ImageIcon(url, "Export"); mItem = new JMenuItem("Export Data..."); mItem.setIcon(iconExport); mItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { DataTableName tableName = (DataTableName) workspaceList.getSelectedValue(); if (!workspace.databaseOpened()) { JOptionPane.showMessageDialog(Jmetrik.this, "You must open a database before exporting data.", "No Open Database", JOptionPane.ERROR_MESSAGE); } else if (tableName == null) { JOptionPane.showMessageDialog(Jmetrik.this, "You must select a table in the workspace list. \n " + "Select a table to continue the export.", "No Table Selected", JOptionPane.ERROR_MESSAGE); } else { ExportDataDialog exportDialog = new ExportDataDialog(Jmetrik.this, workspace.getDatabaseName(), tableName, importExportPath); if (exportDialog.canRun()) { importExportPath = exportDialog.getCurrentDirectory(); workspace.runProcess(exportDialog.getCommand()); } } } }); manageMenu.add(mItem); urlString = "/org/tango-project/tango-icon-theme/16x16/actions/edit-delete.png"; url = this.getClass().getResource(urlString); ImageIcon iconDeleteTable = new ImageIcon(url, "Delete"); mItem = new JMenuItem("Delete Table..."); mItem.setIcon(iconDeleteTable); mItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (workspace.databaseOpened()) { DeleteTableDialog deleteDialog = new DeleteTableDialog(Jmetrik.this, workspace.getDatabaseName(), (SortedListModel<DataTableName>) workspaceList.getModel()); deleteDialog.setVisible(true); if (deleteDialog.canRun()) { int nSelected = deleteDialog.getNumberOfSelectedTables(); int answer = JOptionPane.NO_OPTION; if (nSelected > 1) { answer = JOptionPane.showConfirmDialog(Jmetrik.this, "Do you want to delete these " + nSelected + " tables? \n" + "All data will be permanently deleted. You cannot undo this action.", "Delete Database", JOptionPane.WARNING_MESSAGE, JOptionPane.YES_NO_OPTION); } else { ArrayList<DataTableName> dList = deleteDialog.getSelectedTables(); answer = JOptionPane.showConfirmDialog(Jmetrik.this, "Do you want to delete the table " + dList.get(0).getTableName() + "? \n" + "All data will be permanently deleted. You cannot undo this action.", "Delete Database", JOptionPane.WARNING_MESSAGE, JOptionPane.YES_NO_OPTION); } if (answer == JOptionPane.YES_OPTION) { workspace.runProcess(deleteDialog.getCommand()); } } } else { JOptionPane.showMessageDialog(Jmetrik.this, "You must open a database before deleting a table.", "No Open Database", JOptionPane.ERROR_MESSAGE); } } }); manageMenu.add(mItem); manageMenu.addSeparator(); SubsetCasesProcess subsetCasesProcess = new SubsetCasesProcess(); subsetCasesProcess.addMenuItem(Jmetrik.this, manageMenu, dialogs, workspace, workspaceList); SubsetVariablesProcess subsetVariablesProcess = new SubsetVariablesProcess(); subsetVariablesProcess.addMenuItem(Jmetrik.this, manageMenu, dialogs, workspace, workspaceList); urlString = "/org/tango-project/tango-icon-theme/16x16/actions/edit-delete.png"; url = this.getClass().getResource(urlString); ImageIcon iconDeleteVariables = new ImageIcon(url, "Delete Variables"); mItem = new JMenuItem("Delete Variables..."); mItem.setIcon(iconDeleteVariables); mItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { DataTableName tableName = (DataTableName) workspaceList.getSelectedValue(); if (!workspace.databaseOpened()) { JOptionPane.showMessageDialog(Jmetrik.this, "You must open a database before subsetting data.", "No Open Database", JOptionPane.ERROR_MESSAGE); } else if (tableName == null) { JOptionPane.showMessageDialog(Jmetrik.this, "You must select a table in the workspace list. \n " + "Select a table to continue.", "No Table Selected", JOptionPane.ERROR_MESSAGE); } else if (workspace.tableOpen()) { DeleteVariableDialog deleteVariableDialog = new DeleteVariableDialog(Jmetrik.this, workspace.getDatabaseName(), workspace.getCurrentDataTable(), workspace.getVariables()); deleteVariableDialog.setVisible(true); if (deleteVariableDialog.canRun()) { int nSelected = deleteVariableDialog.getNumberOfSelectedVariables(); int answer = JOptionPane.NO_OPTION; if (nSelected > 1) { answer = JOptionPane.showConfirmDialog(Jmetrik.this, "Do you want to delete these " + nSelected + " variables? \n" + "All data will be permanently deleted. You cannot undo this action.", "Delete Variables", JOptionPane.WARNING_MESSAGE, JOptionPane.YES_NO_OPTION); } else { VariableAttributes v = deleteVariableDialog.getSelectedVariable(); answer = JOptionPane.showConfirmDialog(Jmetrik.this, "Do you want to delete the variable " + v.getName().toString() + "? \n" + "All data will be permanently deleted. You cannot undo this action.", "Delete Database", JOptionPane.WARNING_MESSAGE, JOptionPane.YES_NO_OPTION); } if (answer == JOptionPane.YES_OPTION) { workspace.runProcess(deleteVariableDialog.getCommand()); } } } } }); manageMenu.add(mItem); menuBar.add(manageMenu); //============================================================================================ // Transform Menu //============================================================================================ JMenu transformMenu = new JMenu("Transform"); transformMenu.setMnemonic('t'); BasicScoringProcess basicScoringProcess = new BasicScoringProcess(); basicScoringProcess.addMenuItem(Jmetrik.this, transformMenu, dialogs, workspace, workspaceList); ScoringProcess scoringProcess = new ScoringProcess(); scoringProcess.addMenuItem(Jmetrik.this, transformMenu, dialogs, workspace, workspaceList); transformMenu.addSeparator(); RankingProcess rankingProcess = new RankingProcess(); rankingProcess.addMenuItem(Jmetrik.this, transformMenu, dialogs, workspace, workspaceList); TestScalingProcess testScalingProcess = new TestScalingProcess(); testScalingProcess.addMenuItem(Jmetrik.this, transformMenu, dialogs, workspace, workspaceList); LinearTransformationProcess linearTransformationProcess = new LinearTransformationProcess(); linearTransformationProcess.addMenuItem(Jmetrik.this, transformMenu, dialogs, workspace, workspaceList); transformMenu.addSeparator(); IrtLinkingProcess irtLinkingProcess = new IrtLinkingProcess(); irtLinkingProcess.addMenuItem(Jmetrik.this, transformMenu, dialogs, workspace, workspaceList); IrtEquatingProcess irtEquatingProcess = new IrtEquatingProcess(); irtEquatingProcess.addMenuItem(Jmetrik.this, transformMenu, dialogs, workspace, workspaceList); menuBar.add(transformMenu); //============================================================================================ // Analyze Menu //============================================================================================ JMenu analyzeMenu = new JMenu("Analyze"); analyzeMenu.setMnemonic('a'); FrequencyProcess frequencyProcess = new FrequencyProcess(); frequencyProcess.addMenuItem(Jmetrik.this, analyzeMenu, dialogs, workspace, workspaceList); DescriptiveProcess descriptiveProcess = new DescriptiveProcess(); descriptiveProcess.addMenuItem(Jmetrik.this, analyzeMenu, dialogs, workspace, workspaceList); CorrelationProcess correlationProcess = new CorrelationProcess(); correlationProcess.addMenuItem(Jmetrik.this, analyzeMenu, dialogs, workspace, workspaceList); analyzeMenu.addSeparator(); ItemAnalysisProcess itemAnalysisProcess = new ItemAnalysisProcess(); itemAnalysisProcess.addMenuItem(Jmetrik.this, analyzeMenu, dialogs, workspace, workspaceList); CmhProcess cmhProcess = new CmhProcess(); cmhProcess.addMenuItem(Jmetrik.this, analyzeMenu, dialogs, workspace, workspaceList); analyzeMenu.addSeparator(); RaschAnalysisProcess raschAnalysisProcess = new RaschAnalysisProcess(); raschAnalysisProcess.addMenuItem(Jmetrik.this, analyzeMenu, dialogs, workspace, workspaceList); IrtItemCalibrationProcess irtItemCalibrationProcess = new IrtItemCalibrationProcess(); irtItemCalibrationProcess.addMenuItem(Jmetrik.this, analyzeMenu, dialogs, workspace, workspaceList); IrtPersonScoringProcess irtPersonScoringProcess = new IrtPersonScoringProcess(); irtPersonScoringProcess.addMenuItem(Jmetrik.this, analyzeMenu, dialogs, workspace, workspaceList); menuBar.add(analyzeMenu); //============================================================================================ // Graph Menu //============================================================================================ JMenu graphMenu = new JMenu("Graph"); graphMenu.setMnemonic('g'); BarChartProcess barchartProcess = new BarChartProcess(); barchartProcess.addMenuItem(Jmetrik.this, graphMenu, dialogs, workspace, workspaceList); PieChartProcess piechartProcess = new PieChartProcess(); piechartProcess.addMenuItem(Jmetrik.this, graphMenu, dialogs, workspace, workspaceList); graphMenu.addSeparator(); HistogramProcess histogramProcess = new HistogramProcess(); histogramProcess.addMenuItem(Jmetrik.this, graphMenu, dialogs, workspace, workspaceList); DensityProcess densityProcess = new DensityProcess(); densityProcess.addMenuItem(Jmetrik.this, graphMenu, dialogs, workspace, workspaceList); LineChartProcess lineChartProcess = new LineChartProcess(); lineChartProcess.addMenuItem(Jmetrik.this, graphMenu, dialogs, workspace, workspaceList); ScatterplotProcess scatterplotProcess = new ScatterplotProcess(); scatterplotProcess.addMenuItem(Jmetrik.this, graphMenu, dialogs, workspace, workspaceList); graphMenu.addSeparator(); NonparametricCurveProcess nonparametricCurveProcess = new NonparametricCurveProcess(); nonparametricCurveProcess.addMenuItem(Jmetrik.this, graphMenu, dialogs, workspace, workspaceList); mItem = new JMenuItem("Irt Plot..."); mItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { DataTableName tableName = (DataTableName) workspaceList.getSelectedValue(); if (tableName == null) { JOptionPane.showMessageDialog(Jmetrik.this, "You must open a database and select a table. \n " + "Select a table to continue scoring.", "No Table Selected", JOptionPane.ERROR_MESSAGE); } else { if (irtPlotDialog == null && workspace.tableOpen()) { //Note that starting this dialog is different because variables //names must be obtained from the rows of a table. DatabaseAccessObject dao = workspace.getDatabaseFactory().getDatabaseAccessObject(); try { ArrayList<VariableAttributes> tempVar = dao.getVariableAttributesFromColumn( workspace.getConnection(), workspace.getCurrentDataTable(), new VariableName("name")); irtPlotDialog = new IrtPlotDialog(Jmetrik.this, workspace.getDatabaseName(), tableName, tempVar, (SortedListModel<DataTableName>) workspaceList.getModel()); } catch (SQLException ex) { logger.fatal(ex.getMessage(), ex); firePropertyChange("error", "", "Error - Check log for details."); } } if (irtPlotDialog != null) irtPlotDialog.setVisible(true); } if (irtPlotDialog != null && irtPlotDialog.canRun()) { workspace.runProcess(irtPlotDialog.getCommand()); } } }); graphMenu.add(mItem); ItemMapProcess itemMapProcess = new ItemMapProcess(); itemMapProcess.addMenuItem(Jmetrik.this, graphMenu, dialogs, workspace, workspaceList); menuBar.add(graphMenu); //============================================================================================ // Command Menu //============================================================================================ JMenu commandMenu = new JMenu("Commands"); commandMenu.setMnemonic('c'); mItem = new JMenuItem("Run command"); mItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { JScrollPane pain = (JScrollPane) tabbedPane.getSelectedComponent(); JViewport vp = pain.getViewport(); Component c = vp.getComponent(0); if (c instanceof JmetrikTextFile) { JmetrikTab tempTab = (JmetrikTab) tabbedPane.getTabComponentAt(tabbedPane.getSelectedIndex()); JmetrikTextFile textFile = (JmetrikTextFile) c; workspace.runFromSyntax(textFile.getText()); } } }); commandMenu.add(mItem); mItem = new JMenuItem("Stop command"); mItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { //add something } }); mItem.setEnabled(false); commandMenu.add(mItem); mItem = new JMenuItem("Command Reference..."); mItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { //add something } }); mItem.setEnabled(false); commandMenu.add(mItem); menuBar.add(commandMenu); //============================================================================================ // Help Menu //============================================================================================ JMenu helpMenu = new JMenu("Help"); helpMenu.setMnemonic('h'); mItem = new JMenuItem("Quick Start Guide"); mItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { Desktop deskTop = Desktop.getDesktop(); try { URI uri = new URI("http://www.itemanalysis.com/quick-start-guide.php"); deskTop.browse(uri); } catch (URISyntaxException ex) { logger.fatal(ex.getMessage(), ex); firePropertyChange("error", "", "Error - Check log for details."); } catch (IOException ex) { logger.fatal(ex.getMessage(), ex); firePropertyChange("error", "", "Error - Check log for details."); } } }); helpMenu.add(mItem); urlString = "/org/tango-project/tango-icon-theme/16x16/apps/help-browser.png"; url = this.getClass().getResource(urlString); ImageIcon iconAbout = new ImageIcon(url, "About"); mItem = new JMenuItem("About"); mItem.setIcon(iconAbout); mItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { JmetrikAboutDialog aboutDialog = new JmetrikAboutDialog(Jmetrik.this, APP_NAME, VERSION, AUTHOR, RELEASE_DATE, COPYRIGHT_YEAR, BETA_VERSION); aboutDialog.setVisible(true); } }); helpMenu.add(mItem); menuBar.add(helpMenu); return menuBar; } private JToolBar createToolBar() { String urlString; URL url; final JToolBar tools = new JToolBar("jMetrik Tool Bar"); JButton button; urlString = "/org/tango-project/tango-icon-theme/16x16/actions/document-new.png"; url = this.getClass().getResource(urlString); ImageIcon iconNew = new ImageIcon(url, "New"); button = new JButton(new NewTextFileAction("", iconNew)); tools.add(button); urlString = "/org/tango-project/tango-icon-theme/16x16/actions/document-open.png"; url = this.getClass().getResource(urlString); ImageIcon iconOpen = new ImageIcon(url, "Open"); button = new JButton(new OpenFileAction("", iconOpen)); tools.add(button); urlString = "/org/tango-project/tango-icon-theme/16x16/actions/document-save.png"; url = this.getClass().getResource(urlString); ImageIcon iconSave = new ImageIcon(url, "Save As"); button = new JButton(new SaveAction("", iconSave)); tools.add(button); urlString = "/org/tango-project/tango-icon-theme/16x16/actions/document-save-as.png"; url = this.getClass().getResource(urlString); ImageIcon iconSaveAs = new ImageIcon(url, "Save As"); button = new JButton(new SaveAsAction("", iconSaveAs)); tools.add(button); tools.addSeparator(); urlString = "/org/tango-project/tango-icon-theme/16x16/actions/document-print.png"; url = this.getClass().getResource(urlString); ImageIcon iconPrint = new ImageIcon(url, "Print"); button = new JButton(new PrintAction("", iconPrint)); tools.add(button); tools.addSeparator(); // urlString = "/org/tango-project/tango-icon-theme/16x16/actions/edit-cut.png"; // url = this.getClass().getResource( urlString ); // ImageIcon iconCut = new ImageIcon(url, "Cut"); // button = new JButton(new DefaultEditorKit.CutAction()); // button.setText(""); // button.setIcon(iconCut); // tools.addArgument(button); // // urlString = "/org/tango-project/tango-icon-theme/16x16/actions/edit-copy.png"; // url = this.getClass().getResource( urlString ); // ImageIcon iconCopy = new ImageIcon(url, "Copy"); // button = new JButton(new DefaultEditorKit.CopyAction()); // button.setText(""); // button.setIcon(iconCopy); // tools.addArgument(button); // // urlString = "/org/tango-project/tango-icon-theme/16x16/actions/edit-paste.png"; // url = this.getClass().getResource( urlString ); // ImageIcon iconPaste = new ImageIcon(url, "Paste"); // button = new JButton(new DefaultEditorKit.PasteAction()); // button.setIcon(iconPaste); // button.setText(""); // tools.addArgument(button); // // tools.addSeparator(); urlString = "/org/tango-project/tango-icon-theme/16x16/actions/edit-undo.png"; url = this.getClass().getResource(urlString); ImageIcon iconUndo = new ImageIcon(url, "Undo"); button = new JButton(new UndoAction("", iconUndo)); tools.add(button); urlString = "/org/tango-project/tango-icon-theme/16x16/actions/edit-redo.png"; url = this.getClass().getResource(urlString); ImageIcon iconRedo = new ImageIcon(url, "Redo"); button = new JButton(new RedoAction("", iconRedo)); tools.add(button); tools.addSeparator(); urlString = "/org/tango-project/tango-icon-theme/16x16/apps/accessories-text-editor.png"; url = this.getClass().getResource(urlString); ImageIcon iconDesc = new ImageIcon(url, "Descriptions"); button = new JButton("", iconDesc); button.setToolTipText("View table descriptions"); button.addActionListener(new TableDescriptionActionListener()); tools.add(button); tools.addSeparator(); urlString = "/org/tango-project/tango-icon-theme/16x16/actions/media-playback-start.png"; url = this.getClass().getResource(urlString); ImageIcon iconStart = new ImageIcon(url, "Run Analysis from Syntax"); button = new JButton(iconStart); button.setToolTipText("Run commands"); button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { JScrollPane pain = (JScrollPane) tabbedPane.getSelectedComponent(); JViewport vp = pain.getViewport(); Component c = vp.getComponent(0); if (c instanceof JmetrikTextFile) { JmetrikTab tempTab = (JmetrikTab) tabbedPane.getTabComponentAt(tabbedPane.getSelectedIndex()); JmetrikTextFile textFile = (JmetrikTextFile) c; workspace.runFromSyntax(textFile.getText()); } } }); tools.add(button); urlString = "/org/tango-project/tango-icon-theme/16x16/actions/media-playback-stop.png"; url = this.getClass().getResource(urlString); ImageIcon iconStopThreads = new ImageIcon(url, "Stop Analysis"); // button = new JButton(new StopAllThreadsAction("",iconStopThreads)); button = new JButton(iconStopThreads); tools.add(button); tools.addSeparator(); urlString = "/org/tango-project/tango-icon-theme/16x16/apps/utilities-system-monitor.png"; url = this.getClass().getResource(urlString); ImageIcon iconStartMemoryMonitor = new ImageIcon(url, "Start Memory Monitor"); button = new JButton(iconStartMemoryMonitor); button.setToolTipText("View memory allocation"); button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { double m = (double) Runtime.getRuntime().maxMemory(); double f = (double) Runtime.getRuntime().freeMemory(); double t = (double) Runtime.getRuntime().totalMemory(); f = f / 1048576.0; t = t / 1048576.0; m = m / 1048576.0; double amem = Precision.round(f / t * 100.0, 2); JOptionPane.showMessageDialog(Jmetrik.this, "Total memory available: " + Precision.round(m, 2) + " MB\n" + "Current allocation: " + Precision.round(t, 2) + " MB\n" + "Current amount free: " + Precision.round(f, 2) + " MB (" + amem + "%)", "JVM Memory Available", JOptionPane.INFORMATION_MESSAGE); } }); tools.add(button); urlString = "/org/tango-project/tango-icon-theme/16x16/status/folder-visiting.png"; url = this.getClass().getResource(urlString); ImageIcon iconCloseAllTabs = new ImageIcon(url, "Close All"); button = new JButton(new CloseAllTabsAction("", iconCloseAllTabs)); tools.add(button); urlString = "/org/tango-project/tango-icon-theme/16x16/actions/view-refresh.png"; url = this.getClass().getResource(urlString); ImageIcon iconRefreshData = new ImageIcon(url, "Refresh Data View"); refreshButton = new JButton("", iconRefreshData); refreshButton.setEnabled(false); tools.add(refreshButton); refreshButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { workspace.reloadTable(workspace.getCurrentDataTable()); refreshButton.setEnabled(false); refreshButton.setText(""); } }); workspace.setRefreshButton(refreshButton); return tools; } public void addTab(String title, Component p) { final Component P = p; tabbedPane.addTab(null, p); JmetrikTab jTab = new JmetrikTab(title); jTab.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { int closeTabNumber = tabbedPane.indexOfComponent(P); JScrollPane sp = (JScrollPane) tabbedPane.getComponentAt(closeTabNumber); JViewport vp = sp.getViewport(); if (vp.getComponent(0).getClass().getName().equals(JMETRIK_TEXT_FILE)) { int result = ((JmetrikTextFile) vp.getComponent(0)).promptToSave(Jmetrik.this); if (result == JOptionPane.YES_OPTION || result == JOptionPane.NO_OPTION) { tabbedPane.removeTabAt(closeTabNumber); } } } }); tabbedPane.setTabComponentAt(tabbedPane.getTabCount() - 1, jTab); tabbedPane.setSelectedIndex(tabbedPane.getTabCount() - 1); } public static void main(String args[]) { SwingUtilities.invokeLater(new Runnable() { public void run() { try { Color SELECTED_COLOR = new Color(184, 204, 217); Color BASE_COLOR = new Color(220, 231, 243, 50); Color ALT_COLOR = new Color(220, 231, 243, 115); // Insets MENU_INSETS = new Insets(1,12,2,5);//default values // Font MENU_FONT = new Font("SansSerif ", Font.PLAIN, 12);//default values // UIManager.put("nimbusBase", BASE_COLOR); UIManager.put("nimbusSelection", SELECTED_COLOR); UIManager.put("nimbusSelectionBackground", SELECTED_COLOR); UIManager.put("Menu[Enabled+Selected].backgroundPainter", SELECTED_COLOR); //override defaults for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) { if (info.getName().equals("Nimbus")) { UIManager.setLookAndFeel(info.getClassName()); UIDefaults defaults = UIManager.getLookAndFeelDefaults(); defaults.put("Table.gridColor", Color.lightGray); defaults.put("Table.disabled", false); defaults.put("Table.showGrid", true); defaults.put("Table.intercellSpacing", new Dimension(1, 1)); break; } } // UIManager.put("TitledBorder.position", TitledBorder.TOP); // UIManager.put("Table.showGrid", true); // UIManager.put("Table.gridColor", Color.RED); // UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel"); } catch (UnsupportedLookAndFeelException ulafe) { // logger.fatal("Substance failed to set", ulafe); } catch (Exception ex) { // logger.fatal(ex.getMessage(), ex); } JFrame frame = new Jmetrik(); // set window to maximum size but account for taskbar GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment(); Rectangle rect = env.getMaximumWindowBounds(); int width = Double.valueOf(rect.getWidth() - 1.0).intValue(); int height = Double.valueOf(rect.getHeight() - 1.0).intValue(); frame.setMaximizedBounds(new Rectangle(0, 0, width, height)); frame.setDefaultCloseOperation(DISPOSE_ON_CLOSE); frame.pack(); // frame.setExtendedState(JFrame.MAXIMIZED_BOTH); frame.setVisible(true); //check for updates to jmetrik ((Jmetrik) frame).checkForUpdates(); } }); } /** * Saving file happen in its own thread */ private void save(JmetrikTextFile textFile, JmetrikTab tab) { File f = null; if (!textFile.hasFile()) { f = fileUtils.chooseFileToSave(Jmetrik.this, textFile.getFile()); if (f != null) { Toolkit.getDefaultToolkit().beep(); int question = JOptionPane.showConfirmDialog(Jmetrik.this, f.getName() + " already fileExists. Do you want to overwrite it?", "File Exists", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE); if (question == JOptionPane.YES_OPTION) { textFile.fileSave(f, tab); } } } else { textFile.fileSave(tab); } } private void saveAs(JmetrikTextFile textFile, JmetrikTab tab) { File f = fileUtils.chooseFileToSave(Jmetrik.this, textFile.getFile()); if (f != null) { if (f.exists()) { Toolkit.getDefaultToolkit().beep(); int question = JOptionPane.showConfirmDialog(Jmetrik.this, f.getName() + " already fileExists. Do you want to overwrite it?", "File Exists", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE); if (question == JOptionPane.YES_OPTION) { textFile.fileSave(f, tab); } } else { textFile.fileSave(f, tab); } } } private void resetDialogs() { irtPlotDialog = null; for (String s : dialogs.keySet()) { JDialog d = dialogs.get(s); d.dispose(); d = null; } dialogs.clear(); } private void checkForUpdates() { URL url = null; URLConnection urlConn = null; BufferedReader br = null; logger.info("Checking for updates..."); try { url = new URL("http://www.itemanalysis.com/version/jmetrik-version.txt"); urlConn = url.openConnection(); urlConn.setDoInput(true); urlConn.setUseCaches(false); br = new BufferedReader(new InputStreamReader(urlConn.getInputStream())); String s = ""; String[] availableVersion = null; String[] currentVersion = VERSION.split("\\."); int needUpdate = 0; while ((s = br.readLine()) != null) { availableVersion = s.trim().split("\\."); } br.close(); if (currentVersion.length < availableVersion.length) { needUpdate++; } for (int i = 0; i < currentVersion.length; i++) { if (Integer.parseInt(currentVersion[i].trim()) < Integer.parseInt(availableVersion[i].trim())) { needUpdate++; } } if (needUpdate > 0 && !BETA_VERSION) { showUpdateResults(needUpdate > 0); logger.info( "jMetrik updates available. Please go to www.ItemAnalysis.com and download the new version."); } else { logger.info("No updates available. You have the most current version of jMetrik."); } } catch (MalformedURLException ex) { logger.fatal("Could not access update information: MalformedURLException"); } catch (IOException ex) { logger.fatal("Could not access update information: IOException"); } } private void showUpdateResults(boolean updateAvailable) { String text = ""; if (updateAvailable) { text = "<html><body>jMetrik Update Available. <br>" + "Go to <a href=http://www.itemanalysis.com/jmetrik_download.php>http://www.itemanalysis.com/jmetrik-download.php</a><br>" + "and download the new version.<br>" + "</body></html>"; } else { text = "<html><body>No Update Available. <br>" + "You have the most current version of jMetrik. <br></body></html>"; } final JEditorPane p = new JEditorPane("text/html", text); p.setEditable(false); p.addHyperlinkListener(new HyperlinkListener() { public void hyperlinkUpdate(HyperlinkEvent e) { if (e.getEventType().equals(HyperlinkEvent.EventType.ACTIVATED)) { Desktop deskTop = Desktop.getDesktop(); try { URI uri = new URI("http://www.itemanalysis.com/jmetrik-download.php"); deskTop.browse(uri); } catch (URISyntaxException ex) { logger.fatal(ex.getMessage(), ex); } catch (IOException ex) { logger.fatal(ex.getMessage(), ex); } } } }); JOptionPane.showMessageDialog(Jmetrik.this, p, "jMetrik Update Status", JOptionPane.INFORMATION_MESSAGE); } //================================================================================================================= // Menu Actions //================================================================================================================= public class NewTextFileAction extends AbstractAction { private static final long serialVersionUID = 1L; final static String TOOL_TIP = "New text file"; public NewTextFileAction(String text, ImageIcon icon, Integer mnemonic) { super(text, icon); putValue(SHORT_DESCRIPTION, TOOL_TIP); putValue(MNEMONIC_KEY, mnemonic); } public NewTextFileAction(String text, ImageIcon icon) { super(text, icon); putValue(SHORT_DESCRIPTION, TOOL_TIP); } public NewTextFileAction(String text) { super(text); putValue(SHORT_DESCRIPTION, TOOL_TIP); } public void actionPerformed(ActionEvent e) { newDocument(); } public void newDocument() { String userHome = null; String name = "New File.txt"; JmetrikTextFile textFile = new JmetrikTextFile(); textFile.addPropertyChangeListener(statusBar.getStatusListener()); JScrollPane p = new JScrollPane(textFile); p.setPreferredSize(new Dimension(730, 550)); addTab(name, p); } } // end NewAction public class OpenFileAction extends AbstractAction { private static final long serialVersionUID = 1L; final static String TOOL_TIP = "Open text file"; public OpenFileAction(String text, ImageIcon icon, Integer mnemonic) { super(text, icon); putValue(SHORT_DESCRIPTION, TOOL_TIP); putValue(MNEMONIC_KEY, mnemonic); } public OpenFileAction(String text, ImageIcon icon) { super(text, icon); putValue(SHORT_DESCRIPTION, TOOL_TIP); } public OpenFileAction(String text) { super(text); putValue(SHORT_DESCRIPTION, TOOL_TIP); } public void actionPerformed(ActionEvent e) { openDocument(); } public void openDocument() { File f = fileUtils.chooseFileToOpen(Jmetrik.this); if (f != null) { JmetrikTextFile textFile = new JmetrikTextFile(); textFile.addPropertyChangeListener(statusBar.getStatusListener()); JScrollPane p = new JScrollPane(textFile); p.setPreferredSize(new Dimension(730, 550)); textFile.openFile(f); addTab(f.getName(), p); } } } // end OpenAction public class CloseAllTabsAction extends AbstractAction { private static final long serialVersionUID = 1L; final static String TOOL_TIP = "Close all tabs without saving"; public CloseAllTabsAction(String text, ImageIcon icon, Integer mnemonic) { super(text, icon); putValue(SHORT_DESCRIPTION, TOOL_TIP); putValue(MNEMONIC_KEY, mnemonic); } public CloseAllTabsAction(String text, ImageIcon icon) { super(text, icon); putValue(SHORT_DESCRIPTION, TOOL_TIP); } public CloseAllTabsAction(String text) { super(text); putValue(SHORT_DESCRIPTION, TOOL_TIP); } public void actionPerformed(ActionEvent e) { int count = tabbedPane.getTabCount(); if (count > 2) { int result = JOptionPane.showConfirmDialog(Jmetrik.this, "Close all tabs without saving?", "Close All Tabs", JOptionPane.YES_NO_OPTION); if (result == JOptionPane.YES_OPTION) { while (count > 2) { tabbedPane.removeTabAt(count - 1); count = tabbedPane.getTabCount(); } } } } } // end Action public class SaveAction extends AbstractAction { private static final long serialVersionUID = 1L; final static String TOOL_TIP = "Save text file"; public SaveAction(String text, ImageIcon icon, Integer mnemonic) { super(text, icon); putValue(SHORT_DESCRIPTION, TOOL_TIP); putValue(MNEMONIC_KEY, mnemonic); } public SaveAction(String text, ImageIcon icon) { super(text, icon); putValue(SHORT_DESCRIPTION, TOOL_TIP); } public SaveAction(String text) { super(text); putValue(SHORT_DESCRIPTION, TOOL_TIP); } public void actionPerformed(ActionEvent e) { JScrollPane pain = (JScrollPane) tabbedPane.getSelectedComponent(); JViewport vp = pain.getViewport(); Component c = vp.getComponent(0); if (c instanceof JmetrikTextFile) { JmetrikTab tempTab = (JmetrikTab) tabbedPane.getTabComponentAt(tabbedPane.getSelectedIndex()); JmetrikTextFile textFile = (JmetrikTextFile) c; save(textFile, tempTab); } } }//end save action public class SaveAsAction extends AbstractAction { private static final long serialVersionUID = 1L; final static String TOOL_TIP = "Save As text file"; public SaveAsAction(String text, ImageIcon icon, Integer mnemonic) { super(text, icon); putValue(SHORT_DESCRIPTION, TOOL_TIP); putValue(MNEMONIC_KEY, mnemonic); } public SaveAsAction(String text, ImageIcon icon) { super(text, icon); putValue(SHORT_DESCRIPTION, TOOL_TIP); } public SaveAsAction(String text) { super(text); putValue(SHORT_DESCRIPTION, TOOL_TIP); } public void actionPerformed(ActionEvent e) { JScrollPane pain = (JScrollPane) tabbedPane.getSelectedComponent(); JViewport vp = pain.getViewport(); Component c = vp.getComponent(0); if (c instanceof JmetrikTextFile) { JmetrikTab tempTab = (JmetrikTab) tabbedPane.getTabComponentAt(tabbedPane.getSelectedIndex()); JmetrikTextFile textFile = (JmetrikTextFile) c; saveAs(textFile, tempTab); } } }//end SaveAsAction public class PrintAction extends AbstractAction { private static final long serialVersionUID = 1L; final static String TOOL_TIP = "Print text file"; public PrintAction(String text, ImageIcon icon, Integer mnemonic) { super(text, icon); putValue(SHORT_DESCRIPTION, TOOL_TIP); putValue(MNEMONIC_KEY, mnemonic); } public PrintAction(String text, ImageIcon icon) { super(text, icon); putValue(SHORT_DESCRIPTION, TOOL_TIP); } public PrintAction(String text) { super(text); putValue(SHORT_DESCRIPTION, TOOL_TIP); } public void actionPerformed(ActionEvent e) { if (!tabbedPane.getSelectedComponent().getClass().getName().equals("javax.swing.JPanel")) { JScrollPane pain = (JScrollPane) tabbedPane.getSelectedComponent(); JViewport vp = pain.getViewport(); Component c = vp.getComponent(0); if (c instanceof JmetrikTextFile) { JmetrikTextFile textFile = (JmetrikTextFile) c; PrintUtilities printer = new PrintUtilities(textFile); try { PrinterJob job = PrinterJob.getPrinterJob(); job.setPrintable(printer); if (attributes == null) { attributes = new HashPrintRequestAttributeSet(); // attributes.addArgument(DialogTypeSelection.NATIVE); attributes.add(new DialogOwner(Jmetrik.this)); } boolean ok = job.printDialog(attributes); if (ok) job.print(attributes); } catch (PrinterException ex) { logger.fatal(ex.getMessage(), ex); this.firePropertyChange("error", "", "Error - Check log for details."); } } } } }//end PrintAction public class ExitAction extends AbstractAction { private static final long serialVersionUID = 1L; final static String TOOL_TIP = "Exit"; public ExitAction(String text, ImageIcon icon, Integer mnemonic) { super(text, icon); putValue(SHORT_DESCRIPTION, TOOL_TIP); putValue(MNEMONIC_KEY, mnemonic); } public ExitAction(String text, ImageIcon icon) { super(text, icon); putValue(SHORT_DESCRIPTION, TOOL_TIP); } public ExitAction(String text) { super(text); putValue(SHORT_DESCRIPTION, TOOL_TIP); } public void actionPerformed(ActionEvent e) { if (workspace != null) workspace.closeDatabase(); System.exit(0); } }//end ExitAction public class ViewLogAction extends AbstractAction { private static final long serialVersionUID = 1L; final static String TOOL_TIP = "View Log"; public ViewLogAction(String text, ImageIcon icon, Integer mnemonic) { super(text, icon); putValue(SHORT_DESCRIPTION, TOOL_TIP); putValue(MNEMONIC_KEY, mnemonic); } public ViewLogAction(String text, ImageIcon icon) { super(text, icon); putValue(SHORT_DESCRIPTION, TOOL_TIP); } public ViewLogAction(String text) { super(text); putValue(SHORT_DESCRIPTION, TOOL_TIP); } public void actionPerformed(ActionEvent e) { this.firePropertyChange("status", null, "Opening file..."); JmetrikPreferencesManager prefs = new JmetrikPreferencesManager(); String logHome = prefs.getLogHome(); File f = new File(logHome + "/" + JmetrikPreferencesManager.DEFAULT_LOG_NAME); JmetrikTextFile textFile = new JmetrikTextFile(); JScrollPane p = new JScrollPane(textFile); p.setPreferredSize(new Dimension(730, 550)); addTab(f.getName(), p); FileOpener fileOpener = new FileOpener(f, textFile); fileOpener.addPropertyChangeListener(statusBar.getStatusListener()); fileOpener.addPropertyChangeListener(new ErrorOccurredPropertyChangeListener()); fileOpener.execute();//open in independent thread } }//end View LogAction public class ViewScriptLogAction extends AbstractAction { private static final long serialVersionUID = 1L; final static String TOOL_TIP = "View Script Log"; public ViewScriptLogAction(String text, ImageIcon icon, Integer mnemonic) { super(text, icon); putValue(SHORT_DESCRIPTION, TOOL_TIP); putValue(MNEMONIC_KEY, mnemonic); } public ViewScriptLogAction(String text, ImageIcon icon) { super(text, icon); putValue(SHORT_DESCRIPTION, TOOL_TIP); } public ViewScriptLogAction(String text) { super(text); putValue(SHORT_DESCRIPTION, TOOL_TIP); } public void actionPerformed(ActionEvent e) { this.firePropertyChange("status", null, "Opening Script log..."); JmetrikPreferencesManager prefs = new JmetrikPreferencesManager(); String logHome = prefs.getLogHome(); File f = new File(logHome + "/" + JmetrikPreferencesManager.DEFAULT_SCRIPT_LOG_NAME); JmetrikTextFile textFile = new JmetrikTextFile(); JScrollPane p = new JScrollPane(textFile); p.setPreferredSize(new Dimension(730, 550)); addTab(f.getName(), p); FileOpener fileOpener = new FileOpener(f, textFile); fileOpener.addPropertyChangeListener(statusBar.getStatusListener()); fileOpener.addPropertyChangeListener(new ErrorOccurredPropertyChangeListener()); fileOpener.execute();//open in independent thread } }//end View Script LogAction public class UndoAction extends AbstractAction { private static final long serialVersionUID = 1L; final static String TOOL_TIP = "Undo"; public UndoAction(String text, ImageIcon icon, Integer mnemonic) { super(text, icon); putValue(SHORT_DESCRIPTION, TOOL_TIP); putValue(MNEMONIC_KEY, mnemonic); } public UndoAction(String text, ImageIcon icon) { super(text, icon); putValue(SHORT_DESCRIPTION, TOOL_TIP); } public UndoAction(String text) { super(text); putValue(SHORT_DESCRIPTION, TOOL_TIP); } public void actionPerformed(ActionEvent e) { Component c = tabbedPane.getSelectedComponent(); if (c.getClass().getName().equals("javax.swing.JScrollPane")) { JScrollPane pain = (JScrollPane) c; JViewport vp = pain.getViewport(); Component c2 = vp.getComponent(0); if (c2 instanceof JmetrikTextFile) { JmetrikTextFile tp = (JmetrikTextFile) vp.getComponent(0); tp.undoText(); } } } }//end UndoAction public class RedoAction extends AbstractAction { private static final long serialVersionUID = 1L; final static String TOOL_TIP = "Redo"; public RedoAction(String text, ImageIcon icon, Integer mnemonic) { super(text, icon); putValue(SHORT_DESCRIPTION, TOOL_TIP); putValue(MNEMONIC_KEY, mnemonic); } public RedoAction(String text, ImageIcon icon) { super(text, icon); putValue(SHORT_DESCRIPTION, TOOL_TIP); } public RedoAction(String text) { super(text); putValue(SHORT_DESCRIPTION, TOOL_TIP); } public void actionPerformed(ActionEvent e) { // check to see if component is a TextfileArea which is in a JScrollPane Component c = tabbedPane.getSelectedComponent(); if (c.getClass().getName().equals("javax.swing.JScrollPane")) { JScrollPane pain = (JScrollPane) tabbedPane.getSelectedComponent(); JViewport vp = pain.getViewport(); Component c2 = vp.getComponent(0); if (c2 instanceof JmetrikTextFile) { JmetrikTextFile tp = (JmetrikTextFile) vp.getComponent(0); tp.redoText(); } } } }//end RedoAction class TableDescriptionActionListener implements ActionListener { public void actionPerformed(ActionEvent evt) { if (workspace.databaseOpened()) { DatabaseAccessObject dao = workspace.getDatabaseFactory().getDatabaseAccessObject(); TableDescriptionDialog descriptionDialog = new TableDescriptionDialog(Jmetrik.this, workspace.getConnection(), dao, workspace.getDatabaseName(), (SortedListModel<DataTableName>) workspaceList.getModel()); descriptionDialog.setVisible(true); } else { JOptionPane.showMessageDialog(Jmetrik.this, "You must open a database before viewing table descriptions.", "No Open Database", JOptionPane.ERROR_MESSAGE); } } } /** * Listener will reset all dialogs if table data has changed (i.e. table-updated) * or if a new table is selected in teh tree (i.e. table-selection). It * will also display the data table if teh selected table has changed. * * Dialogs are reset when table-updated is fired because variables need to * have the most up to date information such as any recently changed scoring. */ class TableNameListener implements PropertyChangeListener { public void propertyChange(PropertyChangeEvent e) { String propertyName = e.getPropertyName(); if ("table-selection".equals(propertyName)) { DataTableName newName = (DataTableName) e.getNewValue(); DataTableName oldName = (DataTableName) e.getOldValue(); if (!newName.equals(oldName)) { resetDialogs(); tabbedPane.setSelectedIndex(0);//show selected table in tabbed pane } } else if ("table-updated".equals(propertyName)) { DataTableName newName = (DataTableName) e.getNewValue(); DataTableName oldName = (DataTableName) e.getOldValue(); if (!newName.equals(oldName)) { resetDialogs(); } } } } class ErrorOccurredPropertyChangeListener implements PropertyChangeListener { public void propertyChange(PropertyChangeEvent e) { String propertyName = e.getPropertyName(); if ("error".equals(propertyName)) { JOptionPane.showMessageDialog(Jmetrik.this, "An error occurred. \n" + "View the information in the Log file for details.\n" + "Contact support@itemanalysis.com for help", e.getNewValue().toString(), JOptionPane.ERROR_MESSAGE); firePropertyChange("progress-off", null, null); //make statusbar progress not visible } } } public class DeleteKeyListener implements KeyListener { public void keyPressed(KeyEvent ke) { if (ke.getKeyCode() == KeyEvent.VK_DELETE) { DataTableName tableName = (DataTableName) workspaceList.getSelectedValue(); if (tableName != null && workspace.databaseOpened()) { int answer = JOptionPane.showConfirmDialog(Jmetrik.this, "Do you want to delete the table " + tableName.getTableName() + "? \n" + "All data will be permanently deleted. You cannot undo this action.", "Delete Table", JOptionPane.WARNING_MESSAGE, JOptionPane.YES_NO_OPTION); if (answer == JOptionPane.YES_OPTION) { DatabaseCommand dbCommand = new DatabaseCommand(); dbCommand.getFreeOption("name").add(workspace.getDatabaseName().toString()); dbCommand.getFreeOptionList("tables").addValue(tableName.toString()); dbCommand.getSelectOneOption("action").setSelected("delete-table"); workspace.runProcess(dbCommand); } } } } public void keyReleased(KeyEvent ke) { } public void keyTyped(KeyEvent ke) { } } }