/***
* Copyright (c) 2008, Endless Loop Software, Inc.
*
* This file is part of EgoNet.
*
* EgoNet 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.
*
* EgoNet 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 org.egonet.gui.interview;
import javax.swing.JCheckBoxMenuItem;
import java.awt.AWTEvent;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import javax.swing.JInternalFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JFileChooser;
import javax.swing.ProgressMonitor;
import javax.swing.event.InternalFrameEvent;
import javax.swing.event.InternalFrameListener;
import javax.swing.filechooser.FileFilter;
import org.egonet.graph.GraphData;
import org.egonet.graph.GraphRenderer;
import org.egonet.gui.EgoStore;
import org.egonet.gui.MDIChildFrame;
import org.egonet.io.EdgeListWriter;
import org.egonet.mdi.MDIContext;
import org.egonet.model.Interview;
import org.egonet.model.Study;
import org.egonet.model.question.AlterPairQuestion;
import org.egonet.model.question.Question;
import org.egonet.statistics.StatRecord;
import org.egonet.util.CatchingAction;
import org.egonet.util.EgonetAnalytics;
import org.egonet.util.ExtensionFileFilter;
import org.egonet.util.FileHelpers;
import org.egonet.util.ImageFilter;
import org.egonet.util.SwingWorker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import au.com.bytecode.opencsv.CSVWriter;
// implement MdiChildFrame and molest the public menu!
public class ClientFrame extends MDIChildFrame implements InternalFrameListener {
final private static Logger logger = LoggerFactory.getLogger(ClientFrame.class);
/**
* Used to create drop down menus of different "modes"
*/
public static final int SELECT = 0;
public static final int DO_INTERVIEW = 1;
public static final int VIEW_INTERVIEW = 2;
public static final int VIEW_SUMMARY = 3;
private final JMenuBar jMenuBar1 = new JMenuBar();
private final JMenu jMenuFile = new JMenu("File");
private final JMenu jMenuGraph = new JMenu("Graph");
private final JMenuItem graphProperties = new JMenuItem("Graph Properties");
private final JMenuItem nodeProperties = new JMenuItem("Node Properties");
private final JMenuItem edgeProperties = new JMenuItem("Edge Properties");
private final JMenuItem saveStudySummary = new JMenuItem("Save Study Summary");
private final JMenuItem exportInterview = new JMenuItem("Export interview as...");
private final JMenuItem exit = new JMenuItem("Exit");
public final JMenuItem saveAlterSummary = new JMenuItem("Save Alter Summary");
public final JMenuItem saveTextSummary = new JMenuItem("Save Text Answer Summary");
public final JMenuItem saveAdjacencyMatrix = new JMenuItem("Save Adjacency Matrix");
public final JMenuItem saveWeightedAdjacencyMatrix = new JMenuItem("Save Weighted Adjacency Matrix");
public final JMenuItem saveAlterByAlterPromptMatrix = new JMenuItem("Save Alter by Alter prompt Matrix");
public final JMenuItem saveGraphSettings = new JMenuItem("Save graph settings");
public final JMenuItem applyGraphSettings = new JMenuItem("Load/Apply graph settings");
public final JCheckBoxMenuItem detailedTooltips = new JCheckBoxMenuItem("Show extended node tooltips");
public final JMenuItem saveInterview = new JMenuItem("Save Interview");
public final JMenuItem saveGraph = new JMenuItem("Save Graph as image");
public final JMenuItem saveGraphCoordinates = new JMenuItem("Save Graph coordinates");
public final JMenuItem saveEdgeList = new JMenuItem("Save Edgelist");
public final JMenuItem recalculateStatistics = new JMenuItem("Recalculate Statistics");
public final JMenuItem close = new JMenuItem("Return to Main Menu");
public final JMenuItem saveInterviewStatistics = new JMenuItem("Save Interview Statistics");
private final EgoClient egoClient;
// Construct the frame
public ClientFrame(EgoClient egoClient) {
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
this.egoClient = egoClient;
jbInit();
}
// Component initialization
private void jbInit() {
//setSize(new Dimension(700, 600));
setTitle("Interviewing and Analysis Tool");
createMenuBar(ClientFrame.SELECT);
setContentPane(new JPanel());
pack();
setMaximizable(true);
setIconifiable(true);
setResizable(true);
setClosable(true);
exit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
jMenuFileExit_actionPerformed(e);
} catch (Exception ex) { throw new RuntimeException(ex); }
}
});
saveStudySummary.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
saveStudySummary_actionPerformed(e);
}
});
saveGraph.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
saveGraph_actionPerformed(e);
}
});
saveGraphCoordinates.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
saveGraphCoordinates_actionPerformed(e);
}
});
saveEdgeList.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
saveEdgeList_actionPerformed(e);
}
});
saveGraphSettings
.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
saveGraphSettings_actionPerformed(e);
}
});
saveInterview.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
egoClient.getInterview().completeInterview(egoClient.getStorage());
} catch (Exception ex) {
throw new RuntimeException(ex);
}
EgonetAnalytics.track("save interview"); // track!
}
});
exportInterview.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
egoClient.getStorage().exportStudy(true);
egoClient.getInterview();
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
});
applyGraphSettings
.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
applyGraphSettings_actionPerformed(e);
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
});
detailedTooltips
.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
GraphRenderer.getGraphSettings().setDetailedTooltips(detailedTooltips.isSelected());
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
});
recalculateStatistics.addActionListener(new CatchingAction("recalculateStatistics") {
public void safeActionPerformed(ActionEvent e) throws Exception {
EgoStore storage = egoClient.getStorage();
Interview interview = storage.readInterview(storage.getInterviewFile());
if (interview != null)
gotoViewInterviewPanel();
}
});
close.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
gotoSourceSelectPanel();
}
});
this.addInternalFrameListener(this);
}
public void flood() {
invalidate();
pack();
setMinimumSize(getPreferredSize());
}
// File | Exit action performed
public void jMenuFileExit_actionPerformed(ActionEvent e) {
if (egoClient.getInterview() != null) {
try {
egoClient.getStorage().writeCurrentInterview();
egoClient.getInterview().isComplete();
} catch (Exception e1) {
throw new RuntimeException(e1);
}
}
dispose();
}
// Overridden so we can exit when window is closed
protected void processWindowEvent(WindowEvent e) {
// super.processWindowEvent(e);
if (e.getID() == WindowEvent.WINDOW_CLOSING) {
try { jMenuFileExit_actionPerformed(null); } catch (Exception ex) { throw new RuntimeException(ex); }
}
}
public void createMenuBar(int mode) {
jMenuBar1.removeAll();
jMenuFile.removeAll();
jMenuGraph.removeAll();
// File Menu
if (mode == ClientFrame.VIEW_SUMMARY) {
jMenuFile.add(saveStudySummary);
jMenuFile.add(close);
jMenuFile.addSeparator();
jMenuFile.add(exit);
} else if (mode == ClientFrame.VIEW_INTERVIEW) {
/*******************************************************************
* Create Menu Bar
******************************************************************/
jMenuFile.add(saveAlterSummary);
jMenuFile.add(saveTextSummary);
jMenuFile.add(saveAdjacencyMatrix);
jMenuFile.add(saveWeightedAdjacencyMatrix);
jMenuFile.add(saveAlterByAlterPromptMatrix);
jMenuFile.addSeparator();
jMenuFile.add(saveGraphSettings);
jMenuFile.add(applyGraphSettings);
jMenuFile.add(saveGraphCoordinates);
jMenuFile.add(saveEdgeList);
jMenuFile.add(detailedTooltips);
jMenuFile.addSeparator();
jMenuFile.add(saveGraph);
jMenuFile.add(saveInterview);
jMenuFile.add(exportInterview);
jMenuFile.add(recalculateStatistics);
jMenuFile.addSeparator();
jMenuFile.add(close);
jMenuGraph.add(graphProperties);
jMenuGraph.add(nodeProperties);
jMenuGraph.add(edgeProperties);
} else {
jMenuFile.add(exit);
}
jMenuBar1.add(jMenuFile);
this.setJMenuBar(jMenuBar1);
}
void saveStudySummary_actionPerformed(ActionEvent e) {
String name =
FileHelpers.formatForCSV(egoClient.getStudy().getStudyName());
String filename = name + "_Summary";
CSVWriter w = new CSVWriter(egoClient.getStorage().newStatisticsPrintWriter(
"Study Summary", "csv", filename));
if (w != null) {
try {
((SummaryPanel) egoClient.getFrame().getContentPane())
.writeStudySummary(w);
} finally {
try {
w.close();
} catch (IOException e1) {
logger.error("Unable to close CSVWriter", e1);
}
}
}
}
void saveGraph_actionPerformed(ActionEvent e) {
String fileName;
fileName = egoClient.getStorage().getInterviewFile().getName() + "_graph";
File currentDirectory = new File(egoClient.getStorage().getStudyFile().getParent()+ "/Graphs");
currentDirectory.mkdir();
JFileChooser fileChooser = new JFileChooser();
fileChooser.setCurrentDirectory(currentDirectory);
fileChooser.setSelectedFile(new File(fileName + ".jpg"));
fileChooser.setDialogTitle("Save Graph");
fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
FileFilter imageFilter = new ImageFilter();
fileChooser.addChoosableFileFilter(imageFilter);
int returnValue = JFileChooser.APPROVE_OPTION;
while (returnValue == JFileChooser.APPROVE_OPTION) {
returnValue = fileChooser.showSaveDialog(this);
File imageFile = fileChooser.getSelectedFile();
String fmt = ImageFilter.getExtension(imageFile);
if (fmt != null && imageFilter.accept(imageFile)) {
logger.info(imageFile.getName());
GraphData.writeImage(imageFile, fmt);
break;
} else {
JOptionPane
.showMessageDialog(this,
"I don't recognize that image format. Please try again.");
}
}
}
void saveEdgeList_actionPerformed(ActionEvent e) {
String fileName;
fileName = egoClient.getStorage().getInterviewFile().getName() + "_edgelist";
File currentDirectory = new File(egoClient.getStorage().getStudyFile().getParent()+ "/Graphs");
currentDirectory.mkdir();
JFileChooser fileChooser = new JFileChooser();
fileChooser.setCurrentDirectory(currentDirectory);
fileChooser.setSelectedFile(new File(fileName + ".csv"));
fileChooser.setDialogTitle("Save Graph EdgeList");
fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
int returnValue = JFileChooser.APPROVE_OPTION;
while (returnValue == JFileChooser.APPROVE_OPTION) {
returnValue = fileChooser.showSaveDialog(this);
File dataFile = fileChooser.getSelectedFile();
try {
EdgeListWriter fw = new EdgeListWriter(dataFile);
Interview interview = egoClient.getInterview();
Study study = egoClient.getStudy();
String [] thisInterviewAlterlist = interview.getAlterList();
Iterator<Long> questions = study.getQuestionOrder(AlterPairQuestion.class).iterator();
while (questions.hasNext()) {
Question q = study.getQuestion((Long) questions.next());
int[][] adj = interview.generateAdjacencyMatrix(q, true);
// loop through adj
// if adj[i][j] == 1, thisInterviewAlters[i] && thisInterviewAlters[j] are adjacent in final matrix
fw.writeEdgelist(thisInterviewAlterlist, adj);
}
fw.close();
} catch (Exception e1) {
throw new RuntimeException(e1);
}
break;
}
}
void saveGraphCoordinates_actionPerformed(ActionEvent e) {
String fileName;
fileName = egoClient.getStorage().getInterviewFile().getName() + "_graph_coordinates";
File currentDirectory = new File(egoClient.getStorage().getStudyFile()
.getParent()
+ "/Graphs");
currentDirectory.mkdir();
JFileChooser fileChooser = new JFileChooser();
fileChooser.setCurrentDirectory(currentDirectory);
fileChooser.setSelectedFile(new File(fileName + ".csv"));
fileChooser.setDialogTitle("Save Graph Coordinates");
fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
int returnValue = JFileChooser.APPROVE_OPTION;
while (returnValue == JFileChooser.APPROVE_OPTION) {
returnValue = fileChooser.showSaveDialog(this);
File dataFile = fileChooser.getSelectedFile();
try {
GraphData.writeCoordinates(dataFile);
} catch (IOException e1) {
throw new RuntimeException(e1);
}
break;
}
}
void saveGraphSettings_actionPerformed(ActionEvent e) {
String name = egoClient.getStorage().getInterviewFile().getName();
String fileName = "/" + name.replace(".int", "") + ".xml";
final File currentDirectory = new File(egoClient.getStorage().getStudyFile().getParent(), "Graphs");
currentDirectory.mkdir();
File file = new File(currentDirectory.getAbsolutePath() + fileName);
JFileChooser fileChooser = new JFileChooser();
fileChooser.setCurrentDirectory(currentDirectory);
fileChooser.setSelectedFile(new File(fileName));
fileChooser.setDialogTitle("Save Graph Settings");
fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
fileChooser.setSelectedFile(file);
ExtensionFileFilter filter = new ExtensionFileFilter("Graph Settings","xml");
fileChooser.addChoosableFileFilter(filter);
int returnValue = fileChooser.showSaveDialog(this);
if (returnValue == JFileChooser.APPROVE_OPTION) {
File settingsFile = fileChooser.getSelectedFile();
GraphRenderer.getGraphSettings().saveSettingsFile(settingsFile);
}
}
protected void applyGraphSettings_actionPerformed(ActionEvent e) {
String name = egoClient.getStorage().getInterviewFile().getName();
String fileName = "/" + name.replace(".int", "") + ".xml";
final File currentDirectory = new File(egoClient.getStorage().getStudyFile().getParent(), "Graphs");
currentDirectory.mkdir();
File file = new File(currentDirectory.getAbsolutePath() + fileName);
JFileChooser fileChooser = new JFileChooser();
fileChooser.setCurrentDirectory(currentDirectory);
fileChooser.setSelectedFile(new File(fileName));
fileChooser.setDialogTitle("Load Graph Settings");
fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
fileChooser.setSelectedFile(file);
ExtensionFileFilter filter = new ExtensionFileFilter("Graph Settings","xml");
fileChooser.addChoosableFileFilter(filter);
int returnValue = fileChooser.showOpenDialog(this);
if (returnValue == JFileChooser.APPROVE_OPTION) {
File settingsFile = fileChooser.getSelectedFile();
try {
GraphRenderer.getGraphSettings().loadSettingsFile(settingsFile);
} catch (Throwable ex) {
logger.error("Problem loading graph settings",ex);
}
}
}
public void gotoSourceSelectPanel() {
/* Return to first screen */
setVisible(false);
ClientPanel panel = new ClientPanel(egoClient);
setContentPane(panel);
createMenuBar(ClientFrame.SELECT);
flood();
setVisible(true);
}
public void gotoViewInterviewPanel()
{
final ProgressMonitor progressMonitor = new ProgressMonitor(egoClient.getFrame(), "Calculating Statistics", "", 0, 100);
final SwingWorker worker = new SwingWorker()
{
public Object construct()
{
// Build Screen
setVisible(false);
//com.endlessloopsoftware.egonet.Shared.setWaitCursor(egoClient.getFrame(), true);
progressMonitor.setProgress(5);
setContentPane(new ViewInterviewPanel(egoClient, progressMonitor));
progressMonitor.setProgress(95);
createMenuBar(ClientFrame.VIEW_INTERVIEW);
pack();
// setSize(640, 530);
return this;
}
public void finished()
{
//com.endlessloopsoftware.egonet.Shared.setWaitCursor(egoClient.getFrame(), false);
progressMonitor.close();
setVisible(true);
}
};
progressMonitor.setProgress(0);
progressMonitor.setMillisToDecideToPopup(0);
progressMonitor.setMillisToPopup(0);
worker.start();
}
/**
* Hides the static frame egoClient.getFrame() and initializes it with an
* entirely new QuestionPanel
*/
public void gotoClientQuestionPanel() {
/* Return to first screen */
setVisible(false);
setContentPane(new ClientQuestionPanel(egoClient));
pack();
setVisible(true);
}
public void gotoSummaryPanel(StatRecord[] stats)
{
// Build Screen
setVisible(false);
//com.endlessloopsoftware.egonet.Shared.setWaitCursor(egoClient.getFrame(), true);
setContentPane(new SummaryPanel(egoClient, stats));
createMenuBar(ClientFrame.VIEW_SUMMARY);
pack();
//
//com.endlessloopsoftware.egonet.Shared.setWaitCursor(egoClient.getFrame(), false);
setVisible(true);
}
public void gotoStartPanel() throws Exception
{
/* Return to first screen */
setVisible(false);
StartPanel sp = new StartPanel(egoClient);
setContentPane(sp);
pack();
setSize(350, 350);
setVisible(true);
}
public void quickSaveSummary() {
final ProgressMonitor progressMonitor = new ProgressMonitor(egoClient.getFrame(), "Calculating Statistics", "", 0, 100);
final SwingWorker worker = new SwingWorker()
{
public Object construct()
{
setVisible(false);
SummaryPanel summaryPanel = new SummaryPanel(egoClient, progressMonitor);
return summaryPanel;
}
public void finished() {
if (! progressMonitor.isCanceled()) {
String name =
FileHelpers.formatForCSV(egoClient.getStudy().getStudyName());
String filename = name + "_Summary";
CSVWriter w = new CSVWriter(egoClient.getStorage().newStatisticsPrintWriter(
"Study Summary", "csv", filename));
if (w != null) {
try {
((SummaryPanel) this.getValue()).writeStudySummary(w);
} finally {
try {
w.close();
} catch (IOException e) {
logger.error("Unable to close CSVWriter", e);
}
}
}
}
progressMonitor.close();
setVisible(true);
}
};
progressMonitor.setProgress(0);
progressMonitor.setMillisToDecideToPopup(0);
progressMonitor.setMillisToPopup(0);
worker.start();
}
public void gotoSummaryPanel()
{
final ProgressMonitor progressMonitor = new ProgressMonitor(egoClient.getFrame(), "Calculating Statistics", "", 0, 100);
final SwingWorker worker = new SwingWorker()
{
public Object construct()
{
// Build Screen
setVisible(false);
//com.endlessloopsoftware.egonet.Shared.setWaitCursor(egoClient.getFrame(), true);
setContentPane(new SummaryPanel(egoClient, progressMonitor));
createMenuBar(ClientFrame.VIEW_SUMMARY);
pack();
return egoClient.getFrame();
}
public void finished()
{
//com.endlessloopsoftware.egonet.Shared.setWaitCursor(egoClient.getFrame(), false);
setVisible(true);
if (progressMonitor.isCanceled()) {
gotoSourceSelectPanel();
}
progressMonitor.close();
}
};
progressMonitor.setProgress(0);
progressMonitor.setMillisToDecideToPopup(0);
progressMonitor.setMillisToPopup(0);
worker.start();
}
public void focusActivated() {
logger.trace(this.getTitle() + " activated");
}
public void focusDeactivated() {
logger.trace(this.getTitle() + " deactivated");
}
public JInternalFrame getInternalFrame() {
return this;
}
public void setMdiContext(MDIContext context) {
}
public void internalFrameActivated(InternalFrameEvent e) {
}
public void internalFrameClosed(InternalFrameEvent e) {
}
public void internalFrameClosing(InternalFrameEvent e) {
jMenuFileExit_actionPerformed(null);
}
public void internalFrameDeactivated(InternalFrameEvent e) {
}
public void internalFrameDeiconified(InternalFrameEvent e) {
}
public void internalFrameIconified(InternalFrameEvent e) {
}
public void internalFrameOpened(InternalFrameEvent e) {
}
}