diff --git a/.classpath b/.classpath deleted file mode 100644 index 4cb2221..0000000 --- a/.classpath +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/.gitignore b/.gitignore index d2fcacd..f7627c0 100644 --- a/.gitignore +++ b/.gitignore @@ -161,3 +161,9 @@ pip-log.txt # Mac crap .DS_Store + +target +.cache + +.classpath +.project diff --git a/.project b/.project deleted file mode 100644 index 5e7b252..0000000 --- a/.project +++ /dev/null @@ -1,17 +0,0 @@ - - - Enet - - - - - - org.eclipse.jdt.core.javabuilder - - - - - - org.eclipse.jdt.core.javanature - - diff --git a/build-launch4j.xml b/build-launch4j.xml new file mode 100644 index 0000000..37fc30f --- /dev/null +++ b/build-launch4j.xml @@ -0,0 +1,30 @@ + + + + + + Egonet + + + + + + + + + + + + + + + + + + + + + + diff --git a/build.sbt b/build.sbt new file mode 100644 index 0000000..ab9586c --- /dev/null +++ b/build.sbt @@ -0,0 +1,61 @@ +import AssemblyKeys._ +import Keys._ +import sbtassembly.Plugin._ + +assemblySettings + +name := "egonet" + +libraryDependencies += "net.sf.jung" % "jung-api" % "2.0.1" + +libraryDependencies += "net.sf.jung" % "jung-graph-impl" % "2.0.1" + +libraryDependencies += "net.sf.jung" % "jung-algorithms" % "2.0.1" + +libraryDependencies += "net.sf.jung" % "jung-io" % "2.0.1" + +libraryDependencies += "net.sf.jung" % "jung-visualization" % "2.0.1" + +libraryDependencies += "org.swinglabs" % "swingx" % "0.9.7" + +libraryDependencies += "org.jdesktop" % "swing-worker" % "1.1" + +libraryDependencies += "org.swinglabs" % "swing-layout" % "1.0.3" + +libraryDependencies += "com.miglayout" % "miglayout" % "3.7" + +libraryDependencies += "com.jgoodies" % "forms" % "1.1.0" + +libraryDependencies += "com.jgoodies" % "looks" % "2.1.4" + +libraryDependencies += "com.google.guava" % "guava" % "r08" + +libraryDependencies += "com.jcraft" % "jsch" % "0.1.41" + +libraryDependencies += "net.sf.opencsv" % "opencsv" % "1.8" + +libraryDependencies += "com.lowagie" % "itext" % "2.1.5" + +libraryDependencies += "com.lowagie" % "itext-rtf" % "2.1.5" + +libraryDependencies += "junit" % "junit" % "4.3.1" + +libraryDependencies += "commons-codec" % "commons-codec" % "1.3" + +libraryDependencies += "org.slf4j" % "slf4j-api" % "1.5.6" + +libraryDependencies += "org.slf4j" % "slf4j-jdk14" % "1.5.6" + +mainClass in (Compile, run) := Some("org.egonet.gui.EgonetRunner") + +mainClass in assembly := Some("org.egonet.gui.EgonetRunner") + +mergeStrategy in assembly <<= (mergeStrategy in assembly) { (old) => + { +// case PathList("javax", "servlet", xs @ _*) => MergeStrategy.first +// case PathList(ps @ _*) if ps.last endsWith ".html" => MergeStrategy.first +// case "application.conf" => MergeStrategy.concat + case "RELEASE-NOTES.txt" => MergeStrategy.discard + case x => old(x) + } +} diff --git a/build.xml b/build.xml deleted file mode 100644 index 8f35ba2..0000000 --- a/build.xml +++ /dev/null @@ -1,127 +0,0 @@ - - - - - - Egonet - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/lib/fest-swing-1.0b1/lib/MRJToolkitStubs-1.0.jar b/lib/MRJToolkitStubs-1.0.jar similarity index 100% rename from lib/fest-swing-1.0b1/lib/MRJToolkitStubs-1.0.jar rename to lib/MRJToolkitStubs-1.0.jar diff --git a/lib/fest-swing-1.0b1/lib/fest-assert-1.0a1.jar b/lib/fest-assert-1.0a1.jar similarity index 100% rename from lib/fest-swing-1.0b1/lib/fest-assert-1.0a1.jar rename to lib/fest-assert-1.0a1.jar diff --git a/lib/fest-swing-1.0b1/lib/fest-reflect-0.4.jar b/lib/fest-reflect-0.4.jar similarity index 100% rename from lib/fest-swing-1.0b1/lib/fest-reflect-0.4.jar rename to lib/fest-reflect-0.4.jar diff --git a/lib/fest-swing-1.0b1/fest-swing-1.0b1.jar b/lib/fest-swing-1.0b1.jar similarity index 100% rename from lib/fest-swing-1.0b1/fest-swing-1.0b1.jar rename to lib/fest-swing-1.0b1.jar diff --git a/lib/fest-swing-1.0b1/extensions/fest-swing-junit-1.0b1/fest-swing-junit-1.0b1-sources.jar b/lib/fest-swing-1.0b1/extensions/fest-swing-junit-1.0b1/fest-swing-junit-1.0b1-sources.jar deleted file mode 100644 index 11344c5..0000000 Binary files a/lib/fest-swing-1.0b1/extensions/fest-swing-junit-1.0b1/fest-swing-junit-1.0b1-sources.jar and /dev/null differ diff --git a/lib/fest-swing-1.0b1/extensions/fest-swing-junit-1.0b1/lib/commons-codec-1.3.jar b/lib/fest-swing-1.0b1/extensions/fest-swing-junit-1.0b1/lib/commons-codec-1.3.jar deleted file mode 100644 index 957b675..0000000 Binary files a/lib/fest-swing-1.0b1/extensions/fest-swing-junit-1.0b1/lib/commons-codec-1.3.jar and /dev/null differ diff --git a/lib/fest-swing-1.0b1/extensions/fest-swing-junit-1.0b1/lib/junit-4.3.1.jar b/lib/fest-swing-1.0b1/extensions/fest-swing-junit-1.0b1/lib/junit-4.3.1.jar deleted file mode 100644 index 77b4fb0..0000000 Binary files a/lib/fest-swing-1.0b1/extensions/fest-swing-junit-1.0b1/lib/junit-4.3.1.jar and /dev/null differ diff --git a/lib/fest-swing-1.0b1/extensions/fest-swing-testng-1.0b1/fest-swing-testng-1.0b1-sources.jar b/lib/fest-swing-1.0b1/extensions/fest-swing-testng-1.0b1/fest-swing-testng-1.0b1-sources.jar deleted file mode 100644 index c3c289f..0000000 Binary files a/lib/fest-swing-1.0b1/extensions/fest-swing-testng-1.0b1/fest-swing-testng-1.0b1-sources.jar and /dev/null differ diff --git a/lib/fest-swing-1.0b1/extensions/fest-swing-testng-1.0b1/fest-swing-testng-1.0b1.jar b/lib/fest-swing-1.0b1/extensions/fest-swing-testng-1.0b1/fest-swing-testng-1.0b1.jar deleted file mode 100644 index 3d02ef3..0000000 Binary files a/lib/fest-swing-1.0b1/extensions/fest-swing-testng-1.0b1/fest-swing-testng-1.0b1.jar and /dev/null differ diff --git a/lib/fest-swing-1.0b1/extensions/fest-swing-testng-1.0b1/lib/testng-5.5-jdk15.jar b/lib/fest-swing-1.0b1/extensions/fest-swing-testng-1.0b1/lib/testng-5.5-jdk15.jar deleted file mode 100644 index 7d5651a..0000000 Binary files a/lib/fest-swing-1.0b1/extensions/fest-swing-testng-1.0b1/lib/testng-5.5-jdk15.jar and /dev/null differ diff --git a/lib/fest-swing-1.0b1/fest-swing-1.0b1-sources.jar b/lib/fest-swing-1.0b1/fest-swing-1.0b1-sources.jar deleted file mode 100644 index 3ed114b..0000000 Binary files a/lib/fest-swing-1.0b1/fest-swing-1.0b1-sources.jar and /dev/null differ diff --git a/lib/fest-swing-1.0b1/lib/fest-assert-1.0a1-sources.jar b/lib/fest-swing-1.0b1/lib/fest-assert-1.0a1-sources.jar deleted file mode 100644 index a3bf47c..0000000 Binary files a/lib/fest-swing-1.0b1/lib/fest-assert-1.0a1-sources.jar and /dev/null differ diff --git a/lib/fest-swing-1.0b1/lib/fest-reflect-0.4-sources.jar b/lib/fest-swing-1.0b1/lib/fest-reflect-0.4-sources.jar deleted file mode 100644 index e9233ea..0000000 Binary files a/lib/fest-swing-1.0b1/lib/fest-reflect-0.4-sources.jar and /dev/null differ diff --git a/lib/fest-swing-1.0b1/lib/fest-util-0.4-sources.jar b/lib/fest-swing-1.0b1/lib/fest-util-0.4-sources.jar deleted file mode 100644 index 227e2a9..0000000 Binary files a/lib/fest-swing-1.0b1/lib/fest-util-0.4-sources.jar and /dev/null differ diff --git a/lib/fest-swing-1.0b1/extensions/fest-swing-junit-1.0b1/fest-swing-junit-1.0b1.jar b/lib/fest-swing-junit-1.0b1.jar similarity index 100% rename from lib/fest-swing-1.0b1/extensions/fest-swing-junit-1.0b1/fest-swing-junit-1.0b1.jar rename to lib/fest-swing-junit-1.0b1.jar diff --git a/lib/fest-swing-1.0b1/lib/fest-util-0.4.jar b/lib/fest-util-0.4.jar similarity index 100% rename from lib/fest-swing-1.0b1/lib/fest-util-0.4.jar rename to lib/fest-util-0.4.jar diff --git a/lib/forms-1.1.0.jar b/lib/forms-1.1.0.jar deleted file mode 100644 index 50c1eb8..0000000 Binary files a/lib/forms-1.1.0.jar and /dev/null differ diff --git a/lib/guava-r08.jar b/lib/guava-r08.jar deleted file mode 100644 index d18d0bd..0000000 Binary files a/lib/guava-r08.jar and /dev/null differ diff --git a/lib/iText-2.1.5.jar b/lib/iText-2.1.5.jar deleted file mode 100644 index f28be38..0000000 Binary files a/lib/iText-2.1.5.jar and /dev/null differ diff --git a/lib/iText-rtf-2.1.5.jar b/lib/iText-rtf-2.1.5.jar deleted file mode 100644 index dd4ebfc..0000000 Binary files a/lib/iText-rtf-2.1.5.jar and /dev/null differ diff --git a/lib/jsch-0.1.40.jar b/lib/jsch-0.1.40.jar deleted file mode 100644 index 67952d8..0000000 Binary files a/lib/jsch-0.1.40.jar and /dev/null differ diff --git a/lib/jung/collections-generic-4.01.jar b/lib/jung/collections-generic-4.01.jar deleted file mode 100644 index 92d009c..0000000 Binary files a/lib/jung/collections-generic-4.01.jar and /dev/null differ diff --git a/lib/jung/colt-1.2.0.jar b/lib/jung/colt-1.2.0.jar deleted file mode 100644 index a7192f6..0000000 Binary files a/lib/jung/colt-1.2.0.jar and /dev/null differ diff --git a/lib/jung/concurrent-1.3.4.jar b/lib/jung/concurrent-1.3.4.jar deleted file mode 100644 index 551f347..0000000 Binary files a/lib/jung/concurrent-1.3.4.jar and /dev/null differ diff --git a/lib/jung/jung-algorithms-2.0-beta1.jar b/lib/jung/jung-algorithms-2.0-beta1.jar deleted file mode 100644 index 280a998..0000000 Binary files a/lib/jung/jung-algorithms-2.0-beta1.jar and /dev/null differ diff --git a/lib/jung/jung-api-2.0-beta1.jar b/lib/jung/jung-api-2.0-beta1.jar deleted file mode 100644 index 7483cfc..0000000 Binary files a/lib/jung/jung-api-2.0-beta1.jar and /dev/null differ diff --git a/lib/jung/jung-graph-impl-2.0-beta1.jar b/lib/jung/jung-graph-impl-2.0-beta1.jar deleted file mode 100644 index 5d2e60c..0000000 Binary files a/lib/jung/jung-graph-impl-2.0-beta1.jar and /dev/null differ diff --git a/lib/jung/jung-io-2.0-beta1.jar b/lib/jung/jung-io-2.0-beta1.jar deleted file mode 100644 index 2a50dc3..0000000 Binary files a/lib/jung/jung-io-2.0-beta1.jar and /dev/null differ diff --git a/lib/jung/jung-visualization-2.0-beta1.jar b/lib/jung/jung-visualization-2.0-beta1.jar deleted file mode 100644 index 8fb2713..0000000 Binary files a/lib/jung/jung-visualization-2.0-beta1.jar and /dev/null differ diff --git a/lib/junit-4.3.1.jar b/lib/junit-4.3.1.jar deleted file mode 100644 index 6806753..0000000 Binary files a/lib/junit-4.3.1.jar and /dev/null differ diff --git a/lib/looks-2.1.4.jar b/lib/looks-2.1.4.jar deleted file mode 100644 index d2c47c7..0000000 Binary files a/lib/looks-2.1.4.jar and /dev/null differ diff --git a/lib/miglayout-3.7-swing.jar b/lib/miglayout-3.7-swing.jar deleted file mode 100644 index ad26e11..0000000 Binary files a/lib/miglayout-3.7-swing.jar and /dev/null differ diff --git a/lib/opencsv-1.8.jar b/lib/opencsv-1.8.jar deleted file mode 100644 index b684861..0000000 Binary files a/lib/opencsv-1.8.jar and /dev/null differ diff --git a/lib/slf4j-api-1.5.6.jar b/lib/slf4j-api-1.5.6.jar deleted file mode 100644 index 9b42216..0000000 Binary files a/lib/slf4j-api-1.5.6.jar and /dev/null differ diff --git a/lib/slf4j-jdk14-1.5.6.jar b/lib/slf4j-jdk14-1.5.6.jar deleted file mode 100644 index d41ca3f..0000000 Binary files a/lib/slf4j-jdk14-1.5.6.jar and /dev/null differ diff --git a/lib/swing-layout-1.0.3.jar b/lib/swing-layout-1.0.3.jar deleted file mode 100644 index 5353286..0000000 Binary files a/lib/swing-layout-1.0.3.jar and /dev/null differ diff --git a/lib/swing-worker-1.1.jar b/lib/swing-worker-1.1.jar deleted file mode 100644 index 3935611..0000000 Binary files a/lib/swing-worker-1.1.jar and /dev/null differ diff --git a/lib/swingx-0.9.7.jar b/lib/swingx-0.9.7.jar deleted file mode 100644 index 69a959a..0000000 Binary files a/lib/swingx-0.9.7.jar and /dev/null differ diff --git a/project/plugins.sbt b/project/plugins.sbt new file mode 100644 index 0000000..63cafdb --- /dev/null +++ b/project/plugins.sbt @@ -0,0 +1,3 @@ +addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.4.0") + +addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.11.2") diff --git a/src/com/endlessloopsoftware/ego/author/AuthoringQuestionPanel.java b/src/main/java/com/endlessloopsoftware/ego/author/AuthoringQuestionPanel.java similarity index 100% rename from src/com/endlessloopsoftware/ego/author/AuthoringQuestionPanel.java rename to src/main/java/com/endlessloopsoftware/ego/author/AuthoringQuestionPanel.java diff --git a/src/com/endlessloopsoftware/ego/author/CategoryInputPane.java b/src/main/java/com/endlessloopsoftware/ego/author/CategoryInputPane.java similarity index 96% rename from src/com/endlessloopsoftware/ego/author/CategoryInputPane.java rename to src/main/java/com/endlessloopsoftware/ego/author/CategoryInputPane.java index f534649..1b2502c 100644 --- a/src/com/endlessloopsoftware/ego/author/CategoryInputPane.java +++ b/src/main/java/com/endlessloopsoftware/ego/author/CategoryInputPane.java @@ -1,212 +1,212 @@ -/*** - * 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 . - */ -package com.endlessloopsoftware.ego.author; - -import java.awt.Dimension; -import java.awt.GridBagConstraints; -import java.awt.GridBagLayout; -import java.awt.Insets; -import java.awt.Toolkit; -import java.awt.event.ActionEvent; -import java.io.IOException; - -import javax.swing.JButton; -import javax.swing.JDialog; -import javax.swing.JList; -import javax.swing.JPanel; -import javax.swing.JScrollPane; - -import org.egonet.model.question.AlterPairQuestion; -import org.egonet.model.question.AlterPromptQuestion; -import org.egonet.model.question.Question; -import org.egonet.util.CatchingAction; -import org.egonet.util.listbuilder.ListBuilder; -import org.egonet.util.listbuilder.Selection; - -import com.endlessloopsoftware.egonet.Shared; - -public class CategoryInputPane extends JDialog { - - private final JList parentList; - - private final GridBagLayout gridBagLayout1 = new GridBagLayout(); - - // create list builder with preset values turned on. - private final ListBuilder listBuilder = new ListBuilder(); - - private final JButton jOKButton = new JButton("OK"); - - private final JButton jCancelButton = new JButton("Cancel"); - - private JScrollPane scrollPane; - - private final EgoNet egoNet; - - /** - * Constructor for CategoryInputPane - * - * @param list - * question list from parent frame used to determine which - * question we are operating on - */ - public CategoryInputPane(EgoNet egoNet, JList list) throws Exception - { - parentList = list; - this.egoNet = egoNet; - jbInit(); - } - - /** - * Initializes layout and fields for the dialog - * - * @throws Exception - * No idea, sorry - */ - private void jbInit() throws Exception { - JPanel panel = new JPanel(); - - panel.setLayout(gridBagLayout1); - this.setModal(true); - this.setTitle("Category Options"); - this.setName(this.getTitle()); - - panel.add( - listBuilder, - new GridBagConstraints(0, 0, 4, 1, 1.0, 0.9, - GridBagConstraints.CENTER, GridBagConstraints.BOTH, - new Insets(0, 0, 0, 0), 0, 0)); - panel.add( - jCancelButton, - new GridBagConstraints(2, 1, 2, 1, 0.2, 0.0, - GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, - new Insets(10, 0, 10, 10), 0, 0)); - panel.add( - jOKButton, - new GridBagConstraints(0, 1, 2, 1, 0.2, 0.0, - GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, - new Insets(10, 20, 10, 0), 26, 0)); - - jOKButton.addActionListener(new CatchingAction("jOKButton") { - public void safeActionPerformed(ActionEvent e) throws Exception { - OKButton_actionPerformed(e); - } - }); - - jCancelButton.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(ActionEvent e) { - cancelButton_actionPerformed(e); - } - }); - - scrollPane = new JScrollPane(panel); - this.getContentPane().add(scrollPane); - } - - void OKButton_actionPerformed(ActionEvent e) throws IOException { - boolean changed = false; - boolean compatible = true; - // boolean abort = false; - - Question q = (Question) parentList.getSelectedValue(); - if (q != null) { - /* count choices */ - - Selection[] newSelections = listBuilder.getListSelections(); - - if (newSelections.length != q.getSelections().length) { - if (egoNet.getStudy().confirmIncompatibleChange(egoNet.getFrame())) { - compatible = false; - changed = true; - - // If the number changed we know the list has changed, so - // just copy over - // the reference and let the loop trim the strings - q.setSelections(newSelections); - } else { - // Don't make this change - egoNet.getFrame().fillCurrentPanel(); - this.hide(); - return; - } - } - - // Trim the strings, check for changes - for (int i = 0; i < q.getSelections().length; i++) { - if (!q.getSelections()[i] - .equals(newSelections[i].getString().trim())) { - q.getSelections()[i].setString(newSelections[i].getString() - .trim()); - changed = true; - } - // q.selections[i].value= newSelections[i].value; - } - - egoNet.getStudy().setModified(changed); - egoNet.getStudy().setCompatible(compatible); - - egoNet.getFrame().fillCurrentPanel(); - this.setVisible(false); - } - - } - - void cancelButton_actionPerformed(ActionEvent e) { - this.setVisible(false); - } - - void activate() { - Question q = (Question) parentList.getSelectedValue(); - - if (q != null) { - listBuilder.setListSelections(q.getSelections()); - } else { - System.err.println("Parent list had no selections"); - } - - listBuilder.setEditable(true); - - listBuilder.setElementName("Option: "); - listBuilder.setTitle("Category Options"); - listBuilder - .setDescription("Enter possible answers to this question below. Press Return to add the option " - + "to the options list. Press OK to set options or Cancel to undo changes."); - if(q instanceof AlterPromptQuestion) - listBuilder.setNameModel(egoNet.getStudy().getAlterNameModel()); - listBuilder.setLetUserPickValues(true); - listBuilder.setPresetListsActive(q.answerType == Shared.AnswerType.CATEGORICAL); - -// boolean preset = (q.answerType == Shared.AnswerType.CATEGORICAL) ? true : false; -// logger.info("Is question categorical? " + preset); -// - listBuilder.setAdjacencyActive(q instanceof AlterPairQuestion); - - this.setSize(500, 400); // width, height - - // Center the window - Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); - Dimension frameSize = this.getSize(); - this.setLocation((screenSize.width - frameSize.width) / 2, - (screenSize.height - frameSize.height) / 2); - - jOKButton.setVisible(true); - jCancelButton.setText("Cancel"); - - this.setVisible(true); - } +/*** + * 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 . + */ +package com.endlessloopsoftware.ego.author; + +import java.awt.Dimension; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.awt.Toolkit; +import java.awt.event.ActionEvent; +import java.io.IOException; + +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.JScrollPane; + +import org.egonet.model.question.AlterPairQuestion; +import org.egonet.model.question.AlterPromptQuestion; +import org.egonet.model.question.Question; +import org.egonet.util.CatchingAction; +import org.egonet.util.listbuilder.ListBuilder; +import org.egonet.util.listbuilder.Selection; + +import com.endlessloopsoftware.egonet.Shared; + +public class CategoryInputPane extends JDialog { + + private final JList parentList; + + private final GridBagLayout gridBagLayout1 = new GridBagLayout(); + + // create list builder with preset values turned on. + private final ListBuilder listBuilder = new ListBuilder(); + + private final JButton jOKButton = new JButton("OK"); + + private final JButton jCancelButton = new JButton("Cancel"); + + private JScrollPane scrollPane; + + private final EgoNet egoNet; + + /** + * Constructor for CategoryInputPane + * + * @param list + * question list from parent frame used to determine which + * question we are operating on + */ + public CategoryInputPane(EgoNet egoNet, JList list) throws Exception + { + parentList = list; + this.egoNet = egoNet; + jbInit(); + } + + /** + * Initializes layout and fields for the dialog + * + * @throws Exception + * No idea, sorry + */ + private void jbInit() throws Exception { + JPanel panel = new JPanel(); + + panel.setLayout(gridBagLayout1); + this.setModal(true); + this.setTitle("Category Options"); + this.setName(this.getTitle()); + + panel.add( + listBuilder, + new GridBagConstraints(0, 0, 4, 1, 1.0, 0.9, + GridBagConstraints.CENTER, GridBagConstraints.BOTH, + new Insets(0, 0, 0, 0), 0, 0)); + panel.add( + jCancelButton, + new GridBagConstraints(2, 1, 2, 1, 0.2, 0.0, + GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, + new Insets(10, 0, 10, 10), 0, 0)); + panel.add( + jOKButton, + new GridBagConstraints(0, 1, 2, 1, 0.2, 0.0, + GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, + new Insets(10, 20, 10, 0), 26, 0)); + + jOKButton.addActionListener(new CatchingAction("jOKButton") { + public void safeActionPerformed(ActionEvent e) throws Exception { + OKButton_actionPerformed(e); + } + }); + + jCancelButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(ActionEvent e) { + cancelButton_actionPerformed(e); + } + }); + + scrollPane = new JScrollPane(panel); + this.getContentPane().add(scrollPane); + } + + void OKButton_actionPerformed(ActionEvent e) throws IOException { + boolean changed = false; + boolean compatible = true; + // boolean abort = false; + + Question q = (Question) parentList.getSelectedValue(); + if (q != null) { + /* count choices */ + + Selection[] newSelections = listBuilder.getListSelections(); + + if (newSelections.length != q.getSelections().length) { + if (egoNet.getStudy().confirmIncompatibleChange(egoNet.getFrame())) { + compatible = false; + changed = true; + + // If the number changed we know the list has changed, so + // just copy over + // the reference and let the loop trim the strings + q.setSelections(newSelections); + } else { + // Don't make this change + egoNet.getFrame().fillCurrentPanel(); + this.hide(); + return; + } + } + + // Trim the strings, check for changes + for (int i = 0; i < q.getSelections().length; i++) { + if (!q.getSelections()[i] + .equals(newSelections[i].getString().trim())) { + q.getSelections()[i].setString(newSelections[i].getString() + .trim()); + changed = true; + } + // q.selections[i].value= newSelections[i].value; + } + + egoNet.getStudy().setModified(changed); + egoNet.getStudy().setCompatible(compatible); + + egoNet.getFrame().fillCurrentPanel(); + this.setVisible(false); + } + + } + + void cancelButton_actionPerformed(ActionEvent e) { + this.setVisible(false); + } + + void activate() { + Question q = (Question) parentList.getSelectedValue(); + + if (q != null) { + listBuilder.setListSelections(q.getSelections()); + } else { + System.err.println("Parent list had no selections"); + } + + listBuilder.setEditable(true); + + listBuilder.setElementName("Option: "); + listBuilder.setTitle("Category Options"); + listBuilder + .setDescription("Enter possible answers to this question below. Press Return to add the option " + + "to the options list. Press OK to set options or Cancel to undo changes."); + if(q instanceof AlterPromptQuestion) + listBuilder.setNameModel(egoNet.getStudy().getAlterNameModel()); + listBuilder.setLetUserPickValues(true); + listBuilder.setPresetListsActive(q.answerType == Shared.AnswerType.CATEGORICAL); + +// boolean preset = (q.answerType == Shared.AnswerType.CATEGORICAL) ? true : false; +// logger.info("Is question categorical? " + preset); +// + listBuilder.setAdjacencyActive(q instanceof AlterPairQuestion); + + this.setSize(500, 400); // width, height + + // Center the window + Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); + Dimension frameSize = this.getSize(); + this.setLocation((screenSize.width - frameSize.width) / 2, + (screenSize.height - frameSize.height) / 2); + + jOKButton.setVisible(true); + jCancelButton.setText("Cancel"); + + this.setVisible(true); + } } \ No newline at end of file diff --git a/src/com/endlessloopsoftware/ego/author/EgoFrame.java b/src/main/java/com/endlessloopsoftware/ego/author/EgoFrame.java similarity index 96% rename from src/com/endlessloopsoftware/ego/author/EgoFrame.java rename to src/main/java/com/endlessloopsoftware/ego/author/EgoFrame.java index 56d1d85..80849e3 100644 --- a/src/com/endlessloopsoftware/ego/author/EgoFrame.java +++ b/src/main/java/com/endlessloopsoftware/ego/author/EgoFrame.java @@ -1,572 +1,572 @@ -/*** - * 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 . - */ -package com.endlessloopsoftware.ego.author; - -import org.egonet.model.question.*; -import java.awt.AWTEvent; - -import java.awt.BorderLayout; -import java.awt.Component; -import java.awt.Cursor; -import java.awt.Toolkit; -import java.awt.event.ActionEvent; -import java.awt.event.KeyEvent; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; -import java.util.Observable; -import java.util.Observer; - -import javax.swing.*; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; -import javax.swing.event.InternalFrameEvent; -import javax.swing.event.InternalFrameListener; -import javax.swing.text.DefaultEditorKit; - -import org.egonet.exceptions.CorruptedInterviewException; -import org.egonet.gui.MDIChildFrame; -import org.egonet.mdi.MDIContext; -import org.egonet.model.question.Question; -import org.egonet.util.CatchingAction; -import org.egonet.util.EgonetAnalytics; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.endlessloopsoftware.egonet.Shared; - -import org.egonet.model.question.StudyQuestion; - -public class EgoFrame extends MDIChildFrame implements Observer, InternalFrameListener { - - final private static Logger logger = LoggerFactory.getLogger(EgoFrame.class); - - /** - * Changes based on jTabbedPane_stateChanged, which is activated when tabs are clicked - */ - Class curTab = StudyQuestion.class; - Class lastTab = StudyQuestion.class; - - private final EgoNet egoNet; - private JPanel contentPane; - - private final JMenuBar jEgonetMenuBar = new JMenuBar(); - private final JMenu jMenuFile = new JMenu("File"); - private final JMenuItem jMenuFileNew = new JMenuItem("New Study"); - private final JMenuItem jMenuFileOpen = new JMenuItem("Open Study"); - private final JMenuItem jMenuFileClose = new JMenuItem("Close Study"); - private final JMenuItem jMenuFileImport = new JMenuItem("Import Questions..."); - private final JMenuItem jMenuFileExport = new JMenuItem("Export Questions..."); - private final JMenuItem jMenuFileExportStudy = new JMenuItem("Export Study As..."); - - private final JMenuItem jMenuFileSaveAs = new JMenuItem("Save Study As..."); - private final JMenuItem jMenuFileSave = new JMenuItem("Save Study"); - - - - private final JMenuItem jMenuFileExit = new JMenuItem("Quit"); - private final JMenu jMenuEdit = new JMenu("Edit"); - private final JMenuItem jMenuEditCut = new JMenuItem(new DefaultEditorKit.CutAction()); - private final JMenuItem jMenuEditCopy = new JMenuItem(new DefaultEditorKit.CopyAction()); - private final JMenuItem jMenuEditPaste = new JMenuItem(new DefaultEditorKit.PasteAction()); - - private final JTabbedPane jTabbedPane = new JTabbedPane(); - private final BorderLayout borderLayout1 = new BorderLayout(); - - private final StudyPanel study_panel; - - private final Map,EgoQPanel> questionPanel; - - // Construct the frame - public EgoFrame(EgoNet egoNet) - { - try { - this.egoNet = egoNet; - study_panel = new StudyPanel(egoNet); - - questionPanel = new HashMap,EgoQPanel>(); - questionPanel.put(EgoQuestion.class, new AuthoringQuestionPanel(egoNet, EgoQuestion.class)); - questionPanel.put(AlterPromptQuestion.class, new PromptPanel(egoNet, AlterPromptQuestion.class)); - questionPanel.put(AlterQuestion.class, new AuthoringQuestionPanel(egoNet, AlterQuestion.class)); - questionPanel.put(AlterPairQuestion.class, new AuthoringQuestionPanel(egoNet, AlterPairQuestion.class)); - - enableEvents(AWTEvent.WINDOW_EVENT_MASK); - jbInit(); - } - catch (Exception ex) { - throw new RuntimeException(ex); - } - - } - - // Component initialization - private void jbInit() throws Exception { - // Listen for window closing - //this.addWindowListener(new CloseListener()); - this.addInternalFrameListener(this); - - //fixme - - this.setDefaultCloseOperation(DISPOSE_ON_CLOSE); - setResizable(true); - - contentPane = new JPanel(); - contentPane.setLayout(borderLayout1); - setContentPane(contentPane); - setTitle("Study Design Tool"); - - jMenuFileExit.setAccelerator(javax.swing.KeyStroke.getKeyStroke( - KeyEvent.VK_Q, Toolkit.getDefaultToolkit() - .getMenuShortcutKeyMask())); - jMenuFileNew.setAccelerator(javax.swing.KeyStroke.getKeyStroke( - KeyEvent.VK_N, Toolkit.getDefaultToolkit() - .getMenuShortcutKeyMask())); - jMenuFileOpen.setAccelerator(javax.swing.KeyStroke.getKeyStroke( - KeyEvent.VK_O, Toolkit.getDefaultToolkit() - .getMenuShortcutKeyMask())); - jMenuFileClose.setAccelerator(javax.swing.KeyStroke.getKeyStroke( - KeyEvent.VK_W, Toolkit.getDefaultToolkit() - .getMenuShortcutKeyMask())); - jMenuEditCopy.setAccelerator(javax.swing.KeyStroke.getKeyStroke( - KeyEvent.VK_C, Toolkit.getDefaultToolkit() - .getMenuShortcutKeyMask())); - jMenuEditCut.setAccelerator(javax.swing.KeyStroke.getKeyStroke( - KeyEvent.VK_X, Toolkit.getDefaultToolkit() - .getMenuShortcutKeyMask())); - jMenuEditPaste.setAccelerator(javax.swing.KeyStroke.getKeyStroke( - KeyEvent.VK_V, Toolkit.getDefaultToolkit() - .getMenuShortcutKeyMask())); - - jMenuEditCopy.setText("Copy"); - jMenuEditCut.setText("Cut"); - jMenuEditPaste.setText("Paste"); - - jMenuFile.add(jMenuFileNew); - jMenuFile.add(jMenuFileOpen); - jMenuFile.add(jMenuFileClose); - jMenuFile.addSeparator(); - jMenuFile.add(jMenuFileImport); - jMenuFile.add(jMenuFileExport); - jMenuFile.add(jMenuFileExportStudy); - jMenuFile.addSeparator(); - jMenuFile.add(jMenuFileSave); - jMenuFile.add(jMenuFileSaveAs); - jMenuFile.addSeparator(); - jMenuFile.add(jMenuFileExit); - - jMenuEdit.add(jMenuEditCut); - jMenuEdit.add(jMenuEditCopy); - jMenuEdit.add(jMenuEditPaste); - jEgonetMenuBar.add(jMenuFile); - jEgonetMenuBar.add(jMenuEdit); - this.setJMenuBar(jEgonetMenuBar); - - jTabbedPane.setTabPlacement(JTabbedPane.TOP); - jTabbedPane.add(study_panel, "Study"); - - - for (Class qT : Shared.questionClasses) { - if(qT.equals(StudyQuestion.class)) - continue; - - jTabbedPane.add(questionPanel.get(qT), Question.getNiceName(qT)); - } - contentPane.add(jTabbedPane); - - /*********************************************************************** - * Action Listeners for Menu Events - */ - jMenuFileNew.addActionListener(new CatchingAction("jMenuFileNew") { - public void safeActionPerformed(ActionEvent e) throws Exception { - jMenuFileNew_actionPerformed(e); - } - }); - - jMenuFileOpen.addActionListener(new CatchingAction("jMenuFileOpen") { - public void safeActionPerformed(ActionEvent e) throws Exception { - jMenuFileOpen_actionPerformed(e); - } - }); - - jMenuFileClose.addActionListener(new CatchingAction("jMenuFileClose") { - public void safeActionPerformed(ActionEvent e) throws Exception { - jMenuFileClose_actionPerformed(e); - } - }); - - jMenuFileSave.addActionListener(new CatchingAction("jMenuFileSave") { - public void safeActionPerformed(ActionEvent e) throws Exception { - jMenuFileSave_actionPerformed(e); - } - }); - - jMenuFileExportStudy.addActionListener(new CatchingAction("jMenuFileExportStudy") { - public void safeActionPerformed(ActionEvent e) throws Exception { - jMenuFileExportStudy_actionPerformed(e); - } - }); - - jMenuFileSaveAs.addActionListener(new CatchingAction("jMenuFileSaveAs") { - public void safeActionPerformed(ActionEvent e) throws Exception { - jMenuFileSaveAs_actionPerformed(e); - } - }); - - jMenuFileImport.addActionListener(new CatchingAction("jMenuFileImport") { - public void safeActionPerformed(ActionEvent e) throws Exception { - jMenuFileImport_actionPerformed(e); - } - }); - - jMenuFileExport.addActionListener(new CatchingAction("jMenuFileExport") { - public void safeActionPerformed(ActionEvent e) throws Exception { - jMenuFileExport_actionPerformed(e); - } - }); - - jMenuFileExit.addActionListener(new CatchingAction("jMenuFileExit") { - public void safeActionPerformed(ActionEvent e) throws Exception { - jMenuFileExit_actionPerformed(e); - } - }); - - /*********************************************************************** - * Change Listener for tabs - */ - jTabbedPane.addChangeListener(new ChangeListener() { - public void stateChanged(ChangeEvent e) { - try { - jTabbedPane_stateChanged(e); - } catch (IOException ex) - { - throw new RuntimeException(ex); - } - } - }); - - /* Fill panel, initialize frame */ - egoNet.getStorage().createNewStudy(); - fillCurrentPanel(); - - pack(); - setMinimumSize(getPreferredSize()); - - setMaximizable(true); - setIconifiable(true); - setClosable(true); - - egoNet.getStudy().setModified(false); - updateMenus(); - } - - /*************************************************************************** - * Updates menus to take dirty question and study into account - */ - public void updateMenus() { - if (egoNet.getStorage().getStudyFile() == null) { - jMenuFileImport.setEnabled(false); - jMenuFileClose.setEnabled(false); - jMenuFileSave.setEnabled(false); - jMenuFileExportStudy.setEnabled(false); - jMenuFileSaveAs.setEnabled(false); - jMenuFileExport.setEnabled(false); - jTabbedPane.setEnabledAt(1, false); - jTabbedPane.setEnabledAt(2, false); - jTabbedPane.setEnabledAt(3, false); - jTabbedPane.setEnabledAt(4, false); - jTabbedPane.setSelectedIndex(0); - } else { - jMenuFileImport.setEnabled(true); - jMenuFileClose.setEnabled(true); - jMenuFileSave.setEnabled(egoNet.getStudy().isCompatible() - && egoNet.getStudy().isModified()); - jMenuFileSaveAs.setEnabled(true); - jMenuFileExportStudy.setEnabled(true); - jMenuFileExport.setEnabled(true); - jTabbedPane.setEnabledAt(1, true); - jTabbedPane.setEnabledAt(2, true); - jTabbedPane.setEnabledAt(3, true); - jTabbedPane.setEnabledAt(4, true); - } - } - - // split the file menu functionality out into a class of functionality - // and a class of the UI - /** - * New Study menu handler - * - * @param e - * Menu UI Event - * @throws IOException - */ - private void jMenuFileNew_actionPerformed(ActionEvent e) throws IOException { - boolean ok = closeStudyFile(); - - if (ok) { - egoNet.getStorage().newStudyFiles(); - fillCurrentPanel(); - egoNet.getStudy().setModified(false); - egoNet.getStudy().setCompatible(true); - egoNet.getStudy().addObserver(this); - updateMenus(); - } - } - - /*************************************************************************** - * Open Study menu handler - * - * @param e - * Menu UI Event - * @throws IOException - */ - private void jMenuFileOpen_actionPerformed(ActionEvent e) throws IOException { - boolean ok = closeStudyFile(); - - if (ok) { - egoNet.getStorage().selectStudy(); - fillCurrentPanel(); - egoNet.getStudy().setModified(false); - egoNet.getStudy().setCompatible(true); - egoNet.getStudy().addObserver(this); - updateMenus(); - } - } - - private void jMenuFileClose_actionPerformed(ActionEvent e) throws IOException { - boolean ok = closeStudyFile(); - - if (ok) { - egoNet.getStorage().createNewStudy(); - - fillCurrentPanel(); - egoNet.getStudy().addObserver(this); - egoNet.getStudy().setModified(false); - } - } - - private void jMenuFileImport_actionPerformed(ActionEvent e) throws Exception { - egoNet.getStorage().importQuestions(); - fillCurrentPanel(); - } - - private void jMenuFileExport_actionPerformed(ActionEvent e) { - egoNet.getStorage().exportQuestions(); - } - - private void jMenuFileSave_actionPerformed(ActionEvent e) throws IOException { - EgonetAnalytics.track("save study"); // track! - if (egoNet.getStorage().getStudyFile() == null) { - jMenuFileSaveAs_actionPerformed(e); - } else { - egoNet.getStorage().saveStudyFile(); - egoNet.getStudy().setModified(false); - } - } - - private void jMenuFileExportStudy_actionPerformed(ActionEvent e) throws IOException, CorruptedInterviewException { - egoNet.getStorage().exportStudy(false); - } - - private void jMenuFileSaveAs_actionPerformed(ActionEvent e) throws IOException { - egoNet.getStorage().saveAsStudyFile(); - fillStudyPanel(); - egoNet.getStudy().addObserver(this); - egoNet.getStudy().setModified(false); - egoNet.getStudy().setCompatible(true); - } - - // File | Exit action performed - public void jMenuFileExit_actionPerformed(ActionEvent e) { - try { - boolean exit = closeStudyFile(); - - if (exit) { - dispose(); - } - } catch (IOException ex) { - throw new RuntimeException(ex); - } - } - - /** - * Closes question file. If changes made gives user the option of saving. - * - * @return False iff user cancels save, True otherwise - * @throws IOException - */ - public boolean closeStudyFile() throws IOException { - boolean exit = true; - - if (egoNet.getStudy().isModified()) { - int confirm = JOptionPane - .showConfirmDialog( - this, - "There are unsaved changes to the study. Would you like to save the study now?", - "Save Study Changes", - JOptionPane.YES_NO_CANCEL_OPTION); - - if (confirm == JOptionPane.YES_OPTION) { - jMenuFileSave_actionPerformed(null); - } else if (confirm == JOptionPane.CANCEL_OPTION) { - exit = false; - } - } - - return exit; - } - - public void fillCurrentPanel() throws IOException { - boolean sd = egoNet.getStudy().isModified(); - boolean sc = egoNet.getStudy().isCompatible(); - - if (curTab == StudyQuestion.class) { - study_panel.fillPanel(); - } else { - questionPanel.get(curTab).fillPanel(); - } - - egoNet.getStudy().setModified(sd); - egoNet.getStudy().setCompatible(sc); - } - - public void fillStudyPanel() throws IOException { - boolean sd = egoNet.getStudy().isModified(); - - if (curTab == StudyQuestion.class) { - study_panel.fillPanel(); - } - - egoNet.getStudy().setModified(sd); - } - - private void jTabbedPane_stateChanged(ChangeEvent e) throws IOException - { - lastTab = curTab; - Component selectedTab = jTabbedPane.getSelectedComponent(); - if(selectedTab instanceof StudyPanel) - { - curTab = StudyQuestion.class; - } else { - curTab = ((EgoQPanel)selectedTab).questionType; - } - - if ((lastTab == StudyQuestion.class) && (curTab != lastTab)) { - egoNet.getStudy().validateQuestions(); - } - - if (curTab == StudyQuestion.class) { - study_panel.fillPanel(); - } else { - questionPanel.get(curTab).fillPanel(); - } - } - - protected void setWaitCursor(boolean waitCursor) { - - if (waitCursor) { - this.getGlassPane().setVisible(true); - this.getGlassPane().setCursor( - Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); - } else { - this.getGlassPane().setCursor( - Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); - this.getGlassPane().setVisible(false); - } - } - - class CloseListener extends WindowAdapter { - /* - * (non-Javadoc) - * - * @see java.awt.event.WindowListener#windowClosed(java.awt.event.WindowEvent) - */ - public void windowClosing(WindowEvent arg0) { - logger.info("Window close event received"); - try { - jMenuFileExit_actionPerformed(null); - } catch (Throwable cause) - { - throw new RuntimeException(cause); - } - } - } - - /* - * (non-Javadoc) - * - * @see java.util.Observer#update(java.util.Observable, java.lang.Object) - */ - public void update(Observable o, Object arg) { - updateMenus(); - } - - public void focusActivated() { - //logger.info(this.getTitle() + " activated"); - - } - - public void focusDeactivated() { - //logger.info(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) { - - - } +/*** + * 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 . + */ +package com.endlessloopsoftware.ego.author; + +import org.egonet.model.question.*; +import java.awt.AWTEvent; + +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Cursor; +import java.awt.Toolkit; +import java.awt.event.ActionEvent; +import java.awt.event.KeyEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Observable; +import java.util.Observer; + +import javax.swing.*; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.event.InternalFrameEvent; +import javax.swing.event.InternalFrameListener; +import javax.swing.text.DefaultEditorKit; + +import org.egonet.exceptions.CorruptedInterviewException; +import org.egonet.gui.MDIChildFrame; +import org.egonet.mdi.MDIContext; +import org.egonet.model.question.Question; +import org.egonet.util.CatchingAction; +import org.egonet.util.EgonetAnalytics; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.endlessloopsoftware.egonet.Shared; + +import org.egonet.model.question.StudyQuestion; + +public class EgoFrame extends MDIChildFrame implements Observer, InternalFrameListener { + + final private static Logger logger = LoggerFactory.getLogger(EgoFrame.class); + + /** + * Changes based on jTabbedPane_stateChanged, which is activated when tabs are clicked + */ + Class curTab = StudyQuestion.class; + Class lastTab = StudyQuestion.class; + + private final EgoNet egoNet; + private JPanel contentPane; + + private final JMenuBar jEgonetMenuBar = new JMenuBar(); + private final JMenu jMenuFile = new JMenu("File"); + private final JMenuItem jMenuFileNew = new JMenuItem("New Study"); + private final JMenuItem jMenuFileOpen = new JMenuItem("Open Study"); + private final JMenuItem jMenuFileClose = new JMenuItem("Close Study"); + private final JMenuItem jMenuFileImport = new JMenuItem("Import Questions..."); + private final JMenuItem jMenuFileExport = new JMenuItem("Export Questions..."); + private final JMenuItem jMenuFileExportStudy = new JMenuItem("Export Study As..."); + + private final JMenuItem jMenuFileSaveAs = new JMenuItem("Save Study As..."); + private final JMenuItem jMenuFileSave = new JMenuItem("Save Study"); + + + + private final JMenuItem jMenuFileExit = new JMenuItem("Quit"); + private final JMenu jMenuEdit = new JMenu("Edit"); + private final JMenuItem jMenuEditCut = new JMenuItem(new DefaultEditorKit.CutAction()); + private final JMenuItem jMenuEditCopy = new JMenuItem(new DefaultEditorKit.CopyAction()); + private final JMenuItem jMenuEditPaste = new JMenuItem(new DefaultEditorKit.PasteAction()); + + private final JTabbedPane jTabbedPane = new JTabbedPane(); + private final BorderLayout borderLayout1 = new BorderLayout(); + + private final StudyPanel study_panel; + + private final Map,EgoQPanel> questionPanel; + + // Construct the frame + public EgoFrame(EgoNet egoNet) + { + try { + this.egoNet = egoNet; + study_panel = new StudyPanel(egoNet); + + questionPanel = new HashMap,EgoQPanel>(); + questionPanel.put(EgoQuestion.class, new AuthoringQuestionPanel(egoNet, EgoQuestion.class)); + questionPanel.put(AlterPromptQuestion.class, new PromptPanel(egoNet, AlterPromptQuestion.class)); + questionPanel.put(AlterQuestion.class, new AuthoringQuestionPanel(egoNet, AlterQuestion.class)); + questionPanel.put(AlterPairQuestion.class, new AuthoringQuestionPanel(egoNet, AlterPairQuestion.class)); + + enableEvents(AWTEvent.WINDOW_EVENT_MASK); + jbInit(); + } + catch (Exception ex) { + throw new RuntimeException(ex); + } + + } + + // Component initialization + private void jbInit() throws Exception { + // Listen for window closing + //this.addWindowListener(new CloseListener()); + this.addInternalFrameListener(this); + + //fixme + + this.setDefaultCloseOperation(DISPOSE_ON_CLOSE); + setResizable(true); + + contentPane = new JPanel(); + contentPane.setLayout(borderLayout1); + setContentPane(contentPane); + setTitle("Study Design Tool"); + + jMenuFileExit.setAccelerator(javax.swing.KeyStroke.getKeyStroke( + KeyEvent.VK_Q, Toolkit.getDefaultToolkit() + .getMenuShortcutKeyMask())); + jMenuFileNew.setAccelerator(javax.swing.KeyStroke.getKeyStroke( + KeyEvent.VK_N, Toolkit.getDefaultToolkit() + .getMenuShortcutKeyMask())); + jMenuFileOpen.setAccelerator(javax.swing.KeyStroke.getKeyStroke( + KeyEvent.VK_O, Toolkit.getDefaultToolkit() + .getMenuShortcutKeyMask())); + jMenuFileClose.setAccelerator(javax.swing.KeyStroke.getKeyStroke( + KeyEvent.VK_W, Toolkit.getDefaultToolkit() + .getMenuShortcutKeyMask())); + jMenuEditCopy.setAccelerator(javax.swing.KeyStroke.getKeyStroke( + KeyEvent.VK_C, Toolkit.getDefaultToolkit() + .getMenuShortcutKeyMask())); + jMenuEditCut.setAccelerator(javax.swing.KeyStroke.getKeyStroke( + KeyEvent.VK_X, Toolkit.getDefaultToolkit() + .getMenuShortcutKeyMask())); + jMenuEditPaste.setAccelerator(javax.swing.KeyStroke.getKeyStroke( + KeyEvent.VK_V, Toolkit.getDefaultToolkit() + .getMenuShortcutKeyMask())); + + jMenuEditCopy.setText("Copy"); + jMenuEditCut.setText("Cut"); + jMenuEditPaste.setText("Paste"); + + jMenuFile.add(jMenuFileNew); + jMenuFile.add(jMenuFileOpen); + jMenuFile.add(jMenuFileClose); + jMenuFile.addSeparator(); + jMenuFile.add(jMenuFileImport); + jMenuFile.add(jMenuFileExport); + jMenuFile.add(jMenuFileExportStudy); + jMenuFile.addSeparator(); + jMenuFile.add(jMenuFileSave); + jMenuFile.add(jMenuFileSaveAs); + jMenuFile.addSeparator(); + jMenuFile.add(jMenuFileExit); + + jMenuEdit.add(jMenuEditCut); + jMenuEdit.add(jMenuEditCopy); + jMenuEdit.add(jMenuEditPaste); + jEgonetMenuBar.add(jMenuFile); + jEgonetMenuBar.add(jMenuEdit); + this.setJMenuBar(jEgonetMenuBar); + + jTabbedPane.setTabPlacement(JTabbedPane.TOP); + jTabbedPane.add(study_panel, "Study"); + + + for (Class qT : Shared.questionClasses) { + if(qT.equals(StudyQuestion.class)) + continue; + + jTabbedPane.add(questionPanel.get(qT), Question.getNiceName(qT)); + } + contentPane.add(jTabbedPane); + + /*********************************************************************** + * Action Listeners for Menu Events + */ + jMenuFileNew.addActionListener(new CatchingAction("jMenuFileNew") { + public void safeActionPerformed(ActionEvent e) throws Exception { + jMenuFileNew_actionPerformed(e); + } + }); + + jMenuFileOpen.addActionListener(new CatchingAction("jMenuFileOpen") { + public void safeActionPerformed(ActionEvent e) throws Exception { + jMenuFileOpen_actionPerformed(e); + } + }); + + jMenuFileClose.addActionListener(new CatchingAction("jMenuFileClose") { + public void safeActionPerformed(ActionEvent e) throws Exception { + jMenuFileClose_actionPerformed(e); + } + }); + + jMenuFileSave.addActionListener(new CatchingAction("jMenuFileSave") { + public void safeActionPerformed(ActionEvent e) throws Exception { + jMenuFileSave_actionPerformed(e); + } + }); + + jMenuFileExportStudy.addActionListener(new CatchingAction("jMenuFileExportStudy") { + public void safeActionPerformed(ActionEvent e) throws Exception { + jMenuFileExportStudy_actionPerformed(e); + } + }); + + jMenuFileSaveAs.addActionListener(new CatchingAction("jMenuFileSaveAs") { + public void safeActionPerformed(ActionEvent e) throws Exception { + jMenuFileSaveAs_actionPerformed(e); + } + }); + + jMenuFileImport.addActionListener(new CatchingAction("jMenuFileImport") { + public void safeActionPerformed(ActionEvent e) throws Exception { + jMenuFileImport_actionPerformed(e); + } + }); + + jMenuFileExport.addActionListener(new CatchingAction("jMenuFileExport") { + public void safeActionPerformed(ActionEvent e) throws Exception { + jMenuFileExport_actionPerformed(e); + } + }); + + jMenuFileExit.addActionListener(new CatchingAction("jMenuFileExit") { + public void safeActionPerformed(ActionEvent e) throws Exception { + jMenuFileExit_actionPerformed(e); + } + }); + + /*********************************************************************** + * Change Listener for tabs + */ + jTabbedPane.addChangeListener(new ChangeListener() { + public void stateChanged(ChangeEvent e) { + try { + jTabbedPane_stateChanged(e); + } catch (IOException ex) + { + throw new RuntimeException(ex); + } + } + }); + + /* Fill panel, initialize frame */ + egoNet.getStorage().createNewStudy(); + fillCurrentPanel(); + + pack(); + setMinimumSize(getPreferredSize()); + + setMaximizable(true); + setIconifiable(true); + setClosable(true); + + egoNet.getStudy().setModified(false); + updateMenus(); + } + + /*************************************************************************** + * Updates menus to take dirty question and study into account + */ + public void updateMenus() { + if (egoNet.getStorage().getStudyFile() == null) { + jMenuFileImport.setEnabled(false); + jMenuFileClose.setEnabled(false); + jMenuFileSave.setEnabled(false); + jMenuFileExportStudy.setEnabled(false); + jMenuFileSaveAs.setEnabled(false); + jMenuFileExport.setEnabled(false); + jTabbedPane.setEnabledAt(1, false); + jTabbedPane.setEnabledAt(2, false); + jTabbedPane.setEnabledAt(3, false); + jTabbedPane.setEnabledAt(4, false); + jTabbedPane.setSelectedIndex(0); + } else { + jMenuFileImport.setEnabled(true); + jMenuFileClose.setEnabled(true); + jMenuFileSave.setEnabled(egoNet.getStudy().isCompatible() + && egoNet.getStudy().isModified()); + jMenuFileSaveAs.setEnabled(true); + jMenuFileExportStudy.setEnabled(true); + jMenuFileExport.setEnabled(true); + jTabbedPane.setEnabledAt(1, true); + jTabbedPane.setEnabledAt(2, true); + jTabbedPane.setEnabledAt(3, true); + jTabbedPane.setEnabledAt(4, true); + } + } + + // split the file menu functionality out into a class of functionality + // and a class of the UI + /** + * New Study menu handler + * + * @param e + * Menu UI Event + * @throws IOException + */ + private void jMenuFileNew_actionPerformed(ActionEvent e) throws IOException { + boolean ok = closeStudyFile(); + + if (ok) { + egoNet.getStorage().newStudyFiles(); + fillCurrentPanel(); + egoNet.getStudy().setModified(false); + egoNet.getStudy().setCompatible(true); + egoNet.getStudy().addObserver(this); + updateMenus(); + } + } + + /*************************************************************************** + * Open Study menu handler + * + * @param e + * Menu UI Event + * @throws IOException + */ + private void jMenuFileOpen_actionPerformed(ActionEvent e) throws IOException { + boolean ok = closeStudyFile(); + + if (ok) { + egoNet.getStorage().selectStudy(); + fillCurrentPanel(); + egoNet.getStudy().setModified(false); + egoNet.getStudy().setCompatible(true); + egoNet.getStudy().addObserver(this); + updateMenus(); + } + } + + private void jMenuFileClose_actionPerformed(ActionEvent e) throws IOException { + boolean ok = closeStudyFile(); + + if (ok) { + egoNet.getStorage().createNewStudy(); + + fillCurrentPanel(); + egoNet.getStudy().addObserver(this); + egoNet.getStudy().setModified(false); + } + } + + private void jMenuFileImport_actionPerformed(ActionEvent e) throws Exception { + egoNet.getStorage().importQuestions(); + fillCurrentPanel(); + } + + private void jMenuFileExport_actionPerformed(ActionEvent e) { + egoNet.getStorage().exportQuestions(); + } + + private void jMenuFileSave_actionPerformed(ActionEvent e) throws IOException { + EgonetAnalytics.track("save study"); // track! + if (egoNet.getStorage().getStudyFile() == null) { + jMenuFileSaveAs_actionPerformed(e); + } else { + egoNet.getStorage().saveStudyFile(); + egoNet.getStudy().setModified(false); + } + } + + private void jMenuFileExportStudy_actionPerformed(ActionEvent e) throws IOException, CorruptedInterviewException { + egoNet.getStorage().exportStudy(false); + } + + private void jMenuFileSaveAs_actionPerformed(ActionEvent e) throws IOException { + egoNet.getStorage().saveAsStudyFile(); + fillStudyPanel(); + egoNet.getStudy().addObserver(this); + egoNet.getStudy().setModified(false); + egoNet.getStudy().setCompatible(true); + } + + // File | Exit action performed + public void jMenuFileExit_actionPerformed(ActionEvent e) { + try { + boolean exit = closeStudyFile(); + + if (exit) { + dispose(); + } + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } + + /** + * Closes question file. If changes made gives user the option of saving. + * + * @return False iff user cancels save, True otherwise + * @throws IOException + */ + public boolean closeStudyFile() throws IOException { + boolean exit = true; + + if (egoNet.getStudy().isModified()) { + int confirm = JOptionPane + .showConfirmDialog( + this, + "There are unsaved changes to the study. Would you like to save the study now?", + "Save Study Changes", + JOptionPane.YES_NO_CANCEL_OPTION); + + if (confirm == JOptionPane.YES_OPTION) { + jMenuFileSave_actionPerformed(null); + } else if (confirm == JOptionPane.CANCEL_OPTION) { + exit = false; + } + } + + return exit; + } + + public void fillCurrentPanel() throws IOException { + boolean sd = egoNet.getStudy().isModified(); + boolean sc = egoNet.getStudy().isCompatible(); + + if (curTab == StudyQuestion.class) { + study_panel.fillPanel(); + } else { + questionPanel.get(curTab).fillPanel(); + } + + egoNet.getStudy().setModified(sd); + egoNet.getStudy().setCompatible(sc); + } + + public void fillStudyPanel() throws IOException { + boolean sd = egoNet.getStudy().isModified(); + + if (curTab == StudyQuestion.class) { + study_panel.fillPanel(); + } + + egoNet.getStudy().setModified(sd); + } + + private void jTabbedPane_stateChanged(ChangeEvent e) throws IOException + { + lastTab = curTab; + Component selectedTab = jTabbedPane.getSelectedComponent(); + if(selectedTab instanceof StudyPanel) + { + curTab = StudyQuestion.class; + } else { + curTab = ((EgoQPanel)selectedTab).questionType; + } + + if ((lastTab == StudyQuestion.class) && (curTab != lastTab)) { + egoNet.getStudy().validateQuestions(); + } + + if (curTab == StudyQuestion.class) { + study_panel.fillPanel(); + } else { + questionPanel.get(curTab).fillPanel(); + } + } + + protected void setWaitCursor(boolean waitCursor) { + + if (waitCursor) { + this.getGlassPane().setVisible(true); + this.getGlassPane().setCursor( + Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + } else { + this.getGlassPane().setCursor( + Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + this.getGlassPane().setVisible(false); + } + } + + class CloseListener extends WindowAdapter { + /* + * (non-Javadoc) + * + * @see java.awt.event.WindowListener#windowClosed(java.awt.event.WindowEvent) + */ + public void windowClosing(WindowEvent arg0) { + logger.info("Window close event received"); + try { + jMenuFileExit_actionPerformed(null); + } catch (Throwable cause) + { + throw new RuntimeException(cause); + } + } + } + + /* + * (non-Javadoc) + * + * @see java.util.Observer#update(java.util.Observable, java.lang.Object) + */ + public void update(Observable o, Object arg) { + updateMenus(); + } + + public void focusActivated() { + //logger.info(this.getTitle() + " activated"); + + } + + public void focusDeactivated() { + //logger.info(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) { + + + } } \ No newline at end of file diff --git a/src/com/endlessloopsoftware/ego/author/EgoNet.java b/src/main/java/com/endlessloopsoftware/ego/author/EgoNet.java similarity index 96% rename from src/com/endlessloopsoftware/ego/author/EgoNet.java rename to src/main/java/com/endlessloopsoftware/ego/author/EgoNet.java index aaf46d5..2e27cea 100644 --- a/src/com/endlessloopsoftware/ego/author/EgoNet.java +++ b/src/main/java/com/endlessloopsoftware/ego/author/EgoNet.java @@ -1,60 +1,60 @@ -/*** - * 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 . - */ -package com.endlessloopsoftware.ego.author; - -import org.egonet.gui.EgoStore; -import org.egonet.util.EgonetAnalytics; - -import com.endlessloopsoftware.egonet.Study; - -/** ONLY USE THIS CLASS IN AUTHOR PART OF THE TOOL */ -public class EgoNet -{ - private final EgoStore storage; - private final EgoFrame frame; - - public EgoNet() { - EgonetAnalytics.track("authoring client startup"); // track! - storage = new EgoStore(null); - storage.createNewStudy(); - - frame = new EgoFrame(this); - frame.validate(); - } - - public static void main(String[] args) throws Exception - { - //new Console(); - new EgoNet().getFrame().setVisible(true); - } - - public EgoStore getStorage() { - return storage; - } - - public EgoFrame getFrame() { - return frame; - } - - public Study getStudy() { - return storage.getStudy(); - } - - +/*** + * 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 . + */ +package com.endlessloopsoftware.ego.author; + +import org.egonet.gui.EgoStore; +import org.egonet.util.EgonetAnalytics; + +import com.endlessloopsoftware.egonet.Study; + +/** ONLY USE THIS CLASS IN AUTHOR PART OF THE TOOL */ +public class EgoNet +{ + private final EgoStore storage; + private final EgoFrame frame; + + public EgoNet() { + EgonetAnalytics.track("authoring client startup"); // track! + storage = new EgoStore(null); + storage.createNewStudy(); + + frame = new EgoFrame(this); + frame.validate(); + } + + public static void main(String[] args) throws Exception + { + //new Console(); + new EgoNet().getFrame().setVisible(true); + } + + public EgoStore getStorage() { + return storage; + } + + public EgoFrame getFrame() { + return frame; + } + + public Study getStudy() { + return storage.getStudy(); + } + + } \ No newline at end of file diff --git a/src/com/endlessloopsoftware/ego/author/EgoQPanel.java b/src/main/java/com/endlessloopsoftware/ego/author/EgoQPanel.java similarity index 97% rename from src/com/endlessloopsoftware/ego/author/EgoQPanel.java rename to src/main/java/com/endlessloopsoftware/ego/author/EgoQPanel.java index e23fae9..0636de3 100644 --- a/src/com/endlessloopsoftware/ego/author/EgoQPanel.java +++ b/src/main/java/com/endlessloopsoftware/ego/author/EgoQPanel.java @@ -1,35 +1,35 @@ -/*** - * 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 . - */ -package com.endlessloopsoftware.ego.author; -import javax.swing.JPanel; - -import org.egonet.model.question.Question; - - - -public abstract class EgoQPanel extends JPanel -{ - protected final Class questionType; - abstract public void fillPanel(); - abstract public void clearPanel(); - public EgoQPanel(Class questionType) - { - this.questionType = questionType; - } +/*** + * 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 . + */ +package com.endlessloopsoftware.ego.author; +import javax.swing.JPanel; + +import org.egonet.model.question.Question; + + + +public abstract class EgoQPanel extends JPanel +{ + protected final Class questionType; + abstract public void fillPanel(); + abstract public void clearPanel(); + public EgoQPanel(Class questionType) + { + this.questionType = questionType; + } } \ No newline at end of file diff --git a/src/com/endlessloopsoftware/ego/author/NoTabTextArea.java b/src/main/java/com/endlessloopsoftware/ego/author/NoTabTextArea.java similarity index 97% rename from src/com/endlessloopsoftware/ego/author/NoTabTextArea.java rename to src/main/java/com/endlessloopsoftware/ego/author/NoTabTextArea.java index 3b6cfe4..ffdab99 100644 --- a/src/com/endlessloopsoftware/ego/author/NoTabTextArea.java +++ b/src/main/java/com/endlessloopsoftware/ego/author/NoTabTextArea.java @@ -1,37 +1,37 @@ -/*** - * 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 . - */ -package com.endlessloopsoftware.ego.author; -import java.awt.KeyboardFocusManager; -import java.util.Collections; - -import javax.swing.JTextArea; - -/** - * Extends JTextArea to make tabs focus change events in question text areas - */ -public class NoTabTextArea extends JTextArea -{ - @SuppressWarnings("unchecked") -public NoTabTextArea() - { - super(); - setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, Collections.EMPTY_SET); - setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, Collections.EMPTY_SET); - } +/*** + * 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 . + */ +package com.endlessloopsoftware.ego.author; +import java.awt.KeyboardFocusManager; +import java.util.Collections; + +import javax.swing.JTextArea; + +/** + * Extends JTextArea to make tabs focus change events in question text areas + */ +public class NoTabTextArea extends JTextArea +{ + @SuppressWarnings("unchecked") +public NoTabTextArea() + { + super(); + setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, Collections.EMPTY_SET); + setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, Collections.EMPTY_SET); + } } \ No newline at end of file diff --git a/src/com/endlessloopsoftware/ego/author/PromptPanel.java b/src/main/java/com/endlessloopsoftware/ego/author/PromptPanel.java similarity index 97% rename from src/com/endlessloopsoftware/ego/author/PromptPanel.java rename to src/main/java/com/endlessloopsoftware/ego/author/PromptPanel.java index 46c8b76..51005a8 100644 --- a/src/com/endlessloopsoftware/ego/author/PromptPanel.java +++ b/src/main/java/com/endlessloopsoftware/ego/author/PromptPanel.java @@ -1,498 +1,498 @@ -/*** - * 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 . - */ -package com.endlessloopsoftware.ego.author; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.GridBagConstraints; -import java.awt.GridBagLayout; -import java.awt.GridLayout; -import java.awt.Insets; -import java.awt.event.ActionEvent; - -import javax.swing.*; -import javax.swing.border.Border; -import javax.swing.border.EtchedBorder; -import javax.swing.border.TitledBorder; -import javax.swing.event.DocumentEvent; -import javax.swing.event.DocumentListener; -import javax.swing.event.ListSelectionEvent; -import javax.swing.event.ListSelectionListener; - -import org.egonet.exceptions.DuplicateQuestionException; -import org.egonet.model.question.AlterPromptQuestion; -import org.egonet.model.question.Question; - -import com.endlessloopsoftware.ego.client.ClientQuestionPanel; - - -/** - * Generic Panel creation and handling routines for question editing - */ -public class PromptPanel extends EgoQPanel -{ - private boolean inUpdate; - - private final JSplitPane question_split = new JSplitPane(); - private final JList question_list = new JList(); - private final JScrollPane question_list_scroll = new JScrollPane(question_list); - private final JPanel question_panel_right = new RightPanel(); - private final JLabel question_title_label = new JLabel("Title:"); - private final JLabel question_question_label = new JLabel("Question:"); - private final JLabel question_citation_label = new JLabel("Citation:"); - private final JLabel question_follows_label = new JLabel("Follows Question:"); - private final JTextArea question_question_field = new NoTabTextArea(); - private final JTextArea question_citation_field = new NoTabTextArea(); - private final JTextField question_title_field = new JTextField(); - private final JButton question_new_button = new JButton("New"); - private final JButton question_preview_button = new JButton("Preview"); - private final JComboBox question_follows_menu = new JComboBox(); - private final JButton question_delete_button = new JButton("Delete"); - private final Border listBorder; - - private final EgoNet egoNet; - - /** - * Generates Panel for question editing to insert in file tab window - * - * @param type Type of questions on Page (e.g. Alter Questions) - * @param parent parent frame for referencing composed objects - */ - public PromptPanel(EgoNet egoNet, Class type) throws Exception - { - super(type); - this.egoNet = egoNet; - - - question_question_field.setName("question_question_field"); - question_citation_field.setName("question_citation_field"); - question_title_field.setName("question_title_field"); - - listBorder = BorderFactory.createCompoundBorder( - new TitledBorder(new EtchedBorder(EtchedBorder.RAISED,Color.white,new Color(178, 178, 178)), - Question.getNiceName(questionType)), - BorderFactory.createEmptyBorder(10,10,10,10)); - - jbInit(); - } - - /** - * Component initialization - * - * @throws Exception - */ - private void jbInit() throws Exception - { - inUpdate = true; - - // Configure Split Frame - question_split.setMinimumSize(new Dimension(430, 330)); - question_split.setPreferredSize(new Dimension(430, 330)); - question_split.setResizeWeight(.33); - question_split.setDividerLocation(.33); - question_list_scroll.setRequestFocusEnabled(false); - question_split.add(question_list_scroll, JSplitPane.LEFT); - question_split.add(question_panel_right, JSplitPane.RIGHT); - - this.setLayout(new GridLayout()); - - // Configure List - question_list_scroll.setBorder(listBorder); - question_list_scroll.setMinimumSize(new Dimension(150, 150)); - question_list_scroll.setPreferredSize(new Dimension(150, 150)); - question_list_scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); - - question_list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - question_list.setCellRenderer(new QuestionListCellRenderer()); - - // Configure question fields - question_panel_right.setLayout(new GridBagLayout()); - question_question_field.setMaximumSize(new Dimension(280, 64)); - question_question_field.setMinimumSize(new Dimension(72, 16)); - question_question_field.setPreferredSize(new Dimension(72, 16)); - question_question_field.setLineWrap(true); - question_question_field.setRows(1); - question_question_field.setTabSize(4); - question_question_field.setWrapStyleWord(true); - - question_citation_field.setMaximumSize(new Dimension(280, 64)); - question_citation_field.setMinimumSize(new Dimension(72, 16)); - question_citation_field.setPreferredSize(new Dimension(72, 16)); - question_citation_field.setLineWrap(true); - question_citation_field.setRows(1); - question_citation_field.setTabSize(4); - question_citation_field.setWrapStyleWord(true); - - /* Question Layout */ - question_panel_right.add(question_title_label, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, - GridBagConstraints.HORIZONTAL, new Insets(10, 10, 10, 10), 0, 0)); - question_panel_right.add(question_title_field, new GridBagConstraints(1, 0, 2, 1, 0.0, 0.0, - GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(10, 10, 10, 10), 0, 4)); - question_panel_right.add(question_question_label, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, - GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(10, 10, 10, 10), 0, 0)); - question_panel_right.add(new JScrollPane(question_question_field), new GridBagConstraints(1, 1, 2, 2, 0.0, 0.4, - GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(10, 10, 10, 10), 0, 0)); - question_panel_right.add(question_citation_label, new GridBagConstraints(0, 3, 1, 1, 0.0, 0.0, - GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(10, 10, 10, 10), 0, 0)); - question_panel_right.add(new JScrollPane(question_citation_field), new GridBagConstraints(1, 3, 2, 2, 0.0, 0.3, - GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(10, 10, 10, 10), 0, 0)); - question_panel_right.add(question_new_button, new GridBagConstraints(0, 7, 1, 1, 0.33, 0.0, - GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(10, 10, 10, 10), 0, 0)); - question_panel_right.add(question_preview_button, new GridBagConstraints(1, 7, 1, 1, 0.33, 0.0, - GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(10, 10, 10, 10), 0, 0)); - question_panel_right.add(question_delete_button, new GridBagConstraints(2, 7, 1, 1, 0.33, 0.0, - GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(10, 10, 10, 10), 0, 0)); - question_panel_right.add(question_follows_label, new GridBagConstraints(0, 5, 1, 1, 0.0, 0.0, - GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(10, 10, 10, 10), 0, 0)); - question_panel_right.add(question_follows_menu, new GridBagConstraints(1, 5, 1, 1, 0.0, 0.0, - GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(10, 10, 10, 10), 0, 0)); - - DefaultListModel listModel = new DefaultListModel(); - question_list.setModel(listModel); - egoNet.getStudy().fillList(questionType, listModel); - - question_list.getSelectionModel().addListSelectionListener(new ListSelectionListener() - { - public void valueChanged(ListSelectionEvent e) - { - question_list_selectionChanged(e); - } - }); - - question_new_button.addActionListener(new java.awt.event.ActionListener() - { - public void actionPerformed(ActionEvent e) { - question_new_button_actionPerformed(e); - } - }); - - question_preview_button.addActionListener(new java.awt.event.ActionListener() - { - public void actionPerformed(ActionEvent e) - { - ClientQuestionPanel.showPreview( - question_title_field.getText(),question_question_field.getText(), - AlterPromptQuestion.class,null,null); - } - }); - - question_delete_button.addActionListener(new java.awt.event.ActionListener() - { - public void actionPerformed(ActionEvent e) - { - question_delete_button_actionPerformed(e); - } - }); - - question_follows_menu.addActionListener(new java.awt.event.ActionListener() - { - public void actionPerformed(ActionEvent e) - { - question_follows_menu_actionPerformed(e); - } - }); - - question_title_field.getDocument().addDocumentListener(new DocumentListener() - { - public void insertUpdate(DocumentEvent e) - { - questionTitleEvent(); - } - - public void changedUpdate(DocumentEvent e) - { - questionTitleEvent(); - } - - public void removeUpdate(DocumentEvent e) - { - questionTitleEvent(); - } - }); - - question_question_field.getDocument().addDocumentListener(new DocumentListener() - { - public void insertUpdate(DocumentEvent e) - { - questionTextEvent(); - } - - public void changedUpdate(DocumentEvent e) - { - questionTextEvent(); - } - - public void removeUpdate(DocumentEvent e) - { - questionTextEvent(); - } - }); - - question_citation_field.getDocument().addDocumentListener(new DocumentListener() - { - public void insertUpdate(DocumentEvent e) - { - questionCitationEvent(); - } - - public void changedUpdate(DocumentEvent e) - { - questionCitationEvent(); - } - - public void removeUpdate(DocumentEvent e) - { - questionCitationEvent(); - } - }); - - add(question_split); - - inUpdate = false; - } - - /** - * Updates right side question fields when the selection changes - * - * @param e event generated by selection change. - */ - public void question_list_selectionChanged(ListSelectionEvent e) - { - if (!inUpdate) - { - questionUpdate(); - } - } - - /**** - * fill List with appropriate questions Set other fields to selected - * question - */ - public void fillPanel() - { - //logger.info("fillPanel() called in PromptPanel but questionType was " + questionType + " and curTab was " + egoNet.getFrame().curTab); - if (questionType == egoNet.getFrame().curTab) - { - storageUpdate(); - questionUpdate(); - } - } - - /** - * Called when file changes to load new questions into list - */ - void storageUpdate() - { - inUpdate = true; - - if (questionType == egoNet.getFrame().curTab) - { - ((DefaultListModel) question_list.getModel()).removeAllElements(); - egoNet.getStudy().fillList(questionType, (DefaultListModel)question_list.getModel()); - } - - inUpdate = false; - } - - void questionUpdate() - { - inUpdate = true; - - /** @todo Use List Data Listener? */ - if (questionType.equals(egoNet.getFrame().curTab)) { - int index = question_list.getSelectedIndex(); - if ((question_list.getModel().getSize() > 0) && (index == -1)) - { - index = 0; - } - - question_follows_menu.removeAllItems(); - question_follows_menu.addItem(egoNet.getStudy().getFirstQuestion()); - for (int i = 0; i < question_list.getModel().getSize(); i++) - { - if (i != index) - { - question_follows_menu.addItem(question_list.getModel().getElementAt(i)); - } - } - - question_list.setSelectedIndex(index); - Question q = (Question) question_list.getSelectedValue(); - if (q != null) - { - question_question_field.setText(q.text); - question_citation_field.setText(q.citation); - question_title_field.setText(q.title); - question_follows_menu.setSelectedIndex(index); - - question_question_field.setEditable(true); - question_citation_field.setEditable(true); - question_title_field.setEditable(true); - question_delete_button.setEnabled(true); - question_follows_menu.setEnabled(true); - } - else - { - question_question_field.setText(null); - question_citation_field.setText(null); - question_title_field.setText(null); - - question_question_field.setEditable(false); - question_citation_field.setEditable(false); - question_title_field.setEditable(false); - question_delete_button.setEnabled(false); - question_follows_menu.setEnabled(false); - } - } - - inUpdate = false; - } - - /**** - * Clear all on screen editable fields Generally called when a new survey is - * started - */ - public void clearPanel() - { - inUpdate = true; - ((DefaultListModel) question_list.getModel()).removeAllElements(); - inUpdate = false; - } - - /**** - * Document event handler used to read text fields - * - * @param e Document Event - */ - private void questionTitleEvent() - { - Question q = (Question) question_list.getSelectedValue(); - String s; - - if ((q != null) && !inUpdate) - { - s = question_title_field.getText().trim(); - if ((q.title == null) || (!q.title.equals(s))) - { - q.title = question_title_field.getText().trim(); - egoNet.getStudy().setModified(true); - question_list.repaint(); - } - } - } - - /**** - * Document event handler used to read text fields - * - * @param e Document Event - */ - private void questionTextEvent() - { - Question q = (Question) question_list.getSelectedValue(); - String s; - - if ((q != null) && !inUpdate) - { - s = question_question_field.getText().trim(); - if ((q.text == null) || (!q.text.equals(s))) - { - q.text = question_question_field.getText().trim(); - egoNet.getStudy().setModified(true); - } - } - } - - /**** - * Document event handler used to read text fields - * - * @param e Document Event - */ - private void questionCitationEvent() - { - Question q = (Question) question_list.getSelectedValue(); - String s; - - if ((q != null) && !inUpdate) - { - s = question_citation_field.getText().trim(); - if ((q.citation == null) || (!q.citation.equals(s))) - { - q.citation = question_citation_field.getText().trim(); - egoNet.getStudy().setModified(true); - } - } - } - - void question_new_button_actionPerformed(ActionEvent e) { - - Question q; - try { q = questionType.newInstance(); } catch (Exception ex) { throw new RuntimeException(ex); } - q.title = new String("Untitled Question"); - - try - { - egoNet.getStudy().addQuestion(q); - } - catch (DuplicateQuestionException e1) - { - throw new RuntimeException(e1); - } - - fillPanel(); - question_list.setSelectedValue(q, true); - - question_title_field.requestFocus(); - question_title_field.setSelectionStart(0); - question_title_field.setSelectionEnd(question_title_field.getText().length()); - } - - void question_delete_button_actionPerformed(ActionEvent e) - { - Question q = (Question) question_list.getSelectedValue(); - - if (q != null) - { - int confirm = JOptionPane.showConfirmDialog(egoNet.getFrame(), "Permanently remove this questions?", - "Delete Question", JOptionPane.OK_CANCEL_OPTION); - - if (confirm == JOptionPane.OK_OPTION) - { - egoNet.getStudy().removeQuestion(q); - fillPanel(); - } - } - } - - /** - * Changes order of questions - * - * @param e UI event - */ - void question_follows_menu_actionPerformed(ActionEvent e) - { - if (!inUpdate) - { - Question follows = (Question) question_follows_menu.getSelectedItem(); - Question q = (Question) question_list.getSelectedValue(); - - egoNet.getStudy().moveQuestionAfter(q, follows); - fillPanel(); - } - } -} +/*** + * 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 . + */ +package com.endlessloopsoftware.ego.author; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.GridLayout; +import java.awt.Insets; +import java.awt.event.ActionEvent; + +import javax.swing.*; +import javax.swing.border.Border; +import javax.swing.border.EtchedBorder; +import javax.swing.border.TitledBorder; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; + +import org.egonet.exceptions.DuplicateQuestionException; +import org.egonet.model.question.AlterPromptQuestion; +import org.egonet.model.question.Question; + +import com.endlessloopsoftware.ego.client.ClientQuestionPanel; + + +/** + * Generic Panel creation and handling routines for question editing + */ +public class PromptPanel extends EgoQPanel +{ + private boolean inUpdate; + + private final JSplitPane question_split = new JSplitPane(); + private final JList question_list = new JList(); + private final JScrollPane question_list_scroll = new JScrollPane(question_list); + private final JPanel question_panel_right = new RightPanel(); + private final JLabel question_title_label = new JLabel("Title:"); + private final JLabel question_question_label = new JLabel("Question:"); + private final JLabel question_citation_label = new JLabel("Citation:"); + private final JLabel question_follows_label = new JLabel("Follows Question:"); + private final JTextArea question_question_field = new NoTabTextArea(); + private final JTextArea question_citation_field = new NoTabTextArea(); + private final JTextField question_title_field = new JTextField(); + private final JButton question_new_button = new JButton("New"); + private final JButton question_preview_button = new JButton("Preview"); + private final JComboBox question_follows_menu = new JComboBox(); + private final JButton question_delete_button = new JButton("Delete"); + private final Border listBorder; + + private final EgoNet egoNet; + + /** + * Generates Panel for question editing to insert in file tab window + * + * @param type Type of questions on Page (e.g. Alter Questions) + * @param parent parent frame for referencing composed objects + */ + public PromptPanel(EgoNet egoNet, Class type) throws Exception + { + super(type); + this.egoNet = egoNet; + + + question_question_field.setName("question_question_field"); + question_citation_field.setName("question_citation_field"); + question_title_field.setName("question_title_field"); + + listBorder = BorderFactory.createCompoundBorder( + new TitledBorder(new EtchedBorder(EtchedBorder.RAISED,Color.white,new Color(178, 178, 178)), + Question.getNiceName(questionType)), + BorderFactory.createEmptyBorder(10,10,10,10)); + + jbInit(); + } + + /** + * Component initialization + * + * @throws Exception + */ + private void jbInit() throws Exception + { + inUpdate = true; + + // Configure Split Frame + question_split.setMinimumSize(new Dimension(430, 330)); + question_split.setPreferredSize(new Dimension(430, 330)); + question_split.setResizeWeight(.33); + question_split.setDividerLocation(.33); + question_list_scroll.setRequestFocusEnabled(false); + question_split.add(question_list_scroll, JSplitPane.LEFT); + question_split.add(question_panel_right, JSplitPane.RIGHT); + + this.setLayout(new GridLayout()); + + // Configure List + question_list_scroll.setBorder(listBorder); + question_list_scroll.setMinimumSize(new Dimension(150, 150)); + question_list_scroll.setPreferredSize(new Dimension(150, 150)); + question_list_scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); + + question_list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + question_list.setCellRenderer(new QuestionListCellRenderer()); + + // Configure question fields + question_panel_right.setLayout(new GridBagLayout()); + question_question_field.setMaximumSize(new Dimension(280, 64)); + question_question_field.setMinimumSize(new Dimension(72, 16)); + question_question_field.setPreferredSize(new Dimension(72, 16)); + question_question_field.setLineWrap(true); + question_question_field.setRows(1); + question_question_field.setTabSize(4); + question_question_field.setWrapStyleWord(true); + + question_citation_field.setMaximumSize(new Dimension(280, 64)); + question_citation_field.setMinimumSize(new Dimension(72, 16)); + question_citation_field.setPreferredSize(new Dimension(72, 16)); + question_citation_field.setLineWrap(true); + question_citation_field.setRows(1); + question_citation_field.setTabSize(4); + question_citation_field.setWrapStyleWord(true); + + /* Question Layout */ + question_panel_right.add(question_title_label, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, + GridBagConstraints.HORIZONTAL, new Insets(10, 10, 10, 10), 0, 0)); + question_panel_right.add(question_title_field, new GridBagConstraints(1, 0, 2, 1, 0.0, 0.0, + GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(10, 10, 10, 10), 0, 4)); + question_panel_right.add(question_question_label, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, + GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(10, 10, 10, 10), 0, 0)); + question_panel_right.add(new JScrollPane(question_question_field), new GridBagConstraints(1, 1, 2, 2, 0.0, 0.4, + GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(10, 10, 10, 10), 0, 0)); + question_panel_right.add(question_citation_label, new GridBagConstraints(0, 3, 1, 1, 0.0, 0.0, + GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(10, 10, 10, 10), 0, 0)); + question_panel_right.add(new JScrollPane(question_citation_field), new GridBagConstraints(1, 3, 2, 2, 0.0, 0.3, + GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(10, 10, 10, 10), 0, 0)); + question_panel_right.add(question_new_button, new GridBagConstraints(0, 7, 1, 1, 0.33, 0.0, + GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(10, 10, 10, 10), 0, 0)); + question_panel_right.add(question_preview_button, new GridBagConstraints(1, 7, 1, 1, 0.33, 0.0, + GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(10, 10, 10, 10), 0, 0)); + question_panel_right.add(question_delete_button, new GridBagConstraints(2, 7, 1, 1, 0.33, 0.0, + GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(10, 10, 10, 10), 0, 0)); + question_panel_right.add(question_follows_label, new GridBagConstraints(0, 5, 1, 1, 0.0, 0.0, + GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(10, 10, 10, 10), 0, 0)); + question_panel_right.add(question_follows_menu, new GridBagConstraints(1, 5, 1, 1, 0.0, 0.0, + GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(10, 10, 10, 10), 0, 0)); + + DefaultListModel listModel = new DefaultListModel(); + question_list.setModel(listModel); + egoNet.getStudy().fillList(questionType, listModel); + + question_list.getSelectionModel().addListSelectionListener(new ListSelectionListener() + { + public void valueChanged(ListSelectionEvent e) + { + question_list_selectionChanged(e); + } + }); + + question_new_button.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(ActionEvent e) { + question_new_button_actionPerformed(e); + } + }); + + question_preview_button.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(ActionEvent e) + { + ClientQuestionPanel.showPreview( + question_title_field.getText(),question_question_field.getText(), + AlterPromptQuestion.class,null,null); + } + }); + + question_delete_button.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(ActionEvent e) + { + question_delete_button_actionPerformed(e); + } + }); + + question_follows_menu.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(ActionEvent e) + { + question_follows_menu_actionPerformed(e); + } + }); + + question_title_field.getDocument().addDocumentListener(new DocumentListener() + { + public void insertUpdate(DocumentEvent e) + { + questionTitleEvent(); + } + + public void changedUpdate(DocumentEvent e) + { + questionTitleEvent(); + } + + public void removeUpdate(DocumentEvent e) + { + questionTitleEvent(); + } + }); + + question_question_field.getDocument().addDocumentListener(new DocumentListener() + { + public void insertUpdate(DocumentEvent e) + { + questionTextEvent(); + } + + public void changedUpdate(DocumentEvent e) + { + questionTextEvent(); + } + + public void removeUpdate(DocumentEvent e) + { + questionTextEvent(); + } + }); + + question_citation_field.getDocument().addDocumentListener(new DocumentListener() + { + public void insertUpdate(DocumentEvent e) + { + questionCitationEvent(); + } + + public void changedUpdate(DocumentEvent e) + { + questionCitationEvent(); + } + + public void removeUpdate(DocumentEvent e) + { + questionCitationEvent(); + } + }); + + add(question_split); + + inUpdate = false; + } + + /** + * Updates right side question fields when the selection changes + * + * @param e event generated by selection change. + */ + public void question_list_selectionChanged(ListSelectionEvent e) + { + if (!inUpdate) + { + questionUpdate(); + } + } + + /**** + * fill List with appropriate questions Set other fields to selected + * question + */ + public void fillPanel() + { + //logger.info("fillPanel() called in PromptPanel but questionType was " + questionType + " and curTab was " + egoNet.getFrame().curTab); + if (questionType == egoNet.getFrame().curTab) + { + storageUpdate(); + questionUpdate(); + } + } + + /** + * Called when file changes to load new questions into list + */ + void storageUpdate() + { + inUpdate = true; + + if (questionType == egoNet.getFrame().curTab) + { + ((DefaultListModel) question_list.getModel()).removeAllElements(); + egoNet.getStudy().fillList(questionType, (DefaultListModel)question_list.getModel()); + } + + inUpdate = false; + } + + void questionUpdate() + { + inUpdate = true; + + /** @todo Use List Data Listener? */ + if (questionType.equals(egoNet.getFrame().curTab)) { + int index = question_list.getSelectedIndex(); + if ((question_list.getModel().getSize() > 0) && (index == -1)) + { + index = 0; + } + + question_follows_menu.removeAllItems(); + question_follows_menu.addItem(egoNet.getStudy().getFirstQuestion()); + for (int i = 0; i < question_list.getModel().getSize(); i++) + { + if (i != index) + { + question_follows_menu.addItem(question_list.getModel().getElementAt(i)); + } + } + + question_list.setSelectedIndex(index); + Question q = (Question) question_list.getSelectedValue(); + if (q != null) + { + question_question_field.setText(q.text); + question_citation_field.setText(q.citation); + question_title_field.setText(q.title); + question_follows_menu.setSelectedIndex(index); + + question_question_field.setEditable(true); + question_citation_field.setEditable(true); + question_title_field.setEditable(true); + question_delete_button.setEnabled(true); + question_follows_menu.setEnabled(true); + } + else + { + question_question_field.setText(null); + question_citation_field.setText(null); + question_title_field.setText(null); + + question_question_field.setEditable(false); + question_citation_field.setEditable(false); + question_title_field.setEditable(false); + question_delete_button.setEnabled(false); + question_follows_menu.setEnabled(false); + } + } + + inUpdate = false; + } + + /**** + * Clear all on screen editable fields Generally called when a new survey is + * started + */ + public void clearPanel() + { + inUpdate = true; + ((DefaultListModel) question_list.getModel()).removeAllElements(); + inUpdate = false; + } + + /**** + * Document event handler used to read text fields + * + * @param e Document Event + */ + private void questionTitleEvent() + { + Question q = (Question) question_list.getSelectedValue(); + String s; + + if ((q != null) && !inUpdate) + { + s = question_title_field.getText().trim(); + if ((q.title == null) || (!q.title.equals(s))) + { + q.title = question_title_field.getText().trim(); + egoNet.getStudy().setModified(true); + question_list.repaint(); + } + } + } + + /**** + * Document event handler used to read text fields + * + * @param e Document Event + */ + private void questionTextEvent() + { + Question q = (Question) question_list.getSelectedValue(); + String s; + + if ((q != null) && !inUpdate) + { + s = question_question_field.getText().trim(); + if ((q.text == null) || (!q.text.equals(s))) + { + q.text = question_question_field.getText().trim(); + egoNet.getStudy().setModified(true); + } + } + } + + /**** + * Document event handler used to read text fields + * + * @param e Document Event + */ + private void questionCitationEvent() + { + Question q = (Question) question_list.getSelectedValue(); + String s; + + if ((q != null) && !inUpdate) + { + s = question_citation_field.getText().trim(); + if ((q.citation == null) || (!q.citation.equals(s))) + { + q.citation = question_citation_field.getText().trim(); + egoNet.getStudy().setModified(true); + } + } + } + + void question_new_button_actionPerformed(ActionEvent e) { + + Question q; + try { q = questionType.newInstance(); } catch (Exception ex) { throw new RuntimeException(ex); } + q.title = new String("Untitled Question"); + + try + { + egoNet.getStudy().addQuestion(q); + } + catch (DuplicateQuestionException e1) + { + throw new RuntimeException(e1); + } + + fillPanel(); + question_list.setSelectedValue(q, true); + + question_title_field.requestFocus(); + question_title_field.setSelectionStart(0); + question_title_field.setSelectionEnd(question_title_field.getText().length()); + } + + void question_delete_button_actionPerformed(ActionEvent e) + { + Question q = (Question) question_list.getSelectedValue(); + + if (q != null) + { + int confirm = JOptionPane.showConfirmDialog(egoNet.getFrame(), "Permanently remove this questions?", + "Delete Question", JOptionPane.OK_CANCEL_OPTION); + + if (confirm == JOptionPane.OK_OPTION) + { + egoNet.getStudy().removeQuestion(q); + fillPanel(); + } + } + } + + /** + * Changes order of questions + * + * @param e UI event + */ + void question_follows_menu_actionPerformed(ActionEvent e) + { + if (!inUpdate) + { + Question follows = (Question) question_follows_menu.getSelectedItem(); + Question q = (Question) question_list.getSelectedValue(); + + egoNet.getStudy().moveQuestionAfter(q, follows); + fillPanel(); + } + } +} diff --git a/src/com/endlessloopsoftware/ego/author/QuestionLinkDialog.java b/src/main/java/com/endlessloopsoftware/ego/author/QuestionLinkDialog.java similarity index 97% rename from src/com/endlessloopsoftware/ego/author/QuestionLinkDialog.java rename to src/main/java/com/endlessloopsoftware/ego/author/QuestionLinkDialog.java index 6d6a421..cf74f11 100644 --- a/src/com/endlessloopsoftware/ego/author/QuestionLinkDialog.java +++ b/src/main/java/com/endlessloopsoftware/ego/author/QuestionLinkDialog.java @@ -1,663 +1,663 @@ -/*** - * 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 . - */ -package com.endlessloopsoftware.ego.author; -import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.io.IOException; -import java.util.Observable; -import java.util.Observer; - -import javax.swing.*; -import javax.swing.border.Border; -import javax.swing.border.EtchedBorder; -import javax.swing.border.TitledBorder; -import javax.swing.event.DocumentEvent; -import javax.swing.event.DocumentListener; -import javax.swing.event.ListSelectionEvent; -import javax.swing.event.ListSelectionListener; -import javax.swing.text.PlainDocument; - -import org.egonet.model.question.AlterPairQuestion; -import org.egonet.model.question.AlterPromptQuestion; -import org.egonet.model.question.Question; -import org.egonet.util.CatchingAction; -import org.egonet.util.WholeNumberDocument; -import org.egonet.util.listbuilder.Selection; - -import com.endlessloopsoftware.egonet.Answer; -import com.endlessloopsoftware.egonet.Shared; - -/** - * Generic Panel creation and handling routines for question editing - */ -public class QuestionLinkDialog extends JDialog - implements Observer -{ - private Question baseQuestion; - private Answer linkAnswer = new Answer(new Long(-1)); - - /* Containers */ - private final JSplitPane questionSplit = new JSplitPane(); - private final JList questionList = new JList(); - private final JScrollPane questionListScroll = new JScrollPane(questionList); - private final JPanel answerPanel = new JPanel(); - private final JPanel radioPanel = new JPanel(); - private final JPanel menuPanel = new JPanel(); - private final JPanel textPanel = new JPanel(); - private final JPanel questionPanelLeft = new JPanel(); - private final JPanel questionPanelRight = new RightPanel(); - private final GridBagLayout questionListLayout = new GridBagLayout(); - private final GridBagLayout answerRadioLayout = new GridBagLayout(); - private final GridBagLayout answerTextLayout = new GridBagLayout(); - private final GridBagLayout answerMenuLayout = new GridBagLayout(); - private final GridLayout answerPanelLayout = new GridLayout(); - - /* UI Elements */ - private final Border listBorder; - private final JLabel titleText = new JLabel(); - private final JTextArea questionText = new JTextArea(); - private final JTextArea answerTextField = new NoTabTextArea(); - private final JButton questionButtonOK = new JButton("OK"); - private final JButton questionButtonCancel = new JButton("Cancel"); - private final JButton questionButtonNone = new JButton("No Link"); - private final JLabel textAnswerLabel = new JLabel("Answer: "); - private final JLabel menuAnswerLabel = new JLabel("Answer: "); - private final JLabel radioAnswerLabel = new JLabel("Answer: "); - private final JComboBox answerMenu = new JComboBox(); - private final JCheckBox allAdjacentCheck = new JCheckBox("All Adjacent Selections"); - - private final ButtonGroup answerButtonGroup = new ButtonGroup(); - private ActionListener answerButtonListener; - private final WholeNumberDocument wholeNumberDocument = new WholeNumberDocument(); - private final PlainDocument plainDocument = new PlainDocument(); - - /* Lists */ - private final static int MAX_BUTTONS = 5; - private final JRadioButton[] answerButtons = { new JRadioButton(), new JRadioButton(), - new JRadioButton(), new JRadioButton(), new JRadioButton(), new JRadioButton()}; - - /* Question Iteration Variables */ - private Question question; - - private EgoNet egoNet; - - - /** - * Generates Panel for question editing to insert in file tab window - * @param parent parent frame for referencing composed objects - */ - public QuestionLinkDialog(EgoNet egoNet) throws Exception - { - this.egoNet = egoNet; - listBorder = BorderFactory.createCompoundBorder( - new TitledBorder(new EtchedBorder(EtchedBorder.RAISED,Color.white,new Color(178, 178, 178)), "Questions"), - BorderFactory.createEmptyBorder(10,10,10,10)); - jbInit(); - } - - /** - * Component initialization - * @throws Exception - */ - private void jbInit() - throws Exception - { - /* Overview Layout */ - this.getContentPane().setLayout(new GridLayout()); - - // Configure Split Frame - questionSplit.setMinimumSize(new Dimension(430, 330)); - questionSplit.setPreferredSize(new Dimension(430, 330)); - questionSplit.setResizeWeight(.33); - questionSplit.setDividerLocation(.33); - questionText.setBackground(SystemColor.window); - questionText.setFont(new java.awt.Font("Serif", 0, 16)); - questionText.setLineWrap(true); - questionText.setTabSize(4); - questionText.setWrapStyleWord(true); - questionText.setEditable(false); - - questionSplit.add(questionPanelLeft, JSplitPane.LEFT); - questionSplit.add(questionPanelRight, JSplitPane.RIGHT); - - questionPanelLeft.setLayout(questionListLayout); - questionPanelLeft.setVisible(true); - - titleText.setFont(new java.awt.Font("Lucida Grande Bold", 0, 16)); - - // Configure List - questionListScroll.setBorder(listBorder); - questionListScroll.setMinimumSize(new Dimension(150, 150)); - questionListScroll.setPreferredSize(new Dimension(150, 150)); - questionListScroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); - - questionList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - - // Configure question fields - questionPanelRight.setLayout(new GridBagLayout()); - radioPanel.setLayout(answerRadioLayout); - textPanel.setLayout(answerTextLayout); - menuPanel.setLayout(answerMenuLayout); - - questionText.setBorder(BorderFactory.createLoweredBevelBorder()); - answerMenu.setOpaque(true); - answerPanel.setLayout(answerPanelLayout); - - answerTextField.setFont(new java.awt.Font("SansSerif", 0, 14)); - answerTextField.setMaximumSize(new Dimension(72, 64)); - answerTextField.setMinimumSize(new Dimension(72, 16)); - answerTextField.setPreferredSize(new Dimension(72, 16)); - answerTextField.setLineWrap(true); - answerTextField.setRows(1); - answerTextField.setTabSize(4); - answerTextField.setWrapStyleWord(true); - - /* List Layout */ - questionPanelLeft.add(questionListScroll, new GridBagConstraints(0, 0, 2, 1, 1.0, 1.0 - ,GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 29, 302)); - - /* Question Layout */ - questionPanelRight.add(titleText, new GridBagConstraints(0, 1, 4, 1, 0.0, 0.1 - ,GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(10, 10, 10, 10), 0, 0)); - questionPanelRight.add(questionText, new GridBagConstraints(0, 0, 4, 1, 1.0, 0.3 - ,GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(5, 10, 10, 10), 0, 0)); - - /* Radio Panel Answer Layout */ - radioPanel.add(radioAnswerLabel, new GridBagConstraints(0, 0, 1, 1, 0.3, 0.0 - ,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 5, 0, 5), 0, 0)); - - for (int i = 0; i < MAX_BUTTONS; i++) - { - radioPanel.add(answerButtons[i], new GridBagConstraints(1, i, 1, 1, 0.6, 0.2, - GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); - } - - /* Text Answer Layout */ - textPanel.add(textAnswerLabel, new GridBagConstraints(0, 0, 1, 1, 0.3, 0.0 - ,GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 5, 0, 5), 0, 0)); - textPanel.add(answerTextField, new GridBagConstraints(1, 0, 1, 1, 1.0, 1.0 - ,GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); - - /* Popup Menu Answer Layout */ - menuPanel.add(menuAnswerLabel, new GridBagConstraints(0, 0, 1, 1, 0.3, 0.0 - ,GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 5, 0, 5), 0, 0)); - menuPanel.add(answerMenu, new GridBagConstraints(1, 0, 1, 1, 1.0, 1.0 - ,GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0, 10, 0, 10), 0, 0)); - - /* Misc Button Layout */ - questionPanelRight.add(questionButtonOK, new GridBagConstraints(0, 11, 1, 1, 0.33, 0.1 - ,GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(10, 10, 10, 10), 0, 0)); - questionPanelRight.add(questionButtonNone, new GridBagConstraints(2, 11, 1, 1, 0.33, 0.1 - ,GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(10, 10, 10, 10), 0, 0)); - questionPanelRight.add(questionButtonCancel, new GridBagConstraints(3, 11, 1, 1, 0.33, 0.1 - ,GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(10, 10, 10, 10), 0, 0)); - questionPanelRight.add(answerPanel, new GridBagConstraints(0, 5, 4, 4, 1.0, 0.5 - ,GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(10, 10, 10, 10), 0, 0)); - questionPanelRight.add(allAdjacentCheck, new GridBagConstraints(0, 10, 4, 1, 0.0, 0.0 - ,GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(10, 10, 10, 10), 0, 0)); - - - /* Install event Handlers */ - questionList.getSelectionModel().addListSelectionListener(new ListSelectionListener() { - public void valueChanged(ListSelectionEvent e) { - question_list_selectionChanged(e); }}); - - questionButtonOK.addActionListener(new CatchingAction("questionButtonOK") { - public void safeActionPerformed(ActionEvent e) throws Exception { - questionButtonOK_actionPerformed(e);}}); - - questionButtonNone.addActionListener(new CatchingAction("questionButtonNone") { - public void safeActionPerformed(ActionEvent e) throws Exception { - questionButtonNone_actionPerformed(e);}}); - - questionButtonCancel.addActionListener(new CatchingAction("questionButtonCancel") { - public void safeActionPerformed(ActionEvent e) throws Exception { - questionButtonCancel_actionPerformed(e);}}); - - answerButtonListener = new CatchingAction("answerButtonListener") { - public void safeActionPerformed(ActionEvent e) throws Exception { - questionAnsweredEventHandler(e);}}; - - answerMenu.addActionListener(new CatchingAction("answerMenu") { - public void safeActionPerformed(ActionEvent e) throws Exception { - questionAnsweredEventHandler(e); }}); - - wholeNumberDocument.addDocumentListener(new DocumentListener() { - public void insertUpdate(DocumentEvent e) { answerTextEvent(e); } - public void changedUpdate(DocumentEvent e) { answerTextEvent(e); } - public void removeUpdate(DocumentEvent e) { answerTextEvent(e); }}); - - plainDocument.addDocumentListener(new DocumentListener() { - public void insertUpdate(DocumentEvent e) { answerTextEvent(e); } - public void changedUpdate(DocumentEvent e) { answerTextEvent(e); } - public void removeUpdate(DocumentEvent e) { answerTextEvent(e); }}); - - answerButtonListener = new CatchingAction("") { - public void safeActionPerformed(ActionEvent e) throws Exception { - questionAnsweredEventHandler(e);}}; - - allAdjacentCheck.addActionListener(new CatchingAction(""){ - public void safeActionPerformed(ActionEvent e) throws Exception { - allAdjacentCheck_actionPerformed(e);}}); - - for (int i = 0; i <= MAX_BUTTONS; i++) - { - answerButtonGroup.add(answerButtons[i]); - answerButtons[i].addActionListener(answerButtonListener); - } - - this.getContentPane().add(questionSplit, null); - } - - - void activate(Question q) - { - question = null; - linkAnswer = null; - baseQuestion = q; - - // Question vars - questionList.setModel(new DefaultListModel()); - egoNet.getStudy().fillList((DefaultListModel) questionList.getModel(), q.UniqueId); - - // Set Selection - if (baseQuestion.link.isActive()) - { - Question selected = egoNet.getStudy().getQuestions().getQuestion(baseQuestion.link.getAnswer().questionId); - questionList.setSelectedValue(selected, true); - } - - if ((questionList.getSelectedIndex() == -1) && (questionList.getModel().getSize() > 0)) - { - questionList.setSelectedIndex(0); - } - - /* Prepare starting question and answer, fill with stored values */ - question = (Question) questionList.getSelectedValue(); - - if (question != null) - { - linkAnswer = new Answer(question.UniqueId); - - if (baseQuestion.link.isActive() && (question.UniqueId.equals(baseQuestion.link.getAnswer().questionId))) - { - linkAnswer.setValue(baseQuestion.link.getAnswer().getValue()); - linkAnswer.string = baseQuestion.link.getAnswer().string; - linkAnswer.setAnswered(true); - } - } - - - // Init - fillPanel(); - - this.setTitle("Set Link for Question \"" + q.title + "\""); - this.setSize(550, 500); - - //Center the window - /* Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); - Dimension frameSize = this.getSize(); - if (frameSize.height > screenSize.height) - { - frameSize.height = screenSize.height; - } - if (frameSize.width > screenSize.width) - { - frameSize.width = screenSize.width; - } - this.setLocation((screenSize.width - frameSize.width) / 2, (screenSize.height - frameSize.height) / 2); */ - - this.show(); - } - - - /** - * Updates right side question fields when the selection changes - * @param e event generated by selection change. - */ - public void question_list_selectionChanged(ListSelectionEvent e) - { - if (!e.getValueIsAdjusting() && !questionList.isSelectionEmpty()) - { - question = (Question) questionList.getSelectedValue(); - - if (question != null) - { - linkAnswer = new Answer(question.UniqueId); - - if (baseQuestion.link.isActive() && (question.UniqueId.equals(baseQuestion.link.getAnswer().questionId))) - { - linkAnswer.setValue(baseQuestion.link.getAnswer().getValue()); - linkAnswer.setIndex(baseQuestion.link.getAnswer().getIndex()); - linkAnswer.string = baseQuestion.link.getAnswer().string; - linkAnswer.setAnswered(true); - } - } - - setOKButtonState(); - fillPanel(); - } - } - - /**** - * fill List with appropriate questions - * Set other fields to selected question - */ - public void fillPanel() - { - allAdjacentCheck.setVisible(false); - - if (question != null) - { - titleText.setText(question.title); - - answerPanel.setVisible(false); - answerPanel.removeAll(); - questionText.setText("Please select a question and an answer which will trigger the inclusion of the current question"); - if (question instanceof AlterPromptQuestion) - { - // Should never be here - //assert(false); - } - else if (question.answerType == Shared.AnswerType.TEXT) - { - answerPanel.add(textPanel); - answerPanel.validate(); - answerTextField.setDocument(plainDocument); - answerTextField.requestFocus(); - - if (linkAnswer.isAnswered()) - { - answerTextField.setText(linkAnswer.string); - } - else - { - answerTextField.setText(""); - } - } - else if (question.answerType == Shared.AnswerType.NUMERICAL) - { - answerPanel.add(textPanel); - answerTextField.setDocument(wholeNumberDocument); - answerTextField.requestFocus(); - - if (linkAnswer.isAnswered()) - { - answerTextField.setText(linkAnswer.string); - } - else - { - answerTextField.setText(""); - } - } - else if (question.getSelections().length <= 5) - { - allAdjacentCheck.setVisible(question instanceof AlterPairQuestion); - questionText.setText(question.text); - - answerPanel.add(radioPanel); - - if (linkAnswer.isAnswered()) - { - if (linkAnswer.getValue() == Answer.ALL_ADJACENT) - { - allAdjacentCheck.setSelected(true); - answerButtons[MAX_BUTTONS].setSelected(true); - } - else - { - allAdjacentCheck.setSelected(false); - answerButtons[question.getSelections().length - (linkAnswer.getValue() + 1)].setSelected(true); - } - } - else - { - answerButtons[MAX_BUTTONS].setSelected(true); - } - - for (int i = 0; i < question.getSelections().length; i++) - { - answerButtons[i].setText(question.getSelections()[i].getString()); - answerButtons[i].setVisible(true); - answerButtons[i].setEnabled(linkAnswer.getValue() != Answer.ALL_ADJACENT); - } - - for (int i = question.getSelections().length; i < MAX_BUTTONS; i++) - { - answerButtons[i].setVisible(false); - } - } - else - { - allAdjacentCheck.setVisible(question instanceof AlterPairQuestion); - questionText.setText(question.text); - answerPanel.add(menuPanel); - - answerMenu.removeAllItems(); - - answerMenu.addItem(new Selection("Select an answer")); - for (int i = 0; i < question.getSelections().length; i++) - { - answerMenu.addItem(question.getSelections()[i]); - } - - if (linkAnswer.getValue() == Answer.ALL_ADJACENT) - { - allAdjacentCheck.setSelected(true); - answerMenu.setEnabled(false); - } - else if (linkAnswer.getValue() != Answer.NO_ANSWER) - { - allAdjacentCheck.setSelected(false); - answerMenu.setEnabled(true); - answerMenu.setSelectedIndex(question.getSelections().length - linkAnswer.getValue()); - } - else - { - allAdjacentCheck.setSelected(false); - answerMenu.setEnabled(true); - answerMenu.setSelectedIndex(0); - } - } - - answerPanel.validate(); - answerPanel.setVisible(true); - } - } - - /**** - * Clear all on screen editable fields - * Generally called when a new survey is started - */ - public void clearPanel() - { - ((DefaultListModel) questionList.getModel()).removeAllElements(); - } - - /**** - * Parses answer fields to retrieve answer to question - * @param answer Answer from interview to fill with correct values - */ - void fillAnswer() - { - linkAnswer.string = null; - - if(question.answerType.equals(Shared.AnswerType.NUMERICAL)) { - if (answerTextField.getText().length() > 0) - { - linkAnswer.string = answerTextField.getText(); - linkAnswer.setValue(Integer.valueOf(linkAnswer.string).intValue()); - linkAnswer.setAnswered(true); - } - else - { - linkAnswer.setValue(Answer.NO_ANSWER); - linkAnswer.setAnswered(false); - } - } else if(question.answerType.equals(Shared.AnswerType.TEXT)) { - linkAnswer.string = answerTextField.getText(); - linkAnswer.setValue(linkAnswer.string.length()); - linkAnswer.setAnswered((linkAnswer.getValue() != 0)); - } else if(question.answerType.equals(Shared.AnswerType.INFORMATIONAL)) { - linkAnswer.string = "informational"; - linkAnswer.setValue(1); - linkAnswer.setAnswered(true); - } else if(question.answerType.equals(Shared.AnswerType.CATEGORICAL)) { - - // option/radio buttons - if (question.getSelections().length <= 5) { - if (allAdjacentCheck.isSelected()) { - linkAnswer.setValue(Answer.ALL_ADJACENT); - linkAnswer.string = "All Adjacent"; - linkAnswer.setAnswered(true); - } - else { - int button = selectedButtonIndex(answerButtons); - linkAnswer.setAnswered( (button != MAX_BUTTONS)); - - if (linkAnswer.isAnswered()) - { - linkAnswer.setValue(question.getSelections()[button].getValue()); - linkAnswer.setIndex(question.getSelections()[button].getIndex()); - linkAnswer.string = answerButtons[button].getActionCommand(); - } - else - { - linkAnswer.setValue(Answer.NO_ANSWER); - linkAnswer.setIndex(Answer.NO_ANSWER); - linkAnswer.string = ""; - } - } - } - - // drop down buttons - else { - if (allAdjacentCheck.isSelected()) - { - linkAnswer.setValue(Answer.ALL_ADJACENT); - linkAnswer.string = "All Adjacent"; - linkAnswer.setAnswered(true); - } - else if (answerMenu.getSelectedIndex() > 0) // 0th option is "Select an answer" - { - int selectionIndex = answerMenu.getSelectedIndex() - 1; - linkAnswer.setValue(question.getSelections()[selectionIndex].getValue()); - linkAnswer.string = answerMenu.getSelectedItem().toString(); - linkAnswer.setAnswered((selectionIndex <= question.getSelections().length)); - } - else - { - linkAnswer.setValue(Answer.NO_ANSWER); - linkAnswer.string = ""; - linkAnswer.setAnswered(false); - } - } - } - } - - - void jShowListButton_actionPerformed(ActionEvent e) - { - questionPanelLeft.setVisible(!questionPanelLeft.isVisible()); - questionSplit.setDividerLocation(.33); - questionSplit.repaint(); - } - - void questionButtonNone_actionPerformed(ActionEvent e) throws IOException - { - if (egoNet.getStudy().confirmIncompatibleChange(egoNet.getFrame())) - { - baseQuestion.link.setAnswer(null); - egoNet.getStudy().setModified(true); - egoNet.getStudy().setCompatible(false); - } - - egoNet.getFrame().fillCurrentPanel(); - this.hide(); - } - - void questionButtonCancel_actionPerformed(ActionEvent e) - { - this.hide(); - } - - void questionButtonOK_actionPerformed(ActionEvent e) throws IOException - { - if ((linkAnswer != null) && (linkAnswer.isAnswered()) && egoNet.getStudy().confirmIncompatibleChange(egoNet.getFrame())) - { - baseQuestion.link.setAnswer(linkAnswer); - egoNet.getStudy().setModified(true); - egoNet.getStudy().setCompatible(false); - } - - this.hide(); - egoNet.getFrame().fillCurrentPanel(); - } - - int selectedButtonIndex(JRadioButton[] group) - { - int ri = -1; - - for (int i = 0; i < group.length; i++) - { - if (group[i].isSelected()) - { - ri = i; - break; - } - } - - return (ri); - } - - void setOKButtonState() - { - questionButtonOK.setEnabled((question != null) && linkAnswer.isAnswered()); - } - - - void questionAnsweredEventHandler(ActionEvent e) - { - if (e.getActionCommand() != "Initialization") - { - fillAnswer(); - setOKButtonState(); - } - } - - void answerTextEvent(DocumentEvent e) - { - fillAnswer(); - setOKButtonState(); - } - - public void update(Observable o, Object arg) - { - fillAnswer(); - setOKButtonState(); - } - - void allAdjacentCheck_actionPerformed(ActionEvent e) - { - fillAnswer(); - fillPanel(); - setOKButtonState(); - } +/*** + * 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 . + */ +package com.endlessloopsoftware.ego.author; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.IOException; +import java.util.Observable; +import java.util.Observer; + +import javax.swing.*; +import javax.swing.border.Border; +import javax.swing.border.EtchedBorder; +import javax.swing.border.TitledBorder; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import javax.swing.text.PlainDocument; + +import org.egonet.model.question.AlterPairQuestion; +import org.egonet.model.question.AlterPromptQuestion; +import org.egonet.model.question.Question; +import org.egonet.util.CatchingAction; +import org.egonet.util.WholeNumberDocument; +import org.egonet.util.listbuilder.Selection; + +import com.endlessloopsoftware.egonet.Answer; +import com.endlessloopsoftware.egonet.Shared; + +/** + * Generic Panel creation and handling routines for question editing + */ +public class QuestionLinkDialog extends JDialog + implements Observer +{ + private Question baseQuestion; + private Answer linkAnswer = new Answer(new Long(-1)); + + /* Containers */ + private final JSplitPane questionSplit = new JSplitPane(); + private final JList questionList = new JList(); + private final JScrollPane questionListScroll = new JScrollPane(questionList); + private final JPanel answerPanel = new JPanel(); + private final JPanel radioPanel = new JPanel(); + private final JPanel menuPanel = new JPanel(); + private final JPanel textPanel = new JPanel(); + private final JPanel questionPanelLeft = new JPanel(); + private final JPanel questionPanelRight = new RightPanel(); + private final GridBagLayout questionListLayout = new GridBagLayout(); + private final GridBagLayout answerRadioLayout = new GridBagLayout(); + private final GridBagLayout answerTextLayout = new GridBagLayout(); + private final GridBagLayout answerMenuLayout = new GridBagLayout(); + private final GridLayout answerPanelLayout = new GridLayout(); + + /* UI Elements */ + private final Border listBorder; + private final JLabel titleText = new JLabel(); + private final JTextArea questionText = new JTextArea(); + private final JTextArea answerTextField = new NoTabTextArea(); + private final JButton questionButtonOK = new JButton("OK"); + private final JButton questionButtonCancel = new JButton("Cancel"); + private final JButton questionButtonNone = new JButton("No Link"); + private final JLabel textAnswerLabel = new JLabel("Answer: "); + private final JLabel menuAnswerLabel = new JLabel("Answer: "); + private final JLabel radioAnswerLabel = new JLabel("Answer: "); + private final JComboBox answerMenu = new JComboBox(); + private final JCheckBox allAdjacentCheck = new JCheckBox("All Adjacent Selections"); + + private final ButtonGroup answerButtonGroup = new ButtonGroup(); + private ActionListener answerButtonListener; + private final WholeNumberDocument wholeNumberDocument = new WholeNumberDocument(); + private final PlainDocument plainDocument = new PlainDocument(); + + /* Lists */ + private final static int MAX_BUTTONS = 5; + private final JRadioButton[] answerButtons = { new JRadioButton(), new JRadioButton(), + new JRadioButton(), new JRadioButton(), new JRadioButton(), new JRadioButton()}; + + /* Question Iteration Variables */ + private Question question; + + private EgoNet egoNet; + + + /** + * Generates Panel for question editing to insert in file tab window + * @param parent parent frame for referencing composed objects + */ + public QuestionLinkDialog(EgoNet egoNet) throws Exception + { + this.egoNet = egoNet; + listBorder = BorderFactory.createCompoundBorder( + new TitledBorder(new EtchedBorder(EtchedBorder.RAISED,Color.white,new Color(178, 178, 178)), "Questions"), + BorderFactory.createEmptyBorder(10,10,10,10)); + jbInit(); + } + + /** + * Component initialization + * @throws Exception + */ + private void jbInit() + throws Exception + { + /* Overview Layout */ + this.getContentPane().setLayout(new GridLayout()); + + // Configure Split Frame + questionSplit.setMinimumSize(new Dimension(430, 330)); + questionSplit.setPreferredSize(new Dimension(430, 330)); + questionSplit.setResizeWeight(.33); + questionSplit.setDividerLocation(.33); + questionText.setBackground(SystemColor.window); + questionText.setFont(new java.awt.Font("Serif", 0, 16)); + questionText.setLineWrap(true); + questionText.setTabSize(4); + questionText.setWrapStyleWord(true); + questionText.setEditable(false); + + questionSplit.add(questionPanelLeft, JSplitPane.LEFT); + questionSplit.add(questionPanelRight, JSplitPane.RIGHT); + + questionPanelLeft.setLayout(questionListLayout); + questionPanelLeft.setVisible(true); + + titleText.setFont(new java.awt.Font("Lucida Grande Bold", 0, 16)); + + // Configure List + questionListScroll.setBorder(listBorder); + questionListScroll.setMinimumSize(new Dimension(150, 150)); + questionListScroll.setPreferredSize(new Dimension(150, 150)); + questionListScroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); + + questionList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + + // Configure question fields + questionPanelRight.setLayout(new GridBagLayout()); + radioPanel.setLayout(answerRadioLayout); + textPanel.setLayout(answerTextLayout); + menuPanel.setLayout(answerMenuLayout); + + questionText.setBorder(BorderFactory.createLoweredBevelBorder()); + answerMenu.setOpaque(true); + answerPanel.setLayout(answerPanelLayout); + + answerTextField.setFont(new java.awt.Font("SansSerif", 0, 14)); + answerTextField.setMaximumSize(new Dimension(72, 64)); + answerTextField.setMinimumSize(new Dimension(72, 16)); + answerTextField.setPreferredSize(new Dimension(72, 16)); + answerTextField.setLineWrap(true); + answerTextField.setRows(1); + answerTextField.setTabSize(4); + answerTextField.setWrapStyleWord(true); + + /* List Layout */ + questionPanelLeft.add(questionListScroll, new GridBagConstraints(0, 0, 2, 1, 1.0, 1.0 + ,GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 29, 302)); + + /* Question Layout */ + questionPanelRight.add(titleText, new GridBagConstraints(0, 1, 4, 1, 0.0, 0.1 + ,GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(10, 10, 10, 10), 0, 0)); + questionPanelRight.add(questionText, new GridBagConstraints(0, 0, 4, 1, 1.0, 0.3 + ,GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(5, 10, 10, 10), 0, 0)); + + /* Radio Panel Answer Layout */ + radioPanel.add(radioAnswerLabel, new GridBagConstraints(0, 0, 1, 1, 0.3, 0.0 + ,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 5, 0, 5), 0, 0)); + + for (int i = 0; i < MAX_BUTTONS; i++) + { + radioPanel.add(answerButtons[i], new GridBagConstraints(1, i, 1, 1, 0.6, 0.2, + GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); + } + + /* Text Answer Layout */ + textPanel.add(textAnswerLabel, new GridBagConstraints(0, 0, 1, 1, 0.3, 0.0 + ,GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 5, 0, 5), 0, 0)); + textPanel.add(answerTextField, new GridBagConstraints(1, 0, 1, 1, 1.0, 1.0 + ,GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); + + /* Popup Menu Answer Layout */ + menuPanel.add(menuAnswerLabel, new GridBagConstraints(0, 0, 1, 1, 0.3, 0.0 + ,GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 5, 0, 5), 0, 0)); + menuPanel.add(answerMenu, new GridBagConstraints(1, 0, 1, 1, 1.0, 1.0 + ,GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0, 10, 0, 10), 0, 0)); + + /* Misc Button Layout */ + questionPanelRight.add(questionButtonOK, new GridBagConstraints(0, 11, 1, 1, 0.33, 0.1 + ,GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(10, 10, 10, 10), 0, 0)); + questionPanelRight.add(questionButtonNone, new GridBagConstraints(2, 11, 1, 1, 0.33, 0.1 + ,GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(10, 10, 10, 10), 0, 0)); + questionPanelRight.add(questionButtonCancel, new GridBagConstraints(3, 11, 1, 1, 0.33, 0.1 + ,GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(10, 10, 10, 10), 0, 0)); + questionPanelRight.add(answerPanel, new GridBagConstraints(0, 5, 4, 4, 1.0, 0.5 + ,GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(10, 10, 10, 10), 0, 0)); + questionPanelRight.add(allAdjacentCheck, new GridBagConstraints(0, 10, 4, 1, 0.0, 0.0 + ,GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(10, 10, 10, 10), 0, 0)); + + + /* Install event Handlers */ + questionList.getSelectionModel().addListSelectionListener(new ListSelectionListener() { + public void valueChanged(ListSelectionEvent e) { + question_list_selectionChanged(e); }}); + + questionButtonOK.addActionListener(new CatchingAction("questionButtonOK") { + public void safeActionPerformed(ActionEvent e) throws Exception { + questionButtonOK_actionPerformed(e);}}); + + questionButtonNone.addActionListener(new CatchingAction("questionButtonNone") { + public void safeActionPerformed(ActionEvent e) throws Exception { + questionButtonNone_actionPerformed(e);}}); + + questionButtonCancel.addActionListener(new CatchingAction("questionButtonCancel") { + public void safeActionPerformed(ActionEvent e) throws Exception { + questionButtonCancel_actionPerformed(e);}}); + + answerButtonListener = new CatchingAction("answerButtonListener") { + public void safeActionPerformed(ActionEvent e) throws Exception { + questionAnsweredEventHandler(e);}}; + + answerMenu.addActionListener(new CatchingAction("answerMenu") { + public void safeActionPerformed(ActionEvent e) throws Exception { + questionAnsweredEventHandler(e); }}); + + wholeNumberDocument.addDocumentListener(new DocumentListener() { + public void insertUpdate(DocumentEvent e) { answerTextEvent(e); } + public void changedUpdate(DocumentEvent e) { answerTextEvent(e); } + public void removeUpdate(DocumentEvent e) { answerTextEvent(e); }}); + + plainDocument.addDocumentListener(new DocumentListener() { + public void insertUpdate(DocumentEvent e) { answerTextEvent(e); } + public void changedUpdate(DocumentEvent e) { answerTextEvent(e); } + public void removeUpdate(DocumentEvent e) { answerTextEvent(e); }}); + + answerButtonListener = new CatchingAction("") { + public void safeActionPerformed(ActionEvent e) throws Exception { + questionAnsweredEventHandler(e);}}; + + allAdjacentCheck.addActionListener(new CatchingAction(""){ + public void safeActionPerformed(ActionEvent e) throws Exception { + allAdjacentCheck_actionPerformed(e);}}); + + for (int i = 0; i <= MAX_BUTTONS; i++) + { + answerButtonGroup.add(answerButtons[i]); + answerButtons[i].addActionListener(answerButtonListener); + } + + this.getContentPane().add(questionSplit, null); + } + + + void activate(Question q) + { + question = null; + linkAnswer = null; + baseQuestion = q; + + // Question vars + questionList.setModel(new DefaultListModel()); + egoNet.getStudy().fillList((DefaultListModel) questionList.getModel(), q.UniqueId); + + // Set Selection + if (baseQuestion.link.isActive()) + { + Question selected = egoNet.getStudy().getQuestions().getQuestion(baseQuestion.link.getAnswer().questionId); + questionList.setSelectedValue(selected, true); + } + + if ((questionList.getSelectedIndex() == -1) && (questionList.getModel().getSize() > 0)) + { + questionList.setSelectedIndex(0); + } + + /* Prepare starting question and answer, fill with stored values */ + question = (Question) questionList.getSelectedValue(); + + if (question != null) + { + linkAnswer = new Answer(question.UniqueId); + + if (baseQuestion.link.isActive() && (question.UniqueId.equals(baseQuestion.link.getAnswer().questionId))) + { + linkAnswer.setValue(baseQuestion.link.getAnswer().getValue()); + linkAnswer.string = baseQuestion.link.getAnswer().string; + linkAnswer.setAnswered(true); + } + } + + + // Init + fillPanel(); + + this.setTitle("Set Link for Question \"" + q.title + "\""); + this.setSize(550, 500); + + //Center the window + /* Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); + Dimension frameSize = this.getSize(); + if (frameSize.height > screenSize.height) + { + frameSize.height = screenSize.height; + } + if (frameSize.width > screenSize.width) + { + frameSize.width = screenSize.width; + } + this.setLocation((screenSize.width - frameSize.width) / 2, (screenSize.height - frameSize.height) / 2); */ + + this.show(); + } + + + /** + * Updates right side question fields when the selection changes + * @param e event generated by selection change. + */ + public void question_list_selectionChanged(ListSelectionEvent e) + { + if (!e.getValueIsAdjusting() && !questionList.isSelectionEmpty()) + { + question = (Question) questionList.getSelectedValue(); + + if (question != null) + { + linkAnswer = new Answer(question.UniqueId); + + if (baseQuestion.link.isActive() && (question.UniqueId.equals(baseQuestion.link.getAnswer().questionId))) + { + linkAnswer.setValue(baseQuestion.link.getAnswer().getValue()); + linkAnswer.setIndex(baseQuestion.link.getAnswer().getIndex()); + linkAnswer.string = baseQuestion.link.getAnswer().string; + linkAnswer.setAnswered(true); + } + } + + setOKButtonState(); + fillPanel(); + } + } + + /**** + * fill List with appropriate questions + * Set other fields to selected question + */ + public void fillPanel() + { + allAdjacentCheck.setVisible(false); + + if (question != null) + { + titleText.setText(question.title); + + answerPanel.setVisible(false); + answerPanel.removeAll(); + questionText.setText("Please select a question and an answer which will trigger the inclusion of the current question"); + if (question instanceof AlterPromptQuestion) + { + // Should never be here + //assert(false); + } + else if (question.answerType == Shared.AnswerType.TEXT) + { + answerPanel.add(textPanel); + answerPanel.validate(); + answerTextField.setDocument(plainDocument); + answerTextField.requestFocus(); + + if (linkAnswer.isAnswered()) + { + answerTextField.setText(linkAnswer.string); + } + else + { + answerTextField.setText(""); + } + } + else if (question.answerType == Shared.AnswerType.NUMERICAL) + { + answerPanel.add(textPanel); + answerTextField.setDocument(wholeNumberDocument); + answerTextField.requestFocus(); + + if (linkAnswer.isAnswered()) + { + answerTextField.setText(linkAnswer.string); + } + else + { + answerTextField.setText(""); + } + } + else if (question.getSelections().length <= 5) + { + allAdjacentCheck.setVisible(question instanceof AlterPairQuestion); + questionText.setText(question.text); + + answerPanel.add(radioPanel); + + if (linkAnswer.isAnswered()) + { + if (linkAnswer.getValue() == Answer.ALL_ADJACENT) + { + allAdjacentCheck.setSelected(true); + answerButtons[MAX_BUTTONS].setSelected(true); + } + else + { + allAdjacentCheck.setSelected(false); + answerButtons[question.getSelections().length - (linkAnswer.getValue() + 1)].setSelected(true); + } + } + else + { + answerButtons[MAX_BUTTONS].setSelected(true); + } + + for (int i = 0; i < question.getSelections().length; i++) + { + answerButtons[i].setText(question.getSelections()[i].getString()); + answerButtons[i].setVisible(true); + answerButtons[i].setEnabled(linkAnswer.getValue() != Answer.ALL_ADJACENT); + } + + for (int i = question.getSelections().length; i < MAX_BUTTONS; i++) + { + answerButtons[i].setVisible(false); + } + } + else + { + allAdjacentCheck.setVisible(question instanceof AlterPairQuestion); + questionText.setText(question.text); + answerPanel.add(menuPanel); + + answerMenu.removeAllItems(); + + answerMenu.addItem(new Selection("Select an answer")); + for (int i = 0; i < question.getSelections().length; i++) + { + answerMenu.addItem(question.getSelections()[i]); + } + + if (linkAnswer.getValue() == Answer.ALL_ADJACENT) + { + allAdjacentCheck.setSelected(true); + answerMenu.setEnabled(false); + } + else if (linkAnswer.getValue() != Answer.NO_ANSWER) + { + allAdjacentCheck.setSelected(false); + answerMenu.setEnabled(true); + answerMenu.setSelectedIndex(question.getSelections().length - linkAnswer.getValue()); + } + else + { + allAdjacentCheck.setSelected(false); + answerMenu.setEnabled(true); + answerMenu.setSelectedIndex(0); + } + } + + answerPanel.validate(); + answerPanel.setVisible(true); + } + } + + /**** + * Clear all on screen editable fields + * Generally called when a new survey is started + */ + public void clearPanel() + { + ((DefaultListModel) questionList.getModel()).removeAllElements(); + } + + /**** + * Parses answer fields to retrieve answer to question + * @param answer Answer from interview to fill with correct values + */ + void fillAnswer() + { + linkAnswer.string = null; + + if(question.answerType.equals(Shared.AnswerType.NUMERICAL)) { + if (answerTextField.getText().length() > 0) + { + linkAnswer.string = answerTextField.getText(); + linkAnswer.setValue(Integer.valueOf(linkAnswer.string).intValue()); + linkAnswer.setAnswered(true); + } + else + { + linkAnswer.setValue(Answer.NO_ANSWER); + linkAnswer.setAnswered(false); + } + } else if(question.answerType.equals(Shared.AnswerType.TEXT)) { + linkAnswer.string = answerTextField.getText(); + linkAnswer.setValue(linkAnswer.string.length()); + linkAnswer.setAnswered((linkAnswer.getValue() != 0)); + } else if(question.answerType.equals(Shared.AnswerType.INFORMATIONAL)) { + linkAnswer.string = "informational"; + linkAnswer.setValue(1); + linkAnswer.setAnswered(true); + } else if(question.answerType.equals(Shared.AnswerType.CATEGORICAL)) { + + // option/radio buttons + if (question.getSelections().length <= 5) { + if (allAdjacentCheck.isSelected()) { + linkAnswer.setValue(Answer.ALL_ADJACENT); + linkAnswer.string = "All Adjacent"; + linkAnswer.setAnswered(true); + } + else { + int button = selectedButtonIndex(answerButtons); + linkAnswer.setAnswered( (button != MAX_BUTTONS)); + + if (linkAnswer.isAnswered()) + { + linkAnswer.setValue(question.getSelections()[button].getValue()); + linkAnswer.setIndex(question.getSelections()[button].getIndex()); + linkAnswer.string = answerButtons[button].getActionCommand(); + } + else + { + linkAnswer.setValue(Answer.NO_ANSWER); + linkAnswer.setIndex(Answer.NO_ANSWER); + linkAnswer.string = ""; + } + } + } + + // drop down buttons + else { + if (allAdjacentCheck.isSelected()) + { + linkAnswer.setValue(Answer.ALL_ADJACENT); + linkAnswer.string = "All Adjacent"; + linkAnswer.setAnswered(true); + } + else if (answerMenu.getSelectedIndex() > 0) // 0th option is "Select an answer" + { + int selectionIndex = answerMenu.getSelectedIndex() - 1; + linkAnswer.setValue(question.getSelections()[selectionIndex].getValue()); + linkAnswer.string = answerMenu.getSelectedItem().toString(); + linkAnswer.setAnswered((selectionIndex <= question.getSelections().length)); + } + else + { + linkAnswer.setValue(Answer.NO_ANSWER); + linkAnswer.string = ""; + linkAnswer.setAnswered(false); + } + } + } + } + + + void jShowListButton_actionPerformed(ActionEvent e) + { + questionPanelLeft.setVisible(!questionPanelLeft.isVisible()); + questionSplit.setDividerLocation(.33); + questionSplit.repaint(); + } + + void questionButtonNone_actionPerformed(ActionEvent e) throws IOException + { + if (egoNet.getStudy().confirmIncompatibleChange(egoNet.getFrame())) + { + baseQuestion.link.setAnswer(null); + egoNet.getStudy().setModified(true); + egoNet.getStudy().setCompatible(false); + } + + egoNet.getFrame().fillCurrentPanel(); + this.hide(); + } + + void questionButtonCancel_actionPerformed(ActionEvent e) + { + this.hide(); + } + + void questionButtonOK_actionPerformed(ActionEvent e) throws IOException + { + if ((linkAnswer != null) && (linkAnswer.isAnswered()) && egoNet.getStudy().confirmIncompatibleChange(egoNet.getFrame())) + { + baseQuestion.link.setAnswer(linkAnswer); + egoNet.getStudy().setModified(true); + egoNet.getStudy().setCompatible(false); + } + + this.hide(); + egoNet.getFrame().fillCurrentPanel(); + } + + int selectedButtonIndex(JRadioButton[] group) + { + int ri = -1; + + for (int i = 0; i < group.length; i++) + { + if (group[i].isSelected()) + { + ri = i; + break; + } + } + + return (ri); + } + + void setOKButtonState() + { + questionButtonOK.setEnabled((question != null) && linkAnswer.isAnswered()); + } + + + void questionAnsweredEventHandler(ActionEvent e) + { + if (e.getActionCommand() != "Initialization") + { + fillAnswer(); + setOKButtonState(); + } + } + + void answerTextEvent(DocumentEvent e) + { + fillAnswer(); + setOKButtonState(); + } + + public void update(Observable o, Object arg) + { + fillAnswer(); + setOKButtonState(); + } + + void allAdjacentCheck_actionPerformed(ActionEvent e) + { + fillAnswer(); + fillPanel(); + setOKButtonState(); + } } \ No newline at end of file diff --git a/src/com/endlessloopsoftware/ego/author/RightPanel.java b/src/main/java/com/endlessloopsoftware/ego/author/RightPanel.java similarity index 96% rename from src/com/endlessloopsoftware/ego/author/RightPanel.java rename to src/main/java/com/endlessloopsoftware/ego/author/RightPanel.java index 61cff2e..dae4dfa 100644 --- a/src/com/endlessloopsoftware/ego/author/RightPanel.java +++ b/src/main/java/com/endlessloopsoftware/ego/author/RightPanel.java @@ -1,31 +1,31 @@ -/*** - * 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 . - */ -package com.endlessloopsoftware.ego.author; -import javax.swing.JPanel; - -/** - * Extends JPanel class to keep focus in right panel of split question panel - */ -public class RightPanel extends JPanel -{ - public boolean isFocusCycleRoot() - { - return (true); - } -} +/*** + * 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 . + */ +package com.endlessloopsoftware.ego.author; +import javax.swing.JPanel; + +/** + * Extends JPanel class to keep focus in right panel of split question panel + */ +public class RightPanel extends JPanel +{ + public boolean isFocusCycleRoot() + { + return (true); + } +} diff --git a/src/com/endlessloopsoftware/ego/author/SelectStudyDialog.gui_xml b/src/main/java/com/endlessloopsoftware/ego/author/SelectStudyDialog.gui_xml similarity index 100% rename from src/com/endlessloopsoftware/ego/author/SelectStudyDialog.gui_xml rename to src/main/java/com/endlessloopsoftware/ego/author/SelectStudyDialog.gui_xml diff --git a/src/com/endlessloopsoftware/ego/author/StoreSurvey.gui_xml b/src/main/java/com/endlessloopsoftware/ego/author/StoreSurvey.gui_xml similarity index 100% rename from src/com/endlessloopsoftware/ego/author/StoreSurvey.gui_xml rename to src/main/java/com/endlessloopsoftware/ego/author/StoreSurvey.gui_xml diff --git a/src/com/endlessloopsoftware/ego/author/StudyPanel.java b/src/main/java/com/endlessloopsoftware/ego/author/StudyPanel.java similarity index 100% rename from src/com/endlessloopsoftware/ego/author/StudyPanel.java rename to src/main/java/com/endlessloopsoftware/ego/author/StudyPanel.java diff --git a/src/com/endlessloopsoftware/ego/client/ClientFrame.java b/src/main/java/com/endlessloopsoftware/ego/client/ClientFrame.java similarity index 100% rename from src/com/endlessloopsoftware/ego/client/ClientFrame.java rename to src/main/java/com/endlessloopsoftware/ego/client/ClientFrame.java diff --git a/src/com/endlessloopsoftware/ego/client/ClientPanel.java b/src/main/java/com/endlessloopsoftware/ego/client/ClientPanel.java similarity index 100% rename from src/com/endlessloopsoftware/ego/client/ClientPanel.java rename to src/main/java/com/endlessloopsoftware/ego/client/ClientPanel.java diff --git a/src/com/endlessloopsoftware/ego/client/ClientQuestionPanel.java b/src/main/java/com/endlessloopsoftware/ego/client/ClientQuestionPanel.java similarity index 100% rename from src/com/endlessloopsoftware/ego/client/ClientQuestionPanel.java rename to src/main/java/com/endlessloopsoftware/ego/client/ClientQuestionPanel.java diff --git a/src/com/endlessloopsoftware/ego/client/EgoClient.java b/src/main/java/com/endlessloopsoftware/ego/client/EgoClient.java similarity index 96% rename from src/com/endlessloopsoftware/ego/client/EgoClient.java rename to src/main/java/com/endlessloopsoftware/ego/client/EgoClient.java index 65dcfa4..7689d80 100644 --- a/src/com/endlessloopsoftware/ego/client/EgoClient.java +++ b/src/main/java/com/endlessloopsoftware/ego/client/EgoClient.java @@ -1,90 +1,90 @@ -/*** - * 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 . - */ -package com.endlessloopsoftware.ego.client; - -import org.egonet.gui.EgoStore; -import org.egonet.util.EgonetAnalytics; - -import com.endlessloopsoftware.egonet.Interview; -import com.endlessloopsoftware.egonet.Study; - -/** - * ONLY USE THIS CLASS IN INTERVIEWING PART OF THE TOOL Session object - * representing the session of the user and the EgoNet software - * - * - * @author peters - * @author martins - * - */ -public class EgoClient { - private EgoStore storage; - private ClientFrame frame; - private int uiPath; - - // Construct the application - public EgoClient() { - EgonetAnalytics.track("interviewing client startup"); // track! - - storage = new EgoStore(null); - frame = new ClientFrame(this); - - frame.gotoSourceSelectPanel(); - frame.setVisible(true); - - } - - // Main method - public static void main(String[] args) throws Exception { - // new Console(); - new EgoClient().getFrame().setVisible(true); - } - - public Study getStudy() { - return storage.getStudy(); - } - - public EgoStore getStorage() { - return storage; - } - - public void setStorage(EgoStore storage) { - this.storage = storage; - } - - public ClientFrame getFrame() { - return frame; - } - - public void setFrame(ClientFrame frame) { - this.frame = frame; - } - - public Interview getInterview() { - return storage.getInterview(); - } - - public int getUiPath() { - return uiPath; - } - - public void setUiPath(int uiPath) { - this.uiPath = uiPath; - } +/*** + * 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 . + */ +package com.endlessloopsoftware.ego.client; + +import org.egonet.gui.EgoStore; +import org.egonet.util.EgonetAnalytics; + +import com.endlessloopsoftware.egonet.Interview; +import com.endlessloopsoftware.egonet.Study; + +/** + * ONLY USE THIS CLASS IN INTERVIEWING PART OF THE TOOL Session object + * representing the session of the user and the EgoNet software + * + * + * @author peters + * @author martins + * + */ +public class EgoClient { + private EgoStore storage; + private ClientFrame frame; + private int uiPath; + + // Construct the application + public EgoClient() { + EgonetAnalytics.track("interviewing client startup"); // track! + + storage = new EgoStore(null); + frame = new ClientFrame(this); + + frame.gotoSourceSelectPanel(); + frame.setVisible(true); + + } + + // Main method + public static void main(String[] args) throws Exception { + // new Console(); + new EgoClient().getFrame().setVisible(true); + } + + public Study getStudy() { + return storage.getStudy(); + } + + public EgoStore getStorage() { + return storage; + } + + public void setStorage(EgoStore storage) { + this.storage = storage; + } + + public ClientFrame getFrame() { + return frame; + } + + public void setFrame(ClientFrame frame) { + this.frame = frame; + } + + public Interview getInterview() { + return storage.getInterview(); + } + + public int getUiPath() { + return uiPath; + } + + public void setUiPath(int uiPath) { + this.uiPath = uiPath; + } } \ No newline at end of file diff --git a/src/com/endlessloopsoftware/ego/client/StartPanel.java b/src/main/java/com/endlessloopsoftware/ego/client/StartPanel.java similarity index 96% rename from src/com/endlessloopsoftware/ego/client/StartPanel.java rename to src/main/java/com/endlessloopsoftware/ego/client/StartPanel.java index 1493ae9..cea1525 100644 --- a/src/com/endlessloopsoftware/ego/client/StartPanel.java +++ b/src/main/java/com/endlessloopsoftware/ego/client/StartPanel.java @@ -1,282 +1,282 @@ -/*** - * 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 . - */ -package com.endlessloopsoftware.ego.client; - -import java.awt.GridBagConstraints; -import java.awt.GridBagLayout; -import java.awt.Insets; -import java.awt.event.ActionEvent; - -import javax.swing.BorderFactory; -import javax.swing.JButton; -import javax.swing.JFileChooser; -import javax.swing.JLabel; -import javax.swing.JOptionPane; -import javax.swing.JPanel; -import javax.swing.SwingConstants; -import org.egonet.exceptions.CorruptedInterviewException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.File; -import java.io.IOException; - - - -public class StartPanel extends JPanel -{ - final private static Logger logger = LoggerFactory.getLogger(StartPanel.class); - - private final GridBagLayout gridBagLayout1 = new GridBagLayout(); - private final JLabel titleLabel = new JLabel("Create a new interview file"); - - private final JButton startBrandNewInterviewButton = new JButton("Save or Continue a Respondent Interview (New Respondent)"); - private final JButton startLongitudinalInterviewButton = new JButton("Save New Longitudinal Interview (Existing Respondent)"); - - private final EgoClient egoClient; - - public StartPanel(EgoClient egoClient) throws Exception - { - this.egoClient = egoClient; - logger.info("Create of start panel using " + egoClient + " - " + egoClient.getStudy().getAlterNameModel()); - - jbInit(); - } - - private void jbInit() throws Exception - { - this.setLayout(gridBagLayout1); - - titleLabel.setFont(new java.awt.Font("Lucida Grande", 1, 16)); - titleLabel.setHorizontalAlignment(SwingConstants.CENTER); - titleLabel.setHorizontalTextPosition(SwingConstants.CENTER); - - this.setBorder(BorderFactory.createEtchedBorder()); - this.add( - titleLabel, - new GridBagConstraints( - 0, - 0, - 2, - 1, - 1.0, - 0.2, - GridBagConstraints.CENTER, - GridBagConstraints.HORIZONTAL, - new Insets(0, 0, 0, 0), - 0, - 0)); - - logger.info(egoClient.getStudy().getAlterNameModel().toString()); - logger.info(egoClient.getStudy().getStudyName()); - - this.add( - startBrandNewInterviewButton, - new GridBagConstraints( - 1, - 2, - 1, - 1, - 0.0, - 0.0, - GridBagConstraints.CENTER, - GridBagConstraints.HORIZONTAL, - new Insets(10, 10, 10, 10), - 0, - 6)); - this.add( - startLongitudinalInterviewButton, - new GridBagConstraints( - 0, - 3, - 2, - 1, - 0.0, - 0.0, - GridBagConstraints.CENTER, - GridBagConstraints.HORIZONTAL, - new Insets(10, 10, 10, 10), - 0, - 0)); - - startBrandNewInterviewButton.addActionListener(new java.awt.event.ActionListener() - { - public void actionPerformed(ActionEvent e) - { - startBrandNewInterviewButton_actionPerformed(e); - } - }); - - - startLongitudinalInterviewButton.addActionListener(new java.awt.event.ActionListener() - { - public void actionPerformed(ActionEvent e) - { - startLongitudinalInterviewButton_actionPerformed(e); - } - - }); - } - - private void startLongitudinalInterviewButton_actionPerformed(ActionEvent e) { - boolean success = false; - - /* Logic */ - try - { - - File studyFile = egoClient.getStorage().getStudyFile(); - File studyPath = studyFile.getParentFile(); - - final JFileChooser fcOpen = new JFileChooser(); - - final JFileChooser fcSave = new JFileChooser() { - - // this chooser needs to understand the "overwrite?" confirmation - - @Override - public void approveSelection(){ - File f = getSelectedFile(); - if(f.exists() && getDialogType() == SAVE_DIALOG){ - int result = JOptionPane.showConfirmDialog(this,"The file exists, overwrite?","Existing file",JOptionPane.YES_NO_CANCEL_OPTION); - switch(result){ - case JOptionPane.YES_OPTION: - super.approveSelection(); - return; - case JOptionPane.NO_OPTION: - return; - case JOptionPane.CLOSED_OPTION: - return; - case JOptionPane.CANCEL_OPTION: - cancelSelection(); - return; - } - } - super.approveSelection(); - } - - }; - - fcOpen.setCurrentDirectory(new File(studyPath.getAbsolutePath()+"/Interviews/")); - fcSave.setCurrentDirectory(new File(studyPath.getAbsolutePath()+"/Interviews/")); - - int rOpen = fcOpen.showOpenDialog(this); - if(rOpen != JFileChooser.APPROVE_OPTION) - return; - - int rSave = fcSave.showSaveDialog(this); - if(rSave != JFileChooser.APPROVE_OPTION) - return; - - // don't warn about incomplete? - // copy extant interview - - - success = egoClient.getStorage().saveLongitudinalFile(fcOpen.getSelectedFile(), fcSave.getSelectedFile()); - } - catch (IOException ex) - { - success = false; - } catch (CorruptedInterviewException ex) { - JOptionPane.showMessageDialog(this, "The original interview you selected is corrupted. Will not proceed."); - success = false; - logger.info("Corrupted interview while trying to start a longitudinal study", ex); - } - - /* UI */ - if (success) - { - egoClient.getFrame().gotoClientQuestionPanel(); - } - else - { - egoClient.getFrame().gotoSourceSelectPanel(); - } - } - - void startBrandNewInterviewButton_actionPerformed(ActionEvent e) - { - boolean success = false; - - /* Logic */ - try - { - - File studyFile = egoClient.getStorage().getStudyFile(); - File studyPath = studyFile.getParentFile(); - - final JFileChooser fc = new JFileChooser() { - - // this chooser needs to understand the "overwrite?" confirmation - - @Override - public void approveSelection(){ - File f = getSelectedFile(); - if(f.exists() && getDialogType() == SAVE_DIALOG){ - int result = JOptionPane.showConfirmDialog(this,"The file exists, are you sure you want to continue with an existing interview?","Existing file",JOptionPane.YES_NO_CANCEL_OPTION); - switch(result){ - case JOptionPane.YES_OPTION: - super.approveSelection(); - return; - case JOptionPane.NO_OPTION: - return; - case JOptionPane.CLOSED_OPTION: - return; - case JOptionPane.CANCEL_OPTION: - cancelSelection(); - return; - } - } - super.approveSelection(); - } - - }; - fc.setCurrentDirectory(new File(studyPath.getAbsolutePath()+"/Interviews/")); - - int result = fc.showSaveDialog(this); - if(result != JFileChooser.APPROVE_OPTION) - return; - - File fSelected = fc.getSelectedFile(); - if(fSelected.exists() && fSelected.canRead()) - success = egoClient.getStorage().continueInterview(fSelected); - else - success = egoClient.getStorage().saveInterview(fSelected); - } - catch (IOException ex) - { - success = false; - } catch (CorruptedInterviewException ex) { - JOptionPane.showMessageDialog(this, "The interview you selected is corrupted. Will not proceed."); - success = false; - logger.info("Corrupted interview while trying to continue a brand new interview", ex); - } - - /* UI */ - if (success) - { - egoClient.getFrame().gotoClientQuestionPanel(); - } - else - { - egoClient.getFrame().gotoSourceSelectPanel(); - } - } - +/*** + * 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 . + */ +package com.endlessloopsoftware.ego.client; + +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.awt.event.ActionEvent; + +import javax.swing.BorderFactory; +import javax.swing.JButton; +import javax.swing.JFileChooser; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.SwingConstants; +import org.egonet.exceptions.CorruptedInterviewException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.IOException; + + + +public class StartPanel extends JPanel +{ + final private static Logger logger = LoggerFactory.getLogger(StartPanel.class); + + private final GridBagLayout gridBagLayout1 = new GridBagLayout(); + private final JLabel titleLabel = new JLabel("Create a new interview file"); + + private final JButton startBrandNewInterviewButton = new JButton("Save or Continue a Respondent Interview (New Respondent)"); + private final JButton startLongitudinalInterviewButton = new JButton("Save New Longitudinal Interview (Existing Respondent)"); + + private final EgoClient egoClient; + + public StartPanel(EgoClient egoClient) throws Exception + { + this.egoClient = egoClient; + logger.info("Create of start panel using " + egoClient + " - " + egoClient.getStudy().getAlterNameModel()); + + jbInit(); + } + + private void jbInit() throws Exception + { + this.setLayout(gridBagLayout1); + + titleLabel.setFont(new java.awt.Font("Lucida Grande", 1, 16)); + titleLabel.setHorizontalAlignment(SwingConstants.CENTER); + titleLabel.setHorizontalTextPosition(SwingConstants.CENTER); + + this.setBorder(BorderFactory.createEtchedBorder()); + this.add( + titleLabel, + new GridBagConstraints( + 0, + 0, + 2, + 1, + 1.0, + 0.2, + GridBagConstraints.CENTER, + GridBagConstraints.HORIZONTAL, + new Insets(0, 0, 0, 0), + 0, + 0)); + + logger.info(egoClient.getStudy().getAlterNameModel().toString()); + logger.info(egoClient.getStudy().getStudyName()); + + this.add( + startBrandNewInterviewButton, + new GridBagConstraints( + 1, + 2, + 1, + 1, + 0.0, + 0.0, + GridBagConstraints.CENTER, + GridBagConstraints.HORIZONTAL, + new Insets(10, 10, 10, 10), + 0, + 6)); + this.add( + startLongitudinalInterviewButton, + new GridBagConstraints( + 0, + 3, + 2, + 1, + 0.0, + 0.0, + GridBagConstraints.CENTER, + GridBagConstraints.HORIZONTAL, + new Insets(10, 10, 10, 10), + 0, + 0)); + + startBrandNewInterviewButton.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(ActionEvent e) + { + startBrandNewInterviewButton_actionPerformed(e); + } + }); + + + startLongitudinalInterviewButton.addActionListener(new java.awt.event.ActionListener() + { + public void actionPerformed(ActionEvent e) + { + startLongitudinalInterviewButton_actionPerformed(e); + } + + }); + } + + private void startLongitudinalInterviewButton_actionPerformed(ActionEvent e) { + boolean success = false; + + /* Logic */ + try + { + + File studyFile = egoClient.getStorage().getStudyFile(); + File studyPath = studyFile.getParentFile(); + + final JFileChooser fcOpen = new JFileChooser(); + + final JFileChooser fcSave = new JFileChooser() { + + // this chooser needs to understand the "overwrite?" confirmation + + @Override + public void approveSelection(){ + File f = getSelectedFile(); + if(f.exists() && getDialogType() == SAVE_DIALOG){ + int result = JOptionPane.showConfirmDialog(this,"The file exists, overwrite?","Existing file",JOptionPane.YES_NO_CANCEL_OPTION); + switch(result){ + case JOptionPane.YES_OPTION: + super.approveSelection(); + return; + case JOptionPane.NO_OPTION: + return; + case JOptionPane.CLOSED_OPTION: + return; + case JOptionPane.CANCEL_OPTION: + cancelSelection(); + return; + } + } + super.approveSelection(); + } + + }; + + fcOpen.setCurrentDirectory(new File(studyPath.getAbsolutePath()+"/Interviews/")); + fcSave.setCurrentDirectory(new File(studyPath.getAbsolutePath()+"/Interviews/")); + + int rOpen = fcOpen.showOpenDialog(this); + if(rOpen != JFileChooser.APPROVE_OPTION) + return; + + int rSave = fcSave.showSaveDialog(this); + if(rSave != JFileChooser.APPROVE_OPTION) + return; + + // don't warn about incomplete? + // copy extant interview + + + success = egoClient.getStorage().saveLongitudinalFile(fcOpen.getSelectedFile(), fcSave.getSelectedFile()); + } + catch (IOException ex) + { + success = false; + } catch (CorruptedInterviewException ex) { + JOptionPane.showMessageDialog(this, "The original interview you selected is corrupted. Will not proceed."); + success = false; + logger.info("Corrupted interview while trying to start a longitudinal study", ex); + } + + /* UI */ + if (success) + { + egoClient.getFrame().gotoClientQuestionPanel(); + } + else + { + egoClient.getFrame().gotoSourceSelectPanel(); + } + } + + void startBrandNewInterviewButton_actionPerformed(ActionEvent e) + { + boolean success = false; + + /* Logic */ + try + { + + File studyFile = egoClient.getStorage().getStudyFile(); + File studyPath = studyFile.getParentFile(); + + final JFileChooser fc = new JFileChooser() { + + // this chooser needs to understand the "overwrite?" confirmation + + @Override + public void approveSelection(){ + File f = getSelectedFile(); + if(f.exists() && getDialogType() == SAVE_DIALOG){ + int result = JOptionPane.showConfirmDialog(this,"The file exists, are you sure you want to continue with an existing interview?","Existing file",JOptionPane.YES_NO_CANCEL_OPTION); + switch(result){ + case JOptionPane.YES_OPTION: + super.approveSelection(); + return; + case JOptionPane.NO_OPTION: + return; + case JOptionPane.CLOSED_OPTION: + return; + case JOptionPane.CANCEL_OPTION: + cancelSelection(); + return; + } + } + super.approveSelection(); + } + + }; + fc.setCurrentDirectory(new File(studyPath.getAbsolutePath()+"/Interviews/")); + + int result = fc.showSaveDialog(this); + if(result != JFileChooser.APPROVE_OPTION) + return; + + File fSelected = fc.getSelectedFile(); + if(fSelected.exists() && fSelected.canRead()) + success = egoClient.getStorage().continueInterview(fSelected); + else + success = egoClient.getStorage().saveInterview(fSelected); + } + catch (IOException ex) + { + success = false; + } catch (CorruptedInterviewException ex) { + JOptionPane.showMessageDialog(this, "The interview you selected is corrupted. Will not proceed."); + success = false; + logger.info("Corrupted interview while trying to continue a brand new interview", ex); + } + + /* UI */ + if (success) + { + egoClient.getFrame().gotoClientQuestionPanel(); + } + else + { + egoClient.getFrame().gotoSourceSelectPanel(); + } + } + } \ No newline at end of file diff --git a/src/com/endlessloopsoftware/ego/client/SummaryPanel.java b/src/main/java/com/endlessloopsoftware/ego/client/SummaryPanel.java similarity index 100% rename from src/com/endlessloopsoftware/ego/client/SummaryPanel.java rename to src/main/java/com/endlessloopsoftware/ego/client/SummaryPanel.java diff --git a/src/com/endlessloopsoftware/ego/client/ViewInterviewPanel.java b/src/main/java/com/endlessloopsoftware/ego/client/ViewInterviewPanel.java similarity index 96% rename from src/com/endlessloopsoftware/ego/client/ViewInterviewPanel.java rename to src/main/java/com/endlessloopsoftware/ego/client/ViewInterviewPanel.java index 36a8c25..85a4f0c 100644 --- a/src/com/endlessloopsoftware/ego/client/ViewInterviewPanel.java +++ b/src/main/java/com/endlessloopsoftware/ego/client/ViewInterviewPanel.java @@ -1,51 +1,51 @@ -/*** - * 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 . - */ -package com.endlessloopsoftware.ego.client; - -import javax.swing.JTabbedPane; -import javax.swing.ProgressMonitor; - -import java.util.*; - -import com.endlessloopsoftware.ego.client.statistics.StatisticsFrame; -import com.endlessloopsoftware.ego.client.graph.*; - -public class ViewInterviewPanel - extends JTabbedPane -{ - GraphPanel graphPanel; - public ViewInterviewPanel(EgoClient egoClient, ProgressMonitor progress) - { - super(); - progress.setProgress(10); - this.addTab("Interview", new ClientQuestionPanel(egoClient)); - progress.setProgress(15); - - if(egoClient.getInterview().isComplete()) { - this.addTab("Statistics", new StatisticsFrame(egoClient)); - graphPanel = new GraphPanel(egoClient); - this.addTab("Graph", graphPanel); - } - progress.setProgress(70); - } - - public Iterator settingsIterator() { - return graphPanel.getSettingsIterator(); - } +/*** + * 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 . + */ +package com.endlessloopsoftware.ego.client; + +import javax.swing.JTabbedPane; +import javax.swing.ProgressMonitor; + +import java.util.*; + +import com.endlessloopsoftware.ego.client.statistics.StatisticsFrame; +import com.endlessloopsoftware.ego.client.graph.*; + +public class ViewInterviewPanel + extends JTabbedPane +{ + GraphPanel graphPanel; + public ViewInterviewPanel(EgoClient egoClient, ProgressMonitor progress) + { + super(); + progress.setProgress(10); + this.addTab("Interview", new ClientQuestionPanel(egoClient)); + progress.setProgress(15); + + if(egoClient.getInterview().isComplete()) { + this.addTab("Statistics", new StatisticsFrame(egoClient)); + graphPanel = new GraphPanel(egoClient); + this.addTab("Graph", graphPanel); + } + progress.setProgress(70); + } + + public Iterator settingsIterator() { + return graphPanel.getSettingsIterator(); + } } \ No newline at end of file diff --git a/src/com/endlessloopsoftware/ego/client/WorkingDialog.java b/src/main/java/com/endlessloopsoftware/ego/client/WorkingDialog.java similarity index 96% rename from src/com/endlessloopsoftware/ego/client/WorkingDialog.java rename to src/main/java/com/endlessloopsoftware/ego/client/WorkingDialog.java index 3c30c5e..de8d2d2 100644 --- a/src/com/endlessloopsoftware/ego/client/WorkingDialog.java +++ b/src/main/java/com/endlessloopsoftware/ego/client/WorkingDialog.java @@ -1,54 +1,54 @@ -/*** - * 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 . - */ -package com.endlessloopsoftware.ego.client; - -import java.awt.BorderLayout; -import javax.swing.JDialog; -import javax.swing.JFrame; -import javax.swing.JLabel; -import javax.swing.JPanel; - -public class WorkingDialog extends JDialog -{ - private JPanel panel1 = new JPanel(); - private BorderLayout borderLayout1 = new BorderLayout(); - private JLabel jLabel1 = new JLabel(); - - public WorkingDialog(JFrame frame, String title, boolean modal) - { - super(frame, title, modal); - jbInit(); - pack(); - } - - public WorkingDialog() - { - this(null, "", false); - } - - private void jbInit() - { - panel1.setLayout(borderLayout1); - jLabel1.setFont(new java.awt.Font("Dialog", 1, 16)); - jLabel1.setToolTipText(""); - jLabel1.setText("Working..."); - getContentPane().add(panel1); - panel1.add(jLabel1, BorderLayout.CENTER); - } +/*** + * 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 . + */ +package com.endlessloopsoftware.ego.client; + +import java.awt.BorderLayout; +import javax.swing.JDialog; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; + +public class WorkingDialog extends JDialog +{ + private JPanel panel1 = new JPanel(); + private BorderLayout borderLayout1 = new BorderLayout(); + private JLabel jLabel1 = new JLabel(); + + public WorkingDialog(JFrame frame, String title, boolean modal) + { + super(frame, title, modal); + jbInit(); + pack(); + } + + public WorkingDialog() + { + this(null, "", false); + } + + private void jbInit() + { + panel1.setLayout(borderLayout1); + jLabel1.setFont(new java.awt.Font("Dialog", 1, 16)); + jLabel1.setToolTipText(""); + jLabel1.setText("Working..."); + getContentPane().add(panel1); + panel1.add(jLabel1, BorderLayout.CENTER); + } } \ No newline at end of file diff --git a/src/com/endlessloopsoftware/ego/client/graph/ELSFRLayout2.java b/src/main/java/com/endlessloopsoftware/ego/client/graph/ELSFRLayout2.java similarity index 100% rename from src/com/endlessloopsoftware/ego/client/graph/ELSFRLayout2.java rename to src/main/java/com/endlessloopsoftware/ego/client/graph/ELSFRLayout2.java diff --git a/src/com/endlessloopsoftware/ego/client/graph/Edge.java b/src/main/java/com/endlessloopsoftware/ego/client/graph/Edge.java similarity index 95% rename from src/com/endlessloopsoftware/ego/client/graph/Edge.java rename to src/main/java/com/endlessloopsoftware/ego/client/graph/Edge.java index e47548a..64525a9 100644 --- a/src/com/endlessloopsoftware/ego/client/graph/Edge.java +++ b/src/main/java/com/endlessloopsoftware/ego/client/graph/Edge.java @@ -1,67 +1,67 @@ -package com.endlessloopsoftware.ego.client.graph; - -import edu.uci.ics.jung.graph.util.Pair; - -public class Edge { - - public final Pair pair; - private String notes; - - public Edge(String a, String b) { - super(); - this.pair = buildEdge(a,b); - this.notes = ""; - } - - public String getNotes() { - return notes; - } - - public void setNotes(String notes) { - this.notes = notes; - } - - public Edge(Vertex a, Vertex b) { - super(); - this.pair = buildEdge(a.name,b.name); - this.notes = ""; - } - - // keep them ordered for edge identity - public static Pair buildEdge(String a, String b) { - return a.compareTo(b) > 0 ? new Pair(b,a) : new Pair(a,b); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((pair == null) ? 0 : pair.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (!(obj instanceof Edge)) - return false; - Edge other = (Edge) obj; - if (pair == null) { - if (other.pair != null) - return false; - } else if (!pair.equals(other.pair)) - return false; - return true; - } - - public Pair getEndpoints() { - return pair; - } - - public String toString() { - return "edge1="+pair.getFirst()+",edge2="+pair.getSecond(); - } -} +package com.endlessloopsoftware.ego.client.graph; + +import edu.uci.ics.jung.graph.util.Pair; + +public class Edge { + + public final Pair pair; + private String notes; + + public Edge(String a, String b) { + super(); + this.pair = buildEdge(a,b); + this.notes = ""; + } + + public String getNotes() { + return notes; + } + + public void setNotes(String notes) { + this.notes = notes; + } + + public Edge(Vertex a, Vertex b) { + super(); + this.pair = buildEdge(a.name,b.name); + this.notes = ""; + } + + // keep them ordered for edge identity + public static Pair buildEdge(String a, String b) { + return a.compareTo(b) > 0 ? new Pair(b,a) : new Pair(a,b); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((pair == null) ? 0 : pair.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (!(obj instanceof Edge)) + return false; + Edge other = (Edge) obj; + if (pair == null) { + if (other.pair != null) + return false; + } else if (!pair.equals(other.pair)) + return false; + return true; + } + + public Pair getEndpoints() { + return pair; + } + + public String toString() { + return "edge1="+pair.getFirst()+",edge2="+pair.getSecond(); + } +} diff --git a/src/com/endlessloopsoftware/ego/client/graph/EdgeColorPanel.java b/src/main/java/com/endlessloopsoftware/ego/client/graph/EdgeColorPanel.java similarity index 100% rename from src/com/endlessloopsoftware/ego/client/graph/EdgeColorPanel.java rename to src/main/java/com/endlessloopsoftware/ego/client/graph/EdgeColorPanel.java diff --git a/src/com/endlessloopsoftware/ego/client/graph/EdgeProperty.java b/src/main/java/com/endlessloopsoftware/ego/client/graph/EdgeProperty.java similarity index 100% rename from src/com/endlessloopsoftware/ego/client/graph/EdgeProperty.java rename to src/main/java/com/endlessloopsoftware/ego/client/graph/EdgeProperty.java diff --git a/src/com/endlessloopsoftware/ego/client/graph/EdgeShapePanel.java b/src/main/java/com/endlessloopsoftware/ego/client/graph/EdgeShapePanel.java similarity index 100% rename from src/com/endlessloopsoftware/ego/client/graph/EdgeShapePanel.java rename to src/main/java/com/endlessloopsoftware/ego/client/graph/EdgeShapePanel.java diff --git a/src/com/endlessloopsoftware/ego/client/graph/EdgeSizePanel.java b/src/main/java/com/endlessloopsoftware/ego/client/graph/EdgeSizePanel.java similarity index 100% rename from src/com/endlessloopsoftware/ego/client/graph/EdgeSizePanel.java rename to src/main/java/com/endlessloopsoftware/ego/client/graph/EdgeSizePanel.java diff --git a/src/com/endlessloopsoftware/ego/client/graph/EllipseVertexShapeFunction.java b/src/main/java/com/endlessloopsoftware/ego/client/graph/EllipseVertexShapeFunction.java similarity index 100% rename from src/com/endlessloopsoftware/ego/client/graph/EllipseVertexShapeFunction.java rename to src/main/java/com/endlessloopsoftware/ego/client/graph/EllipseVertexShapeFunction.java diff --git a/src/com/endlessloopsoftware/ego/client/graph/GraphData.java b/src/main/java/com/endlessloopsoftware/ego/client/graph/GraphData.java similarity index 100% rename from src/com/endlessloopsoftware/ego/client/graph/GraphData.java rename to src/main/java/com/endlessloopsoftware/ego/client/graph/GraphData.java diff --git a/src/com/endlessloopsoftware/ego/client/graph/GraphPanel.java b/src/main/java/com/endlessloopsoftware/ego/client/graph/GraphPanel.java similarity index 100% rename from src/com/endlessloopsoftware/ego/client/graph/GraphPanel.java rename to src/main/java/com/endlessloopsoftware/ego/client/graph/GraphPanel.java diff --git a/src/com/endlessloopsoftware/ego/client/graph/GraphProperty.java b/src/main/java/com/endlessloopsoftware/ego/client/graph/GraphProperty.java similarity index 100% rename from src/com/endlessloopsoftware/ego/client/graph/GraphProperty.java rename to src/main/java/com/endlessloopsoftware/ego/client/graph/GraphProperty.java diff --git a/src/com/endlessloopsoftware/ego/client/graph/GraphQuestionSelectionPair.java b/src/main/java/com/endlessloopsoftware/ego/client/graph/GraphQuestionSelectionPair.java similarity index 100% rename from src/com/endlessloopsoftware/ego/client/graph/GraphQuestionSelectionPair.java rename to src/main/java/com/endlessloopsoftware/ego/client/graph/GraphQuestionSelectionPair.java diff --git a/src/com/endlessloopsoftware/ego/client/graph/GraphRenderer.java b/src/main/java/com/endlessloopsoftware/ego/client/graph/GraphRenderer.java similarity index 100% rename from src/com/endlessloopsoftware/ego/client/graph/GraphRenderer.java rename to src/main/java/com/endlessloopsoftware/ego/client/graph/GraphRenderer.java diff --git a/src/com/endlessloopsoftware/ego/client/graph/GraphSettings.java b/src/main/java/com/endlessloopsoftware/ego/client/graph/GraphSettings.java similarity index 100% rename from src/com/endlessloopsoftware/ego/client/graph/GraphSettings.java rename to src/main/java/com/endlessloopsoftware/ego/client/graph/GraphSettings.java diff --git a/src/com/endlessloopsoftware/ego/client/graph/GraphSettingsEntry.java b/src/main/java/com/endlessloopsoftware/ego/client/graph/GraphSettingsEntry.java similarity index 97% rename from src/com/endlessloopsoftware/ego/client/graph/GraphSettingsEntry.java rename to src/main/java/com/endlessloopsoftware/ego/client/graph/GraphSettingsEntry.java index 0045b47..c7f48ef 100644 --- a/src/com/endlessloopsoftware/ego/client/graph/GraphSettingsEntry.java +++ b/src/main/java/com/endlessloopsoftware/ego/client/graph/GraphSettingsEntry.java @@ -1,142 +1,142 @@ -/*** - * 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 . - */ -package com.endlessloopsoftware.ego.client.graph; - -import org.w3c.dom.*; - -import com.endlessloopsoftware.ego.client.graph.EdgeProperty.EdgePropertyType; -import com.endlessloopsoftware.ego.client.graph.NodeProperty.NodePropertyType; - -public class GraphSettingsEntry { - - public enum GraphSettingType { - Node, Edge - } - - GraphQuestionSelectionPair graphQuestion = null; - - GraphProperty property = null; - - GraphSettingType type; - - public GraphSettingsEntry(GraphQuestionSelectionPair gq, NodeProperty np, - GraphSettingType type) { - this.graphQuestion = gq; - this.property = np; - this.type = type; - } - - public GraphSettingsEntry(GraphQuestionSelectionPair gq, EdgeProperty ep, - GraphSettingType type) { - this.graphQuestion = gq; - this.property = ep; - this.type = type; - } - - public GraphQuestionSelectionPair getGraphQuestion() { - return graphQuestion; - } - - public GraphProperty getProperty() { - return property; - } - - public String toString() { - return "[questionSelectionPair=("+graphQuestion.toString() + "),(property=" + property.toString() + ")]"; - } - - public GraphSettingType getType() { - return type; - } - - public void writeEntryElement(Document doc, Element rootElement) { - Element entryElement = doc.createElement("Entry"); - - // Record Graph Question (Question , Answer) - Element graphQuestionElement = doc.createElement("GraphQuestionSelectionPair"); - // Question - Element questionElement = doc.createElement("Question"); - questionElement.setAttribute("id", graphQuestion.getQuestion().UniqueId - .toString()); - // Selection - Element selectionElement = doc.createElement("Selection"); - selectionElement.setAttribute("text", graphQuestion.getSelection().getString()); - // Type - Element categoryElement = doc.createElement("Category"); - String category = graphQuestion.getCategory().getSimpleName()+""; - categoryElement.setAttribute("category", category); - // Append all three to graphQuestion Element - graphQuestionElement.appendChild(questionElement); - graphQuestionElement.appendChild(selectionElement); - graphQuestionElement.appendChild(categoryElement); - - // Record Property(Color Shape Size Label) - Element propertyElement = doc.createElement("Property"); - propertyElement.setAttribute("type", type.toString()); - - if (property instanceof NodeProperty) { - NodeProperty np = ((NodeProperty) property); - if(np.getProperty().equals(NodePropertyType.Color)) - { - String rgb = ((Integer) property.getColor().getRGB()).toString(); - propertyElement.setAttribute("color", rgb); - } else if(np.getProperty().equals(NodePropertyType.Label)) { - // doesn't save label yet! - } else if(np.getProperty().equals(NodePropertyType.Shape)) { - String shape = np.getShape().toString(); - propertyElement.setAttribute("shape", shape); - } else if(np.getProperty().equals(NodePropertyType.Size)) { - String size = ((Integer) property.getSize()).toString(); - propertyElement.setAttribute("size", size); - } - - // no visible property on nodes - } else { - - EdgeProperty ep = ((EdgeProperty) property); - if(ep.getProperty().equals(EdgePropertyType.Color)) - { - String rgb = ((Integer) property.getColor().getRGB()).toString(); - propertyElement.setAttribute("color", rgb); - } else if(ep.getProperty().equals(EdgePropertyType.Label)) { - // doesn't save label yet! - } else if(ep.getProperty().equals(EdgePropertyType.Shape)) { - String shape = ep.getShape().toString(); - propertyElement.setAttribute("shape", shape); - } else if(ep.getProperty().equals(EdgePropertyType.Size)) { - String size = ((Integer) property.getSize()).toString(); - propertyElement.setAttribute("size", size); - } - - Element visibleElement = doc.createElement("Visible"); - if (((EdgeProperty) property).isVisible()) - visibleElement.setAttribute("visible", "true"); - else - visibleElement.setAttribute("visible", "false"); - propertyElement.appendChild(visibleElement); - } - - - entryElement.appendChild(graphQuestionElement); - entryElement.appendChild(propertyElement); - - rootElement.appendChild(entryElement); - } - -} +/*** + * 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 . + */ +package com.endlessloopsoftware.ego.client.graph; + +import org.w3c.dom.*; + +import com.endlessloopsoftware.ego.client.graph.EdgeProperty.EdgePropertyType; +import com.endlessloopsoftware.ego.client.graph.NodeProperty.NodePropertyType; + +public class GraphSettingsEntry { + + public enum GraphSettingType { + Node, Edge + } + + GraphQuestionSelectionPair graphQuestion = null; + + GraphProperty property = null; + + GraphSettingType type; + + public GraphSettingsEntry(GraphQuestionSelectionPair gq, NodeProperty np, + GraphSettingType type) { + this.graphQuestion = gq; + this.property = np; + this.type = type; + } + + public GraphSettingsEntry(GraphQuestionSelectionPair gq, EdgeProperty ep, + GraphSettingType type) { + this.graphQuestion = gq; + this.property = ep; + this.type = type; + } + + public GraphQuestionSelectionPair getGraphQuestion() { + return graphQuestion; + } + + public GraphProperty getProperty() { + return property; + } + + public String toString() { + return "[questionSelectionPair=("+graphQuestion.toString() + "),(property=" + property.toString() + ")]"; + } + + public GraphSettingType getType() { + return type; + } + + public void writeEntryElement(Document doc, Element rootElement) { + Element entryElement = doc.createElement("Entry"); + + // Record Graph Question (Question , Answer) + Element graphQuestionElement = doc.createElement("GraphQuestionSelectionPair"); + // Question + Element questionElement = doc.createElement("Question"); + questionElement.setAttribute("id", graphQuestion.getQuestion().UniqueId + .toString()); + // Selection + Element selectionElement = doc.createElement("Selection"); + selectionElement.setAttribute("text", graphQuestion.getSelection().getString()); + // Type + Element categoryElement = doc.createElement("Category"); + String category = graphQuestion.getCategory().getSimpleName()+""; + categoryElement.setAttribute("category", category); + // Append all three to graphQuestion Element + graphQuestionElement.appendChild(questionElement); + graphQuestionElement.appendChild(selectionElement); + graphQuestionElement.appendChild(categoryElement); + + // Record Property(Color Shape Size Label) + Element propertyElement = doc.createElement("Property"); + propertyElement.setAttribute("type", type.toString()); + + if (property instanceof NodeProperty) { + NodeProperty np = ((NodeProperty) property); + if(np.getProperty().equals(NodePropertyType.Color)) + { + String rgb = ((Integer) property.getColor().getRGB()).toString(); + propertyElement.setAttribute("color", rgb); + } else if(np.getProperty().equals(NodePropertyType.Label)) { + // doesn't save label yet! + } else if(np.getProperty().equals(NodePropertyType.Shape)) { + String shape = np.getShape().toString(); + propertyElement.setAttribute("shape", shape); + } else if(np.getProperty().equals(NodePropertyType.Size)) { + String size = ((Integer) property.getSize()).toString(); + propertyElement.setAttribute("size", size); + } + + // no visible property on nodes + } else { + + EdgeProperty ep = ((EdgeProperty) property); + if(ep.getProperty().equals(EdgePropertyType.Color)) + { + String rgb = ((Integer) property.getColor().getRGB()).toString(); + propertyElement.setAttribute("color", rgb); + } else if(ep.getProperty().equals(EdgePropertyType.Label)) { + // doesn't save label yet! + } else if(ep.getProperty().equals(EdgePropertyType.Shape)) { + String shape = ep.getShape().toString(); + propertyElement.setAttribute("shape", shape); + } else if(ep.getProperty().equals(EdgePropertyType.Size)) { + String size = ((Integer) property.getSize()).toString(); + propertyElement.setAttribute("size", size); + } + + Element visibleElement = doc.createElement("Visible"); + if (((EdgeProperty) property).isVisible()) + visibleElement.setAttribute("visible", "true"); + else + visibleElement.setAttribute("visible", "false"); + propertyElement.appendChild(visibleElement); + } + + + entryElement.appendChild(graphQuestionElement); + entryElement.appendChild(propertyElement); + + rootElement.appendChild(entryElement); + } + +} diff --git a/src/com/endlessloopsoftware/ego/client/graph/GraphTabPanel.java b/src/main/java/com/endlessloopsoftware/ego/client/graph/GraphTabPanel.java similarity index 100% rename from src/com/endlessloopsoftware/ego/client/graph/GraphTabPanel.java rename to src/main/java/com/endlessloopsoftware/ego/client/graph/GraphTabPanel.java diff --git a/src/com/endlessloopsoftware/ego/client/graph/NodeColorPanel.java b/src/main/java/com/endlessloopsoftware/ego/client/graph/NodeColorPanel.java similarity index 100% rename from src/com/endlessloopsoftware/ego/client/graph/NodeColorPanel.java rename to src/main/java/com/endlessloopsoftware/ego/client/graph/NodeColorPanel.java diff --git a/src/com/endlessloopsoftware/ego/client/graph/NodeLabelPanel.java b/src/main/java/com/endlessloopsoftware/ego/client/graph/NodeLabelPanel.java similarity index 100% rename from src/com/endlessloopsoftware/ego/client/graph/NodeLabelPanel.java rename to src/main/java/com/endlessloopsoftware/ego/client/graph/NodeLabelPanel.java diff --git a/src/com/endlessloopsoftware/ego/client/graph/NodeProperty.java b/src/main/java/com/endlessloopsoftware/ego/client/graph/NodeProperty.java similarity index 100% rename from src/com/endlessloopsoftware/ego/client/graph/NodeProperty.java rename to src/main/java/com/endlessloopsoftware/ego/client/graph/NodeProperty.java diff --git a/src/com/endlessloopsoftware/ego/client/graph/NodeShapePanel.java b/src/main/java/com/endlessloopsoftware/ego/client/graph/NodeShapePanel.java similarity index 100% rename from src/com/endlessloopsoftware/ego/client/graph/NodeShapePanel.java rename to src/main/java/com/endlessloopsoftware/ego/client/graph/NodeShapePanel.java diff --git a/src/com/endlessloopsoftware/ego/client/graph/NodeSizePanel.java b/src/main/java/com/endlessloopsoftware/ego/client/graph/NodeSizePanel.java similarity index 100% rename from src/com/endlessloopsoftware/ego/client/graph/NodeSizePanel.java rename to src/main/java/com/endlessloopsoftware/ego/client/graph/NodeSizePanel.java diff --git a/src/com/endlessloopsoftware/ego/client/graph/PolygonVertexShapeFunction.java b/src/main/java/com/endlessloopsoftware/ego/client/graph/PolygonVertexShapeFunction.java similarity index 100% rename from src/com/endlessloopsoftware/ego/client/graph/PolygonVertexShapeFunction.java rename to src/main/java/com/endlessloopsoftware/ego/client/graph/PolygonVertexShapeFunction.java diff --git a/src/com/endlessloopsoftware/ego/client/graph/StructuralMeasuresPanel.java b/src/main/java/com/endlessloopsoftware/ego/client/graph/StructuralMeasuresPanel.java similarity index 100% rename from src/com/endlessloopsoftware/ego/client/graph/StructuralMeasuresPanel.java rename to src/main/java/com/endlessloopsoftware/ego/client/graph/StructuralMeasuresPanel.java diff --git a/src/com/endlessloopsoftware/ego/client/graph/Vertex.java b/src/main/java/com/endlessloopsoftware/ego/client/graph/Vertex.java similarity index 94% rename from src/com/endlessloopsoftware/ego/client/graph/Vertex.java rename to src/main/java/com/endlessloopsoftware/ego/client/graph/Vertex.java index 56c0d77..e0da1df 100644 --- a/src/com/endlessloopsoftware/ego/client/graph/Vertex.java +++ b/src/main/java/com/endlessloopsoftware/ego/client/graph/Vertex.java @@ -1,40 +1,40 @@ -package com.endlessloopsoftware.ego.client.graph; - -public class Vertex { - - public final String name; - - public Vertex(String name) { - super(); - this.name = name; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((name == null) ? 0 : name.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (!(obj instanceof Vertex)) - return false; - Vertex other = (Vertex) obj; - if (name == null) { - if (other.name != null) - return false; - } else if (!name.equals(other.name)) - return false; - return true; - } - - public String toString() { - return "vertex="+name; - } -} +package com.endlessloopsoftware.ego.client.graph; + +public class Vertex { + + public final String name; + + public Vertex(String name) { + super(); + this.name = name; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (!(obj instanceof Vertex)) + return false; + Vertex other = (Vertex) obj; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + return true; + } + + public String toString() { + return "vertex="+name; + } +} diff --git a/src/com/endlessloopsoftware/ego/client/graph/VertexToolTipFunction.java b/src/main/java/com/endlessloopsoftware/ego/client/graph/VertexToolTipFunction.java similarity index 100% rename from src/com/endlessloopsoftware/ego/client/graph/VertexToolTipFunction.java rename to src/main/java/com/endlessloopsoftware/ego/client/graph/VertexToolTipFunction.java diff --git a/src/com/endlessloopsoftware/ego/client/statistics/AlterStats.java b/src/main/java/com/endlessloopsoftware/ego/client/statistics/AlterStats.java similarity index 97% rename from src/com/endlessloopsoftware/ego/client/statistics/AlterStats.java rename to src/main/java/com/endlessloopsoftware/ego/client/statistics/AlterStats.java index ee27093..6590fdb 100644 --- a/src/com/endlessloopsoftware/ego/client/statistics/AlterStats.java +++ b/src/main/java/com/endlessloopsoftware/ego/client/statistics/AlterStats.java @@ -1,32 +1,32 @@ -/*** - * 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 . - */ -package com.endlessloopsoftware.ego.client.statistics; - -import com.endlessloopsoftware.egonet.Shared; - -public class AlterStats -{ - public String qTitle; - public Shared.AnswerType answerType; - public Long questionId; - public int answerCount; - public String[] answerText; - public int answerTotals[]; -} - +/*** + * 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 . + */ +package com.endlessloopsoftware.ego.client.statistics; + +import com.endlessloopsoftware.egonet.Shared; + +public class AlterStats +{ + public String qTitle; + public Shared.AnswerType answerType; + public Long questionId; + public int answerCount; + public String[] answerText; + public int answerTotals[]; +} + diff --git a/src/com/endlessloopsoftware/ego/client/statistics/StatRecord.java b/src/main/java/com/endlessloopsoftware/ego/client/statistics/StatRecord.java similarity index 96% rename from src/com/endlessloopsoftware/ego/client/statistics/StatRecord.java rename to src/main/java/com/endlessloopsoftware/ego/client/statistics/StatRecord.java index a6a30f6..c153505 100644 --- a/src/com/endlessloopsoftware/ego/client/statistics/StatRecord.java +++ b/src/main/java/com/endlessloopsoftware/ego/client/statistics/StatRecord.java @@ -1,159 +1,159 @@ -/*** - * 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 . - */ -package com.endlessloopsoftware.ego.client.statistics; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.egonet.util.Name; - - -public class StatRecord -{ - private String name = ""; - public String degreeName = ""; - public Integer degreeValue = new Integer(0); - public Float degreeMean = new Float(0); - public Float degreeNC = new Float(0); - - public String betweenName = ""; - public Float betweenValue = new Float(0); - public Float betweenMean = new Float(0); - public Float betweenNC = new Float(0); - - public String closenessName = ""; - public Float closenessValue = new Float(0); - public Float closenessMean = new Float(0); - public Float closenessNC = new Float(0); - - public Integer numCliques = new Integer(0); - public Integer numComponents = new Integer(0); - public Integer numIsolates = new Integer(0); - public Integer numDyads = new Integer(0); - - public List egoAnswers = new ArrayList(); - public List alterAnswers = new ArrayList(); - - public StatRecord() - { - - } - - public List getEgoAnswers() - { - return egoAnswers; - } - public List getAlterAnswers() - { - return alterAnswers; - } - - public StatRecord(Statistics stats) - { - setName(new Name(stats.getInterview().getIntName()).toString()); - - degreeName = stats.mostCentralDegreeAlterName; - degreeValue = new Integer(stats.mostCentralDegreeAlterValue); - degreeMean = new Float(stats.meanCentralDegreeValue); - degreeNC = new Float(stats.degreeNC); - - closenessName = stats.mostCentralClosenessAlterName; - closenessValue = new Float(stats.mostCentralClosenessAlterValue); - closenessMean = new Float(stats.meanCentralClosenessValue); - closenessNC = new Float(stats.closenessNC); - - betweenName = stats.mostCentralBetweenAlterName; - betweenValue = new Float(stats.mostCentralBetweenAlterValue); - betweenMean = new Float(stats.meanCentralBetweenAlterValue); - betweenNC = new Float(stats.betweenNC); - - numCliques = new Integer(stats.cliqueSet.size()); - numComponents = new Integer(stats.componentSet.size() - stats.isolates - stats.dyads); - numIsolates = new Integer(stats.isolates); - numDyads = new Integer(stats.dyads); - - egoAnswers = Arrays.asList(stats.getInterview().getEgoAnswerArray(this)); - - for (int i = 0; i < stats.alterStatArray.length; ++i) - { - alterAnswers.add(new AlterAnswer(stats.alterStatArray[i])); - } - } - - public void setName(String name) { - this.name = name; -} - -public String getName() { - return name; -} - -public static class EgoAnswer - { - public final String title; - public final String answer; - public final int index; - - public EgoAnswer(String title, String answer, int index) - { - this.title = title; - this.answer = answer; - this.index = index; - } - } - - public static class AlterAnswer - { - public String title; - public int count; - public String[] selections; - public int[] totals; - //code added - public int[] AnswerIndex; - //end of add - - public AlterAnswer(String title, int count, String[] selections, - int[] totals, int[] answerIndex) { - super(); - this.title = title; - this.count = count; - this.selections = selections; - this.totals = totals; - AnswerIndex = answerIndex; - } - - public AlterAnswer(AlterStats alterStats) - { - title = alterStats.qTitle; - count = alterStats.answerCount; - selections = (String[]) alterStats.answerText.clone(); - totals = (int[]) alterStats.answerTotals.clone(); - } - - public String[] getSelections() { - return selections; - } - - public String getTitle() { - return title; - } - - } +/*** + * 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 . + */ +package com.endlessloopsoftware.ego.client.statistics; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.egonet.util.Name; + + +public class StatRecord +{ + private String name = ""; + public String degreeName = ""; + public Integer degreeValue = new Integer(0); + public Float degreeMean = new Float(0); + public Float degreeNC = new Float(0); + + public String betweenName = ""; + public Float betweenValue = new Float(0); + public Float betweenMean = new Float(0); + public Float betweenNC = new Float(0); + + public String closenessName = ""; + public Float closenessValue = new Float(0); + public Float closenessMean = new Float(0); + public Float closenessNC = new Float(0); + + public Integer numCliques = new Integer(0); + public Integer numComponents = new Integer(0); + public Integer numIsolates = new Integer(0); + public Integer numDyads = new Integer(0); + + public List egoAnswers = new ArrayList(); + public List alterAnswers = new ArrayList(); + + public StatRecord() + { + + } + + public List getEgoAnswers() + { + return egoAnswers; + } + public List getAlterAnswers() + { + return alterAnswers; + } + + public StatRecord(Statistics stats) + { + setName(new Name(stats.getInterview().getIntName()).toString()); + + degreeName = stats.mostCentralDegreeAlterName; + degreeValue = new Integer(stats.mostCentralDegreeAlterValue); + degreeMean = new Float(stats.meanCentralDegreeValue); + degreeNC = new Float(stats.degreeNC); + + closenessName = stats.mostCentralClosenessAlterName; + closenessValue = new Float(stats.mostCentralClosenessAlterValue); + closenessMean = new Float(stats.meanCentralClosenessValue); + closenessNC = new Float(stats.closenessNC); + + betweenName = stats.mostCentralBetweenAlterName; + betweenValue = new Float(stats.mostCentralBetweenAlterValue); + betweenMean = new Float(stats.meanCentralBetweenAlterValue); + betweenNC = new Float(stats.betweenNC); + + numCliques = new Integer(stats.cliqueSet.size()); + numComponents = new Integer(stats.componentSet.size() - stats.isolates - stats.dyads); + numIsolates = new Integer(stats.isolates); + numDyads = new Integer(stats.dyads); + + egoAnswers = Arrays.asList(stats.getInterview().getEgoAnswerArray(this)); + + for (int i = 0; i < stats.alterStatArray.length; ++i) + { + alterAnswers.add(new AlterAnswer(stats.alterStatArray[i])); + } + } + + public void setName(String name) { + this.name = name; +} + +public String getName() { + return name; +} + +public static class EgoAnswer + { + public final String title; + public final String answer; + public final int index; + + public EgoAnswer(String title, String answer, int index) + { + this.title = title; + this.answer = answer; + this.index = index; + } + } + + public static class AlterAnswer + { + public String title; + public int count; + public String[] selections; + public int[] totals; + //code added + public int[] AnswerIndex; + //end of add + + public AlterAnswer(String title, int count, String[] selections, + int[] totals, int[] answerIndex) { + super(); + this.title = title; + this.count = count; + this.selections = selections; + this.totals = totals; + AnswerIndex = answerIndex; + } + + public AlterAnswer(AlterStats alterStats) + { + title = alterStats.qTitle; + count = alterStats.answerCount; + selections = (String[]) alterStats.answerText.clone(); + totals = (int[]) alterStats.answerTotals.clone(); + } + + public String[] getSelections() { + return selections; + } + + public String getTitle() { + return title; + } + + } } \ No newline at end of file diff --git a/src/com/endlessloopsoftware/ego/client/statistics/Statistics.java b/src/main/java/com/endlessloopsoftware/ego/client/statistics/Statistics.java similarity index 100% rename from src/com/endlessloopsoftware/ego/client/statistics/Statistics.java rename to src/main/java/com/endlessloopsoftware/ego/client/statistics/Statistics.java diff --git a/src/com/endlessloopsoftware/ego/client/statistics/StatisticsArrayPanel.java b/src/main/java/com/endlessloopsoftware/ego/client/statistics/StatisticsArrayPanel.java similarity index 96% rename from src/com/endlessloopsoftware/ego/client/statistics/StatisticsArrayPanel.java rename to src/main/java/com/endlessloopsoftware/ego/client/statistics/StatisticsArrayPanel.java index 5f14e05..449135e 100644 --- a/src/com/endlessloopsoftware/ego/client/statistics/StatisticsArrayPanel.java +++ b/src/main/java/com/endlessloopsoftware/ego/client/statistics/StatisticsArrayPanel.java @@ -1,86 +1,86 @@ -/*** - * 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 . - */ -package com.endlessloopsoftware.ego.client.statistics; - -import java.awt.GridBagConstraints; -import java.awt.GridBagLayout; -import java.awt.Insets; - -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JTable; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.endlessloopsoftware.ego.client.statistics.models.StatTableModel; - -public class StatisticsArrayPanel extends JPanel -{ - final private static Logger logger = LoggerFactory.getLogger(StatisticsArrayPanel.class); - - StatTableModel data; - private JTable dataTable; - private JScrollPane dataScroll = new JScrollPane(); - private GridBagLayout gridBagLayout1 = new GridBagLayout(); - - public StatisticsArrayPanel(StatTableModel data) - { - this.data = data; - - try - { - jbInit(); - } - catch (Exception ex) - { - logger.error(ex.toString()); - } - } - - private void jbInit() throws Exception - { - dataTable = new JTable(data); - - this.setLayout(gridBagLayout1); - - dataTable.setAutoResizeMode(data.getResizeMode()); - dataTable.setRowHeight(16); - this.add( - dataScroll, - new GridBagConstraints( - 0, - 0, - 1, - 1, - 1.0, - 1.0, - GridBagConstraints.CENTER, - GridBagConstraints.BOTH, - new Insets(5, 5, 5, 5), - 0, - 0)); - dataScroll.getViewport().add(dataTable, null); - } - - public StatTableModel getTableModel() - { - return data; - } +/*** + * 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 . + */ +package com.endlessloopsoftware.ego.client.statistics; + +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; + +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTable; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.endlessloopsoftware.ego.client.statistics.models.StatTableModel; + +public class StatisticsArrayPanel extends JPanel +{ + final private static Logger logger = LoggerFactory.getLogger(StatisticsArrayPanel.class); + + StatTableModel data; + private JTable dataTable; + private JScrollPane dataScroll = new JScrollPane(); + private GridBagLayout gridBagLayout1 = new GridBagLayout(); + + public StatisticsArrayPanel(StatTableModel data) + { + this.data = data; + + try + { + jbInit(); + } + catch (Exception ex) + { + logger.error(ex.toString()); + } + } + + private void jbInit() throws Exception + { + dataTable = new JTable(data); + + this.setLayout(gridBagLayout1); + + dataTable.setAutoResizeMode(data.getResizeMode()); + dataTable.setRowHeight(16); + this.add( + dataScroll, + new GridBagConstraints( + 0, + 0, + 1, + 1, + 1.0, + 1.0, + GridBagConstraints.CENTER, + GridBagConstraints.BOTH, + new Insets(5, 5, 5, 5), + 0, + 0)); + dataScroll.getViewport().add(dataTable, null); + } + + public StatTableModel getTableModel() + { + return data; + } } \ No newline at end of file diff --git a/src/com/endlessloopsoftware/ego/client/statistics/StatisticsFrame.java b/src/main/java/com/endlessloopsoftware/ego/client/statistics/StatisticsFrame.java similarity index 97% rename from src/com/endlessloopsoftware/ego/client/statistics/StatisticsFrame.java rename to src/main/java/com/endlessloopsoftware/ego/client/statistics/StatisticsFrame.java index 1152cb7..02da62f 100644 --- a/src/com/endlessloopsoftware/ego/client/statistics/StatisticsFrame.java +++ b/src/main/java/com/endlessloopsoftware/ego/client/statistics/StatisticsFrame.java @@ -1,313 +1,313 @@ -/*** - * 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 . - */ -package com.endlessloopsoftware.ego.client.statistics; -import java.awt.Container; -import java.awt.GridBagConstraints; -import java.awt.GridBagLayout; -import java.awt.GridLayout; -import java.awt.Insets; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.io.PrintWriter; -import java.util.Iterator; - -import javax.swing.JComponent; -import javax.swing.JLabel; -import javax.swing.JMenuItem; -import javax.swing.JPanel; -import javax.swing.JTabbedPane; - -import org.egonet.model.question.AlterPairQuestion; -import org.egonet.model.question.Question; -import org.egonet.util.CatchingAction; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; - -import com.endlessloopsoftware.ego.client.EgoClient; -import com.endlessloopsoftware.ego.client.statistics.models.BetweennessModel; -import com.endlessloopsoftware.ego.client.statistics.models.CliqueModel; -import com.endlessloopsoftware.ego.client.statistics.models.ClosenessModel; -import com.endlessloopsoftware.ego.client.statistics.models.CompositionalStatsModel; -import com.endlessloopsoftware.ego.client.statistics.models.DegreeModel; -import com.endlessloopsoftware.ego.client.statistics.models.InterviewSummaryModel; -import com.endlessloopsoftware.ego.client.statistics.models.QSummaryModel; - - - -public class StatisticsFrame extends JPanel { - private Statistics stats = null; - - private JTabbedPane tabs = new JTabbedPane(); - - private JPanel summaryPanel = null; - - private JPanel dcPanel = null; - - private JPanel ccPanel = null; - - private JPanel bcPanel = null; - - private JPanel cliquePanel = null; - - private JPanel componentPanel = null; - - private JPanel qSummaryPanel = null; - - private EgoClient egoClient; - - final private static Logger logger = LoggerFactory.getLogger(StatisticsFrame.class); - - public StatisticsFrame(EgoClient egoClient) { - this.egoClient = egoClient; - jbInit(); - } - - private void jbInit() { - boolean studyStatable = false; - - /*********************************************************************** - * Fill in alter pair question selection menu - **********************************************************************/ - Iterator questions = egoClient.getStudy().getQuestionOrder(AlterPairQuestion.class).iterator(); - while (questions.hasNext()) { - Question q = egoClient.getStudy().getQuestion((Long) questions.next()); - - if (q.isStatable()) { - //alterQuestionMenu.addItem(q); - studyStatable = true; - stats = egoClient.getInterview().generateStatistics(q); - - // Use stats to initialize panels - summaryPanel = new StatisticsArrayPanel(new InterviewSummaryModel( - stats)); - dcPanel = new StatisticsArrayPanel(new DegreeModel(stats)); - ccPanel = new StatisticsArrayPanel(new ClosenessModel(stats)); - bcPanel = new StatisticsArrayPanel(new BetweennessModel(stats)); - cliquePanel = new StatisticsArrayPanel(new CliqueModel(stats)); - componentPanel = new StatisticsArrayPanel( - new CompositionalStatsModel(stats)); - qSummaryPanel = new StatisticsArrayPanel(new QSummaryModel(stats)); - - /******************************************************************* - * Create UI - ******************************************************************/ - // setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); - // Container panel = this.getContentPane(); - Container panel = this; - - panel.setLayout(new GridBagLayout()); - tabs.addTab("Structural Measures", summaryPanel); - tabs.addTab("Compositional Summary", qSummaryPanel); - tabs.addTab("Degree Centrality", dcPanel); - tabs.addTab("Closeness Centrality", ccPanel); - tabs.addTab("Betweenness Centrality", bcPanel); - tabs.addTab("Cliques", cliquePanel); - tabs.addTab("Components", componentPanel); - // tabs.addTab("Graph", graphPanel); - - /******************************************************************* - * Layout - ******************************************************************/ - this.add(tabs); - panel.add(tabs, new GridBagConstraints(0, 0, 1, 1, 1.0, 0.9, - GridBagConstraints.CENTER, GridBagConstraints.BOTH, - new Insets(0, 0, 0, 0), 0, 0)); - - /******************************************************************* - * Event Handlers - ******************************************************************/ - /*alterQuestionMenu - .addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(ActionEvent e) { - alterQuestionMenu_actionPerformed(e); - } - });*/ - - removeAllActionListeners(egoClient.getFrame().saveAlterSummary); - egoClient.getFrame().saveAlterSummary - .addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(ActionEvent e) { - saveAlterSummary_actionPerformed(e); - } - }); - - removeAllActionListeners(egoClient.getFrame().saveTextSummary); - egoClient.getFrame().saveTextSummary - .addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(ActionEvent e) { - saveTextSummary_actionPerformed(e); - } - }); - - removeAllActionListeners(egoClient.getFrame().saveWeightedAdjacencyMatrix); - egoClient.getFrame().saveWeightedAdjacencyMatrix - .addActionListener(new CatchingAction("saveWeightedAdjacencyMatrix") { - public void safeActionPerformed(ActionEvent e) throws Exception { - saveAdjacencyMatrix_actionPerformed(e, true); - } - }); - - - removeAllActionListeners(egoClient.getFrame().saveAlterByAlterPromptMatrix); - egoClient.getFrame().saveAlterByAlterPromptMatrix - .addActionListener(new CatchingAction("saveAlterByAlterPromptMatrix") { - public void safeActionPerformed(ActionEvent e) throws Exception { - saveAlterByAlterPromptMatrix_actionPerformed(e); - } - }); - - removeAllActionListeners(egoClient.getFrame().saveAdjacencyMatrix); - egoClient.getFrame().saveAdjacencyMatrix - .addActionListener(new CatchingAction("saveAdjacencyMatrix") { - public void safeActionPerformed(ActionEvent e) throws Exception { - saveAdjacencyMatrix_actionPerformed(e, false); - } - }); - - removeAllActionListeners(egoClient.getFrame().saveInterviewStatistics); - egoClient.getFrame().saveInterviewStatistics - .addActionListener(new CatchingAction("saveInterviewStatistics") { - public void safeActionPerformed(ActionEvent e) throws Exception { - saveInterviewStatistics_actionPerformed(e); - } - }); - - - updateAll(); - } - else { - logger.error("No stateable ALTER_PAIR question, bailing on lots of stuff"); - } - } - - /*********************************************************************** - * Check that there is at least one statable question, if not abort this - */ - if (!studyStatable) { - /******************************************************************* - * No Statable Questions - */ - this.setLayout(new GridLayout()); - this - .add(new JLabel( - "No questions with adjacent and non-adjacent selections found.")); - } - - egoClient.getFrame().close - .addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(ActionEvent e) { - close_actionPerformed(e); - } - }); - } - - private static void removeAllActionListeners(JMenuItem saveAlterSummary) { - ActionListener[] listeners = saveAlterSummary.getActionListeners(); - for(ActionListener l : listeners) - saveAlterSummary.removeActionListener(l); - } - - void updateAll() { - for (int i = 0; i < tabs.getTabCount(); i++) { - JComponent component = (JComponent) tabs.getComponentAt(i); - - if (component instanceof StatisticsArrayPanel) { - ((StatisticsArrayPanel) component).getTableModel().setStats( - stats); - ((StatisticsArrayPanel) component).getTableModel().update(); - } - } - } - - //TODO: We need to do alter pair stats when a question is selected, since we got rid of the drop down list. - /*void alterQuestionMenu_actionPerformed(ActionEvent e) { - if (!e.getActionCommand().equals("Initialization")) { - stats = egoClient.getInterview() - .generateStatistics((Question) alterQuestionMenu - .getSelectedItem()); - - updateAll(); - } - }*/ - - void saveAlterSummary_actionPerformed(ActionEvent e) { - String name = egoClient.getInterview().getIntName(); - String filename = name + "_alter_summary"; - PrintWriter w = egoClient.getStorage().newStatisticsPrintWriter("Alter Summary", "csv", filename); - - try { - stats.writeAlterArray(w); - } finally { - w.close(); - } - } - - void saveTextSummary_actionPerformed(ActionEvent e) { - String name = egoClient.getInterview().getIntName(); - String filename = name + "_Text_Summary"; - PrintWriter w = egoClient.getStorage().newStatisticsPrintWriter( - "Text Summary", "txt", filename); - - if (w != null) { - try { - stats.writeTextAnswers(w); - } finally { - w.close(); - } - } - } - - void saveAdjacencyMatrix_actionPerformed(ActionEvent e, boolean weighted) throws IOException { - String filename = egoClient.getStorage().getInterviewFile().getName() + (weighted ? "_Weighted" : "") + "_Adjacency_Matrix"; - - PrintWriter w = egoClient.getStorage().newStatisticsPrintWriter(filename, "csv", filename); - - stats.writeAdjacencyFile(w, egoClient.getStorage().getInterviewFile().getName().replace(".int", ""), weighted); - } - - void saveAlterByAlterPromptMatrix_actionPerformed(ActionEvent e) throws IOException - { - String filename = egoClient.getStorage().getInterviewFile().getName() + ("_alter_by_alter_prompt"); - - PrintWriter w = egoClient.getStorage().newStatisticsPrintWriter(filename, "csv", filename); - - stats.writeAlterByPromptFile(w, filename); - } - - void close_actionPerformed(ActionEvent e) { - //logger.info("Return"); - egoClient.getFrame().gotoSourceSelectPanel(); - } - - void saveInterviewStatistics_actionPerformed(ActionEvent e) throws IOException { - /*********************************************************************** - * Generate statistics for the first statable question - */ - Question q = egoClient.getStudy().getFirstStatableQuestion(); - - if (q != null) { - egoClient.getStorage().writeStatisticsFiles(stats); - } else { - throw new IOException("No statable questions"); - } - - } -} +/*** + * 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 . + */ +package com.endlessloopsoftware.ego.client.statistics; +import java.awt.Container; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.GridLayout; +import java.awt.Insets; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.PrintWriter; +import java.util.Iterator; + +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JMenuItem; +import javax.swing.JPanel; +import javax.swing.JTabbedPane; + +import org.egonet.model.question.AlterPairQuestion; +import org.egonet.model.question.Question; +import org.egonet.util.CatchingAction; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; + +import com.endlessloopsoftware.ego.client.EgoClient; +import com.endlessloopsoftware.ego.client.statistics.models.BetweennessModel; +import com.endlessloopsoftware.ego.client.statistics.models.CliqueModel; +import com.endlessloopsoftware.ego.client.statistics.models.ClosenessModel; +import com.endlessloopsoftware.ego.client.statistics.models.CompositionalStatsModel; +import com.endlessloopsoftware.ego.client.statistics.models.DegreeModel; +import com.endlessloopsoftware.ego.client.statistics.models.InterviewSummaryModel; +import com.endlessloopsoftware.ego.client.statistics.models.QSummaryModel; + + + +public class StatisticsFrame extends JPanel { + private Statistics stats = null; + + private JTabbedPane tabs = new JTabbedPane(); + + private JPanel summaryPanel = null; + + private JPanel dcPanel = null; + + private JPanel ccPanel = null; + + private JPanel bcPanel = null; + + private JPanel cliquePanel = null; + + private JPanel componentPanel = null; + + private JPanel qSummaryPanel = null; + + private EgoClient egoClient; + + final private static Logger logger = LoggerFactory.getLogger(StatisticsFrame.class); + + public StatisticsFrame(EgoClient egoClient) { + this.egoClient = egoClient; + jbInit(); + } + + private void jbInit() { + boolean studyStatable = false; + + /*********************************************************************** + * Fill in alter pair question selection menu + **********************************************************************/ + Iterator questions = egoClient.getStudy().getQuestionOrder(AlterPairQuestion.class).iterator(); + while (questions.hasNext()) { + Question q = egoClient.getStudy().getQuestion((Long) questions.next()); + + if (q.isStatable()) { + //alterQuestionMenu.addItem(q); + studyStatable = true; + stats = egoClient.getInterview().generateStatistics(q); + + // Use stats to initialize panels + summaryPanel = new StatisticsArrayPanel(new InterviewSummaryModel( + stats)); + dcPanel = new StatisticsArrayPanel(new DegreeModel(stats)); + ccPanel = new StatisticsArrayPanel(new ClosenessModel(stats)); + bcPanel = new StatisticsArrayPanel(new BetweennessModel(stats)); + cliquePanel = new StatisticsArrayPanel(new CliqueModel(stats)); + componentPanel = new StatisticsArrayPanel( + new CompositionalStatsModel(stats)); + qSummaryPanel = new StatisticsArrayPanel(new QSummaryModel(stats)); + + /******************************************************************* + * Create UI + ******************************************************************/ + // setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + // Container panel = this.getContentPane(); + Container panel = this; + + panel.setLayout(new GridBagLayout()); + tabs.addTab("Structural Measures", summaryPanel); + tabs.addTab("Compositional Summary", qSummaryPanel); + tabs.addTab("Degree Centrality", dcPanel); + tabs.addTab("Closeness Centrality", ccPanel); + tabs.addTab("Betweenness Centrality", bcPanel); + tabs.addTab("Cliques", cliquePanel); + tabs.addTab("Components", componentPanel); + // tabs.addTab("Graph", graphPanel); + + /******************************************************************* + * Layout + ******************************************************************/ + this.add(tabs); + panel.add(tabs, new GridBagConstraints(0, 0, 1, 1, 1.0, 0.9, + GridBagConstraints.CENTER, GridBagConstraints.BOTH, + new Insets(0, 0, 0, 0), 0, 0)); + + /******************************************************************* + * Event Handlers + ******************************************************************/ + /*alterQuestionMenu + .addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(ActionEvent e) { + alterQuestionMenu_actionPerformed(e); + } + });*/ + + removeAllActionListeners(egoClient.getFrame().saveAlterSummary); + egoClient.getFrame().saveAlterSummary + .addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(ActionEvent e) { + saveAlterSummary_actionPerformed(e); + } + }); + + removeAllActionListeners(egoClient.getFrame().saveTextSummary); + egoClient.getFrame().saveTextSummary + .addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(ActionEvent e) { + saveTextSummary_actionPerformed(e); + } + }); + + removeAllActionListeners(egoClient.getFrame().saveWeightedAdjacencyMatrix); + egoClient.getFrame().saveWeightedAdjacencyMatrix + .addActionListener(new CatchingAction("saveWeightedAdjacencyMatrix") { + public void safeActionPerformed(ActionEvent e) throws Exception { + saveAdjacencyMatrix_actionPerformed(e, true); + } + }); + + + removeAllActionListeners(egoClient.getFrame().saveAlterByAlterPromptMatrix); + egoClient.getFrame().saveAlterByAlterPromptMatrix + .addActionListener(new CatchingAction("saveAlterByAlterPromptMatrix") { + public void safeActionPerformed(ActionEvent e) throws Exception { + saveAlterByAlterPromptMatrix_actionPerformed(e); + } + }); + + removeAllActionListeners(egoClient.getFrame().saveAdjacencyMatrix); + egoClient.getFrame().saveAdjacencyMatrix + .addActionListener(new CatchingAction("saveAdjacencyMatrix") { + public void safeActionPerformed(ActionEvent e) throws Exception { + saveAdjacencyMatrix_actionPerformed(e, false); + } + }); + + removeAllActionListeners(egoClient.getFrame().saveInterviewStatistics); + egoClient.getFrame().saveInterviewStatistics + .addActionListener(new CatchingAction("saveInterviewStatistics") { + public void safeActionPerformed(ActionEvent e) throws Exception { + saveInterviewStatistics_actionPerformed(e); + } + }); + + + updateAll(); + } + else { + logger.error("No stateable ALTER_PAIR question, bailing on lots of stuff"); + } + } + + /*********************************************************************** + * Check that there is at least one statable question, if not abort this + */ + if (!studyStatable) { + /******************************************************************* + * No Statable Questions + */ + this.setLayout(new GridLayout()); + this + .add(new JLabel( + "No questions with adjacent and non-adjacent selections found.")); + } + + egoClient.getFrame().close + .addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(ActionEvent e) { + close_actionPerformed(e); + } + }); + } + + private static void removeAllActionListeners(JMenuItem saveAlterSummary) { + ActionListener[] listeners = saveAlterSummary.getActionListeners(); + for(ActionListener l : listeners) + saveAlterSummary.removeActionListener(l); + } + + void updateAll() { + for (int i = 0; i < tabs.getTabCount(); i++) { + JComponent component = (JComponent) tabs.getComponentAt(i); + + if (component instanceof StatisticsArrayPanel) { + ((StatisticsArrayPanel) component).getTableModel().setStats( + stats); + ((StatisticsArrayPanel) component).getTableModel().update(); + } + } + } + + //TODO: We need to do alter pair stats when a question is selected, since we got rid of the drop down list. + /*void alterQuestionMenu_actionPerformed(ActionEvent e) { + if (!e.getActionCommand().equals("Initialization")) { + stats = egoClient.getInterview() + .generateStatistics((Question) alterQuestionMenu + .getSelectedItem()); + + updateAll(); + } + }*/ + + void saveAlterSummary_actionPerformed(ActionEvent e) { + String name = egoClient.getInterview().getIntName(); + String filename = name + "_alter_summary"; + PrintWriter w = egoClient.getStorage().newStatisticsPrintWriter("Alter Summary", "csv", filename); + + try { + stats.writeAlterArray(w); + } finally { + w.close(); + } + } + + void saveTextSummary_actionPerformed(ActionEvent e) { + String name = egoClient.getInterview().getIntName(); + String filename = name + "_Text_Summary"; + PrintWriter w = egoClient.getStorage().newStatisticsPrintWriter( + "Text Summary", "txt", filename); + + if (w != null) { + try { + stats.writeTextAnswers(w); + } finally { + w.close(); + } + } + } + + void saveAdjacencyMatrix_actionPerformed(ActionEvent e, boolean weighted) throws IOException { + String filename = egoClient.getStorage().getInterviewFile().getName() + (weighted ? "_Weighted" : "") + "_Adjacency_Matrix"; + + PrintWriter w = egoClient.getStorage().newStatisticsPrintWriter(filename, "csv", filename); + + stats.writeAdjacencyFile(w, egoClient.getStorage().getInterviewFile().getName().replace(".int", ""), weighted); + } + + void saveAlterByAlterPromptMatrix_actionPerformed(ActionEvent e) throws IOException + { + String filename = egoClient.getStorage().getInterviewFile().getName() + ("_alter_by_alter_prompt"); + + PrintWriter w = egoClient.getStorage().newStatisticsPrintWriter(filename, "csv", filename); + + stats.writeAlterByPromptFile(w, filename); + } + + void close_actionPerformed(ActionEvent e) { + //logger.info("Return"); + egoClient.getFrame().gotoSourceSelectPanel(); + } + + void saveInterviewStatistics_actionPerformed(ActionEvent e) throws IOException { + /*********************************************************************** + * Generate statistics for the first statable question + */ + Question q = egoClient.getStudy().getFirstStatableQuestion(); + + if (q != null) { + egoClient.getStorage().writeStatisticsFiles(stats); + } else { + throw new IOException("No statable questions"); + } + + } +} diff --git a/src/com/endlessloopsoftware/ego/client/statistics/models/BetweennessModel.java b/src/main/java/com/endlessloopsoftware/ego/client/statistics/models/BetweennessModel.java similarity index 96% rename from src/com/endlessloopsoftware/ego/client/statistics/models/BetweennessModel.java rename to src/main/java/com/endlessloopsoftware/ego/client/statistics/models/BetweennessModel.java index d66af73..89aee08 100644 --- a/src/com/endlessloopsoftware/ego/client/statistics/models/BetweennessModel.java +++ b/src/main/java/com/endlessloopsoftware/ego/client/statistics/models/BetweennessModel.java @@ -1,87 +1,87 @@ -/*** - * 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 . - */ -package com.endlessloopsoftware.ego.client.statistics.models; - -import javax.swing.JTable; - -import com.endlessloopsoftware.ego.client.statistics.Statistics; - -public class BetweennessModel extends StatTableModel -{ - public BetweennessModel(Statistics stats) - { - super(stats); - } - - public int getColumnCount() - { - return (3); - } - - public int getRowCount() - { - return (stats.degreeArray.length); - } - - public Object getValueAt(int rowIndex, int columnIndex) - { - try - { - if (columnIndex == 0) - { - return (stats.alterList[rowIndex]); - } - else if (columnIndex == 1) - { - return (new Float(stats.betweennessArray[rowIndex])); - } - else - { - double big = stats.proximityMatrix.length - 1; - big *= big; - return (new Float(stats.betweennessArray[rowIndex] / big)); - } - } - catch (Exception ex) - { - throw new RuntimeException(ex); - } - } - - public String getColumnName(int column) - { - if (column == 0) - { - return ("Alters"); - } - else if (column == 1) - { - return ("Raw"); - } - else - { - return ("Normalized"); - } - } - - public int getResizeMode() - { - return JTable.AUTO_RESIZE_ALL_COLUMNS; - } +/*** + * 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 . + */ +package com.endlessloopsoftware.ego.client.statistics.models; + +import javax.swing.JTable; + +import com.endlessloopsoftware.ego.client.statistics.Statistics; + +public class BetweennessModel extends StatTableModel +{ + public BetweennessModel(Statistics stats) + { + super(stats); + } + + public int getColumnCount() + { + return (3); + } + + public int getRowCount() + { + return (stats.degreeArray.length); + } + + public Object getValueAt(int rowIndex, int columnIndex) + { + try + { + if (columnIndex == 0) + { + return (stats.alterList[rowIndex]); + } + else if (columnIndex == 1) + { + return (new Float(stats.betweennessArray[rowIndex])); + } + else + { + double big = stats.proximityMatrix.length - 1; + big *= big; + return (new Float(stats.betweennessArray[rowIndex] / big)); + } + } + catch (Exception ex) + { + throw new RuntimeException(ex); + } + } + + public String getColumnName(int column) + { + if (column == 0) + { + return ("Alters"); + } + else if (column == 1) + { + return ("Raw"); + } + else + { + return ("Normalized"); + } + } + + public int getResizeMode() + { + return JTable.AUTO_RESIZE_ALL_COLUMNS; + } } \ No newline at end of file diff --git a/src/com/endlessloopsoftware/ego/client/statistics/models/CliqueModel.java b/src/main/java/com/endlessloopsoftware/ego/client/statistics/models/CliqueModel.java similarity index 95% rename from src/com/endlessloopsoftware/ego/client/statistics/models/CliqueModel.java rename to src/main/java/com/endlessloopsoftware/ego/client/statistics/models/CliqueModel.java index 0b82d1c..adbe1e1 100644 --- a/src/com/endlessloopsoftware/ego/client/statistics/models/CliqueModel.java +++ b/src/main/java/com/endlessloopsoftware/ego/client/statistics/models/CliqueModel.java @@ -1,106 +1,106 @@ -/*** - * 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 . - */ -package com.endlessloopsoftware.ego.client.statistics.models; - -import java.util.Iterator; -import java.util.Stack; - -import javax.swing.JTable; - -import com.endlessloopsoftware.ego.client.statistics.Statistics; - -public class CliqueModel extends StatTableModel -{ - private Stack[] cliqueArray; - private int cliqueDepth; - - public CliqueModel(Statistics stats) - { - super(stats); - initModel(); - } - - private void initModel() - { - cliqueArray = new Stack[stats.cliqueSet.size()]; - stats.cliqueSet.toArray(cliqueArray); - - /* Determine deepest clique */ - Iterator it = stats.cliqueSet.iterator(); - int maxCount = 0; - - while (it.hasNext()) - { - Stack s = (Stack) it.next(); - - if (s.size() > maxCount) - { - maxCount = s.size(); - } - } - - cliqueDepth = maxCount; - } - - public void update() - { - initModel(); - this.fireTableStructureChanged(); - fireTableDataChanged(); - } - - public int getColumnCount() - { - return (cliqueArray.length); - } - - public int getRowCount() - { - return (cliqueDepth); - } - - public Object getValueAt(int rowIndex, int columnIndex) - { - if (rowIndex < cliqueArray[columnIndex].size()) - { - try - { - return (stats.alterList[((Integer) cliqueArray[columnIndex].get(rowIndex)).intValue()]); - } - catch (Exception ex) - { - throw new RuntimeException(ex); - } - } - else - { - return null; - } - } - - public String getColumnName(int column) - { - return ("Clique " + (column + 1)); - } - - public int getResizeMode() - { - return JTable.AUTO_RESIZE_OFF; - } -} +/*** + * 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 . + */ +package com.endlessloopsoftware.ego.client.statistics.models; + +import java.util.Iterator; +import java.util.Stack; + +import javax.swing.JTable; + +import com.endlessloopsoftware.ego.client.statistics.Statistics; + +public class CliqueModel extends StatTableModel +{ + private Stack[] cliqueArray; + private int cliqueDepth; + + public CliqueModel(Statistics stats) + { + super(stats); + initModel(); + } + + private void initModel() + { + cliqueArray = new Stack[stats.cliqueSet.size()]; + stats.cliqueSet.toArray(cliqueArray); + + /* Determine deepest clique */ + Iterator it = stats.cliqueSet.iterator(); + int maxCount = 0; + + while (it.hasNext()) + { + Stack s = (Stack) it.next(); + + if (s.size() > maxCount) + { + maxCount = s.size(); + } + } + + cliqueDepth = maxCount; + } + + public void update() + { + initModel(); + this.fireTableStructureChanged(); + fireTableDataChanged(); + } + + public int getColumnCount() + { + return (cliqueArray.length); + } + + public int getRowCount() + { + return (cliqueDepth); + } + + public Object getValueAt(int rowIndex, int columnIndex) + { + if (rowIndex < cliqueArray[columnIndex].size()) + { + try + { + return (stats.alterList[((Integer) cliqueArray[columnIndex].get(rowIndex)).intValue()]); + } + catch (Exception ex) + { + throw new RuntimeException(ex); + } + } + else + { + return null; + } + } + + public String getColumnName(int column) + { + return ("Clique " + (column + 1)); + } + + public int getResizeMode() + { + return JTable.AUTO_RESIZE_OFF; + } +} diff --git a/src/com/endlessloopsoftware/ego/client/statistics/models/ClosenessModel.java b/src/main/java/com/endlessloopsoftware/ego/client/statistics/models/ClosenessModel.java similarity index 96% rename from src/com/endlessloopsoftware/ego/client/statistics/models/ClosenessModel.java rename to src/main/java/com/endlessloopsoftware/ego/client/statistics/models/ClosenessModel.java index adf06e8..ca43118 100644 --- a/src/com/endlessloopsoftware/ego/client/statistics/models/ClosenessModel.java +++ b/src/main/java/com/endlessloopsoftware/ego/client/statistics/models/ClosenessModel.java @@ -1,93 +1,93 @@ -/*** - * 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 . - */ -package com.endlessloopsoftware.ego.client.statistics.models; - -import javax.swing.JTable; - -import com.endlessloopsoftware.ego.client.statistics.Statistics; - -public class ClosenessModel extends StatTableModel -{ - public ClosenessModel(Statistics stats) - { - super(stats); - } - - public int getColumnCount() - { - return (stats.proximityMatrix.length + 3); - } - - public int getRowCount() - { - return (stats.proximityMatrix.length); - } - - public Object getValueAt(int rowIndex, int columnIndex) - { - try - { - if (columnIndex == 0) - { - return (stats.alterList[rowIndex]); - } - else if (columnIndex == (getColumnCount() - 2)) - { - return (new Integer(stats.farnessArray[rowIndex])); - } - else if (columnIndex == (getColumnCount() - 1)) - { - return (new Float(stats.closenessArray[rowIndex])); - } - else - { - return (new Integer(stats.proximityMatrix[rowIndex][columnIndex - 1])); - } - } - catch (Exception ex) - { - throw new RuntimeException(ex); - } - } - - public String getColumnName(int column) - { - if (column == 0) - { - return (" "); - } - else if (column == (getColumnCount() - 2)) - { - return ("Farness"); - } - else if (column == (getColumnCount() - 1)) - { - return ("nCloseness"); - } - else - { - return stats.alterList[column - 1]; - } - } - - public int getResizeMode() - { - return JTable.AUTO_RESIZE_OFF; - } -} +/*** + * 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 . + */ +package com.endlessloopsoftware.ego.client.statistics.models; + +import javax.swing.JTable; + +import com.endlessloopsoftware.ego.client.statistics.Statistics; + +public class ClosenessModel extends StatTableModel +{ + public ClosenessModel(Statistics stats) + { + super(stats); + } + + public int getColumnCount() + { + return (stats.proximityMatrix.length + 3); + } + + public int getRowCount() + { + return (stats.proximityMatrix.length); + } + + public Object getValueAt(int rowIndex, int columnIndex) + { + try + { + if (columnIndex == 0) + { + return (stats.alterList[rowIndex]); + } + else if (columnIndex == (getColumnCount() - 2)) + { + return (new Integer(stats.farnessArray[rowIndex])); + } + else if (columnIndex == (getColumnCount() - 1)) + { + return (new Float(stats.closenessArray[rowIndex])); + } + else + { + return (new Integer(stats.proximityMatrix[rowIndex][columnIndex - 1])); + } + } + catch (Exception ex) + { + throw new RuntimeException(ex); + } + } + + public String getColumnName(int column) + { + if (column == 0) + { + return (" "); + } + else if (column == (getColumnCount() - 2)) + { + return ("Farness"); + } + else if (column == (getColumnCount() - 1)) + { + return ("nCloseness"); + } + else + { + return stats.alterList[column - 1]; + } + } + + public int getResizeMode() + { + return JTable.AUTO_RESIZE_OFF; + } +} diff --git a/src/com/endlessloopsoftware/ego/client/statistics/models/CompositionalStatsModel.java b/src/main/java/com/endlessloopsoftware/ego/client/statistics/models/CompositionalStatsModel.java similarity index 95% rename from src/com/endlessloopsoftware/ego/client/statistics/models/CompositionalStatsModel.java rename to src/main/java/com/endlessloopsoftware/ego/client/statistics/models/CompositionalStatsModel.java index 07065cf..e7274eb 100644 --- a/src/com/endlessloopsoftware/ego/client/statistics/models/CompositionalStatsModel.java +++ b/src/main/java/com/endlessloopsoftware/ego/client/statistics/models/CompositionalStatsModel.java @@ -1,103 +1,103 @@ -/*** - * 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 . - */ -package com.endlessloopsoftware.ego.client.statistics.models; - -import java.util.Iterator; -import java.util.Set; - -import javax.swing.JTable; - -import com.endlessloopsoftware.ego.client.statistics.Statistics; - -public class CompositionalStatsModel extends StatTableModel -{ - private Integer[][] componentArray; - private int componentDepth; - - public CompositionalStatsModel(Statistics stats) - { - super(stats); - initModel(); - } - - private void initModel() - { - Iterator> it = stats.componentSet.iterator(); - int index = 0; - int maxCount = 0; - - componentArray = new Integer[stats.componentSet.size()][]; - - while (it.hasNext()) - { - Set s = it.next(); - - componentArray[index] = new Integer[s.size()]; - s.toArray(componentArray[index]); - - if (s.size() > maxCount) - { - maxCount = s.size(); - } - - index++; - } - - componentDepth = maxCount; - } - - public void update() - { - initModel(); - this.fireTableStructureChanged(); - fireTableDataChanged(); - } - - public int getColumnCount() - { - return (componentArray.length); - } - - public int getRowCount() - { - return (componentDepth); - } - - public Object getValueAt(int rowIndex, int columnIndex) - { - if (rowIndex < componentArray[columnIndex].length) - { - return (stats.alterList[componentArray[columnIndex][rowIndex].intValue()]); - } - else - { - return null; - } - } - - public String getColumnName(int column) - { - return ("Component " + (column + 1)); - } - - public int getResizeMode() - { - return JTable.AUTO_RESIZE_OFF; - } -} +/*** + * 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 . + */ +package com.endlessloopsoftware.ego.client.statistics.models; + +import java.util.Iterator; +import java.util.Set; + +import javax.swing.JTable; + +import com.endlessloopsoftware.ego.client.statistics.Statistics; + +public class CompositionalStatsModel extends StatTableModel +{ + private Integer[][] componentArray; + private int componentDepth; + + public CompositionalStatsModel(Statistics stats) + { + super(stats); + initModel(); + } + + private void initModel() + { + Iterator> it = stats.componentSet.iterator(); + int index = 0; + int maxCount = 0; + + componentArray = new Integer[stats.componentSet.size()][]; + + while (it.hasNext()) + { + Set s = it.next(); + + componentArray[index] = new Integer[s.size()]; + s.toArray(componentArray[index]); + + if (s.size() > maxCount) + { + maxCount = s.size(); + } + + index++; + } + + componentDepth = maxCount; + } + + public void update() + { + initModel(); + this.fireTableStructureChanged(); + fireTableDataChanged(); + } + + public int getColumnCount() + { + return (componentArray.length); + } + + public int getRowCount() + { + return (componentDepth); + } + + public Object getValueAt(int rowIndex, int columnIndex) + { + if (rowIndex < componentArray[columnIndex].length) + { + return (stats.alterList[componentArray[columnIndex][rowIndex].intValue()]); + } + else + { + return null; + } + } + + public String getColumnName(int column) + { + return ("Component " + (column + 1)); + } + + public int getResizeMode() + { + return JTable.AUTO_RESIZE_OFF; + } +} diff --git a/src/com/endlessloopsoftware/ego/client/statistics/models/DegreeModel.java b/src/main/java/com/endlessloopsoftware/ego/client/statistics/models/DegreeModel.java similarity index 95% rename from src/com/endlessloopsoftware/ego/client/statistics/models/DegreeModel.java rename to src/main/java/com/endlessloopsoftware/ego/client/statistics/models/DegreeModel.java index ae6642c..3d2200e 100644 --- a/src/com/endlessloopsoftware/ego/client/statistics/models/DegreeModel.java +++ b/src/main/java/com/endlessloopsoftware/ego/client/statistics/models/DegreeModel.java @@ -1,85 +1,85 @@ -/*** - * 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 . - */ -package com.endlessloopsoftware.ego.client.statistics.models; - -import javax.swing.JTable; - -import com.endlessloopsoftware.ego.client.statistics.Statistics; - -public class DegreeModel extends StatTableModel -{ - public DegreeModel(Statistics stats) - { - super(stats); - } - - public int getColumnCount() - { - return (3); - } - - public int getRowCount() - { - return (stats.degreeArray.length); - } - - public Object getValueAt(int rowIndex, int columnIndex) - { - try - { - if (columnIndex == 0) - { - return (stats.alterList[rowIndex]); - } - else if (columnIndex == 1) - { - return (new Integer(stats.degreeArray[rowIndex])); - } - else - { - return (new Float(stats.degreeArray[rowIndex] / ((float) (stats.proximityMatrix.length - 1)))); - } - } - catch (Exception ex) - { - throw new RuntimeException(ex); - } - } - - public String getColumnName(int column) - { - if (column == 0) - { - return ("Alter"); - } - else if (column == 1) - { - return ("Raw"); - } - else - { - return ("Normalized"); - } - } - - public int getResizeMode() - { - return JTable.AUTO_RESIZE_ALL_COLUMNS; - } -} +/*** + * 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 . + */ +package com.endlessloopsoftware.ego.client.statistics.models; + +import javax.swing.JTable; + +import com.endlessloopsoftware.ego.client.statistics.Statistics; + +public class DegreeModel extends StatTableModel +{ + public DegreeModel(Statistics stats) + { + super(stats); + } + + public int getColumnCount() + { + return (3); + } + + public int getRowCount() + { + return (stats.degreeArray.length); + } + + public Object getValueAt(int rowIndex, int columnIndex) + { + try + { + if (columnIndex == 0) + { + return (stats.alterList[rowIndex]); + } + else if (columnIndex == 1) + { + return (new Integer(stats.degreeArray[rowIndex])); + } + else + { + return (new Float(stats.degreeArray[rowIndex] / ((float) (stats.proximityMatrix.length - 1)))); + } + } + catch (Exception ex) + { + throw new RuntimeException(ex); + } + } + + public String getColumnName(int column) + { + if (column == 0) + { + return ("Alter"); + } + else if (column == 1) + { + return ("Raw"); + } + else + { + return ("Normalized"); + } + } + + public int getResizeMode() + { + return JTable.AUTO_RESIZE_ALL_COLUMNS; + } +} diff --git a/src/com/endlessloopsoftware/ego/client/statistics/models/InterviewSummaryModel.java b/src/main/java/com/endlessloopsoftware/ego/client/statistics/models/InterviewSummaryModel.java similarity index 95% rename from src/com/endlessloopsoftware/ego/client/statistics/models/InterviewSummaryModel.java rename to src/main/java/com/endlessloopsoftware/ego/client/statistics/models/InterviewSummaryModel.java index 897c0ef..0b2633e 100644 --- a/src/com/endlessloopsoftware/ego/client/statistics/models/InterviewSummaryModel.java +++ b/src/main/java/com/endlessloopsoftware/ego/client/statistics/models/InterviewSummaryModel.java @@ -1,128 +1,128 @@ -/*** - * 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 . - */ -package com.endlessloopsoftware.ego.client.statistics.models; - -import javax.swing.JTable; - -import com.endlessloopsoftware.ego.client.statistics.Statistics; - -public class InterviewSummaryModel extends StatTableModel -{ - public InterviewSummaryModel(Statistics stats) - { - super(stats); - } - - public int getColumnCount() - { - if (stats.adjacencyMatrix.length > 0) - { - return 3; - } - else - { - return 1; - } - } - - public Object getValueAt(int rowIndex, int columnIndex) - { - switch (columnIndex) - { - case 0 : - switch (rowIndex) - { - case 0 : - return ("Degree Centrality Maximum"); - case 1 : - return ("Closeness Centrality Maximum"); - case 2 : - return ("Betweenness Centrality Maximum"); - case 3 : - return ("Number of Cliques"); - case 4 : - return ("Number of Components"); - default : - return (null); - } - - case 1 : - switch (rowIndex) - { - case 0 : - return (stats.mostCentralDegreeAlterName); - case 1 : - return (stats.mostCentralClosenessAlterName); - case 2 : - return (stats.mostCentralBetweenAlterName); - case 3 : - return (new Integer(stats.cliqueSet.size())); - case 4 : - return (new Integer(stats.componentSet.size())); - default : - return (null); - } - - case 2 : - switch (rowIndex) - { - case 0 : - return (new Integer(stats.mostCentralDegreeAlterValue)); - case 1 : - return (new Float(stats.mostCentralClosenessAlterValue)); - case 2 : - return (new Float(stats.mostCentralBetweenAlterValue)); - default : - return (null); - } - - default : - return (null); - } - } - - public int getRowCount() - { - if (stats.adjacencyMatrix.length > 0) - { - return 5; - } - else - { - return 0; - } - } - - public String getColumnName(int column) - { - if (stats.adjacencyMatrix.length > 0) - { - return null; - } - else - { - return ("No Structural Measures question specified in study"); - } - } - - public int getResizeMode() - { - return JTable.AUTO_RESIZE_ALL_COLUMNS; - } -} +/*** + * 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 . + */ +package com.endlessloopsoftware.ego.client.statistics.models; + +import javax.swing.JTable; + +import com.endlessloopsoftware.ego.client.statistics.Statistics; + +public class InterviewSummaryModel extends StatTableModel +{ + public InterviewSummaryModel(Statistics stats) + { + super(stats); + } + + public int getColumnCount() + { + if (stats.adjacencyMatrix.length > 0) + { + return 3; + } + else + { + return 1; + } + } + + public Object getValueAt(int rowIndex, int columnIndex) + { + switch (columnIndex) + { + case 0 : + switch (rowIndex) + { + case 0 : + return ("Degree Centrality Maximum"); + case 1 : + return ("Closeness Centrality Maximum"); + case 2 : + return ("Betweenness Centrality Maximum"); + case 3 : + return ("Number of Cliques"); + case 4 : + return ("Number of Components"); + default : + return (null); + } + + case 1 : + switch (rowIndex) + { + case 0 : + return (stats.mostCentralDegreeAlterName); + case 1 : + return (stats.mostCentralClosenessAlterName); + case 2 : + return (stats.mostCentralBetweenAlterName); + case 3 : + return (new Integer(stats.cliqueSet.size())); + case 4 : + return (new Integer(stats.componentSet.size())); + default : + return (null); + } + + case 2 : + switch (rowIndex) + { + case 0 : + return (new Integer(stats.mostCentralDegreeAlterValue)); + case 1 : + return (new Float(stats.mostCentralClosenessAlterValue)); + case 2 : + return (new Float(stats.mostCentralBetweenAlterValue)); + default : + return (null); + } + + default : + return (null); + } + } + + public int getRowCount() + { + if (stats.adjacencyMatrix.length > 0) + { + return 5; + } + else + { + return 0; + } + } + + public String getColumnName(int column) + { + if (stats.adjacencyMatrix.length > 0) + { + return null; + } + else + { + return ("No Structural Measures question specified in study"); + } + } + + public int getResizeMode() + { + return JTable.AUTO_RESIZE_ALL_COLUMNS; + } +} diff --git a/src/com/endlessloopsoftware/ego/client/statistics/models/QSummaryModel.java b/src/main/java/com/endlessloopsoftware/ego/client/statistics/models/QSummaryModel.java similarity index 95% rename from src/com/endlessloopsoftware/ego/client/statistics/models/QSummaryModel.java rename to src/main/java/com/endlessloopsoftware/ego/client/statistics/models/QSummaryModel.java index 855a43d..40cdffc 100644 --- a/src/com/endlessloopsoftware/ego/client/statistics/models/QSummaryModel.java +++ b/src/main/java/com/endlessloopsoftware/ego/client/statistics/models/QSummaryModel.java @@ -1,136 +1,136 @@ -/*** - * 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 . - */ -package com.endlessloopsoftware.ego.client.statistics.models; - -import javax.swing.JTable; - -import com.endlessloopsoftware.ego.client.statistics.Statistics; -import com.endlessloopsoftware.egonet.Shared; - -public class QSummaryModel extends StatTableModel -{ - private int answerDepth; - - public QSummaryModel(Statistics stats) - { - super(stats); - initModel(); - } - - private void initModel() - { - int maxCount = 0; - for (int i = 0; i < stats.alterStatArray.length; i++) - { - if (stats.alterStatArray[i].answerTotals.length > maxCount) - { - maxCount = stats.alterStatArray[i].answerTotals.length; - } - } - - answerDepth = maxCount; - } - - public void update() - { - initModel(); - this.fireTableStructureChanged(); - fireTableDataChanged(); - } - - public int getColumnCount() - { - return (answerDepth + 1); - } - - public int getRowCount() - { - return (stats.alterStatArray.length); - } - - public Object getValueAt(int rowIndex, int columnIndex) - { - if (columnIndex == 0) - { - return (stats.alterStatArray[rowIndex].qTitle); - } - else if (columnIndex <= stats.alterStatArray[rowIndex].answerTotals.length) - { - if ((stats.alterStatArray[rowIndex].answerType == Shared.AnswerType.NUMERICAL) && (columnIndex == 1)) - { - return ( - "Average: " - + stats.alterStatArray[rowIndex].answerTotals[0] / stats.alterStatArray[rowIndex].answerCount); - } - else if (stats.alterStatArray[rowIndex].answerType == Shared.AnswerType.CATEGORICAL) - { - String s = null; - try - { - if (stats.alterStatArray[rowIndex].answerCount == 0) - { - s = stats.alterStatArray[rowIndex].answerText[columnIndex - 1] + ": n/a"; - } - else - { - s = - stats.alterStatArray[rowIndex].answerText[columnIndex - - 1] - + ": " - + ((stats.alterStatArray[rowIndex].answerTotals[columnIndex - 1] * 100) - / stats.alterStatArray[rowIndex].answerCount) - + "%"; - } - } - catch (Exception ex) - { - s = "Statistics Generation Error"; - System.err.println("Error in StatTableModel::getValueAt; " + ex); - } - - return s; - } - else - { - return null; - } - } - else - { - return null; - } - } - - public String getColumnName(int column) - { - if (column == 0) - { - return ("Question"); - } - else - { - return ("Answer " + column); - } - } - - public int getResizeMode() - { - return JTable.AUTO_RESIZE_OFF; - } -} +/*** + * 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 . + */ +package com.endlessloopsoftware.ego.client.statistics.models; + +import javax.swing.JTable; + +import com.endlessloopsoftware.ego.client.statistics.Statistics; +import com.endlessloopsoftware.egonet.Shared; + +public class QSummaryModel extends StatTableModel +{ + private int answerDepth; + + public QSummaryModel(Statistics stats) + { + super(stats); + initModel(); + } + + private void initModel() + { + int maxCount = 0; + for (int i = 0; i < stats.alterStatArray.length; i++) + { + if (stats.alterStatArray[i].answerTotals.length > maxCount) + { + maxCount = stats.alterStatArray[i].answerTotals.length; + } + } + + answerDepth = maxCount; + } + + public void update() + { + initModel(); + this.fireTableStructureChanged(); + fireTableDataChanged(); + } + + public int getColumnCount() + { + return (answerDepth + 1); + } + + public int getRowCount() + { + return (stats.alterStatArray.length); + } + + public Object getValueAt(int rowIndex, int columnIndex) + { + if (columnIndex == 0) + { + return (stats.alterStatArray[rowIndex].qTitle); + } + else if (columnIndex <= stats.alterStatArray[rowIndex].answerTotals.length) + { + if ((stats.alterStatArray[rowIndex].answerType == Shared.AnswerType.NUMERICAL) && (columnIndex == 1)) + { + return ( + "Average: " + + stats.alterStatArray[rowIndex].answerTotals[0] / stats.alterStatArray[rowIndex].answerCount); + } + else if (stats.alterStatArray[rowIndex].answerType == Shared.AnswerType.CATEGORICAL) + { + String s = null; + try + { + if (stats.alterStatArray[rowIndex].answerCount == 0) + { + s = stats.alterStatArray[rowIndex].answerText[columnIndex - 1] + ": n/a"; + } + else + { + s = + stats.alterStatArray[rowIndex].answerText[columnIndex + - 1] + + ": " + + ((stats.alterStatArray[rowIndex].answerTotals[columnIndex - 1] * 100) + / stats.alterStatArray[rowIndex].answerCount) + + "%"; + } + } + catch (Exception ex) + { + s = "Statistics Generation Error"; + System.err.println("Error in StatTableModel::getValueAt; " + ex); + } + + return s; + } + else + { + return null; + } + } + else + { + return null; + } + } + + public String getColumnName(int column) + { + if (column == 0) + { + return ("Question"); + } + else + { + return ("Answer " + column); + } + } + + public int getResizeMode() + { + return JTable.AUTO_RESIZE_OFF; + } +} diff --git a/src/com/endlessloopsoftware/ego/client/statistics/models/StatTableModel.java b/src/main/java/com/endlessloopsoftware/ego/client/statistics/models/StatTableModel.java similarity index 96% rename from src/com/endlessloopsoftware/ego/client/statistics/models/StatTableModel.java rename to src/main/java/com/endlessloopsoftware/ego/client/statistics/models/StatTableModel.java index 4c618ad..441cb12 100644 --- a/src/com/endlessloopsoftware/ego/client/statistics/models/StatTableModel.java +++ b/src/main/java/com/endlessloopsoftware/ego/client/statistics/models/StatTableModel.java @@ -1,54 +1,54 @@ -/*** - * 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 . - */ -package com.endlessloopsoftware.ego.client.statistics.models; -import javax.swing.JTable; -import javax.swing.table.AbstractTableModel; - -import com.endlessloopsoftware.ego.client.statistics.Statistics; - -public abstract class StatTableModel extends AbstractTableModel -{ - public Statistics stats; - - public StatTableModel(Statistics stats) - { - this.stats = stats; - } - - public StatTableModel() {} - - public int getResizeMode() - { - return JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS; - } - - public void update() - { - this.fireTableStructureChanged(); - fireTableDataChanged(); - } - - /** - * @param stats The stats to set. - */ - public void setStats(Statistics stats) - { - this.stats = stats; - } -} +/*** + * 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 . + */ +package com.endlessloopsoftware.ego.client.statistics.models; +import javax.swing.JTable; +import javax.swing.table.AbstractTableModel; + +import com.endlessloopsoftware.ego.client.statistics.Statistics; + +public abstract class StatTableModel extends AbstractTableModel +{ + public Statistics stats; + + public StatTableModel(Statistics stats) + { + this.stats = stats; + } + + public StatTableModel() {} + + public int getResizeMode() + { + return JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS; + } + + public void update() + { + this.fireTableStructureChanged(); + fireTableDataChanged(); + } + + /** + * @param stats The stats to set. + */ + public void setStats(Statistics stats) + { + this.stats = stats; + } +} diff --git a/src/com/endlessloopsoftware/egonet/.cvsignore b/src/main/java/com/endlessloopsoftware/egonet/.cvsignore similarity index 100% rename from src/com/endlessloopsoftware/egonet/.cvsignore rename to src/main/java/com/endlessloopsoftware/egonet/.cvsignore diff --git a/src/com/endlessloopsoftware/egonet/Answer.java b/src/main/java/com/endlessloopsoftware/egonet/Answer.java similarity index 96% rename from src/com/endlessloopsoftware/egonet/Answer.java rename to src/main/java/com/endlessloopsoftware/egonet/Answer.java index fa13a89..3528cf8 100644 --- a/src/com/endlessloopsoftware/egonet/Answer.java +++ b/src/main/java/com/endlessloopsoftware/egonet/Answer.java @@ -1,139 +1,139 @@ -/*** - * 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 . - */ -package com.endlessloopsoftware.egonet; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Date; -import java.util.List; -import java.text.*; - -public class Answer implements Cloneable { - /** - * Unique ID for every question - */ - public Long questionId; - - /** - * Represents the alter or alter pair that this answer is about. It may be a - * single alter for alter questions, or two alters for an alter pair - * question. - */ - private List alters; - - private boolean _answered = false; - - public boolean isAnswered() { - return _answered; - } - - public void setAnswered(boolean _answered) { - this._answered = _answered; - } - - public boolean adjacent; - - private int value; - - private int index; - - public String string; - - public String timestamp; - - public static final int NO_ANSWER = -1; - public static final int ALL_ADJACENT = -2; - - public Answer(Long Id) { - this(Id, null); - } - - public Answer(Long Id, int[] alters) { - //logger.info("New answer object created with id="+Id+" and alters: " + Arrays.asList(alters)); - questionId = Id; - setAnswered(false); - adjacent = false; - setValue(-1); - string = ""; - timestamp = DateFormat.getDateInstance().format(new Date()); - - if (alters == null) { - this.alters = new ArrayList(); - } else { - this.alters = new ArrayList(alters.length); - for(Integer a : alters) - this.alters.add(a); - } - } - - public Integer firstAlter() - { - return alters.get(0); - } - - public Integer secondAlter() - { - return alters.get(1); - } - - public boolean hasTwoAlters() - { - return alters.size() > 1; - } - - public boolean hasAtLeastOneAlter() - { - return alters.size() > 0; - } - - public Object clone() throws CloneNotSupportedException { - return (super.clone()); - } - - public String toString() { - return string == null ? getValue()+"" : string; - } - - public String getString() { - String str = ""; - str = "questionId=" + questionId + ", answered=" + isAnswered() + ", adjacent=" + adjacent + ", string=" + string + ", index="+getIndex()+", value=" + getValue(); - return str; - - } - - public void setValue(int value) { - this.value = value; - } - - public int getValue() { - return value; - } - - public void setIndex(int index) { - this.index = index; - } - - public int getIndex() { - return index; - } - - public List getAlters() - { - return Collections.unmodifiableList(alters); - } +/*** + * 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 . + */ +package com.endlessloopsoftware.egonet; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.text.*; + +public class Answer implements Cloneable { + /** + * Unique ID for every question + */ + public Long questionId; + + /** + * Represents the alter or alter pair that this answer is about. It may be a + * single alter for alter questions, or two alters for an alter pair + * question. + */ + private List alters; + + private boolean _answered = false; + + public boolean isAnswered() { + return _answered; + } + + public void setAnswered(boolean _answered) { + this._answered = _answered; + } + + public boolean adjacent; + + private int value; + + private int index; + + public String string; + + public String timestamp; + + public static final int NO_ANSWER = -1; + public static final int ALL_ADJACENT = -2; + + public Answer(Long Id) { + this(Id, null); + } + + public Answer(Long Id, int[] alters) { + //logger.info("New answer object created with id="+Id+" and alters: " + Arrays.asList(alters)); + questionId = Id; + setAnswered(false); + adjacent = false; + setValue(-1); + string = ""; + timestamp = DateFormat.getDateInstance().format(new Date()); + + if (alters == null) { + this.alters = new ArrayList(); + } else { + this.alters = new ArrayList(alters.length); + for(Integer a : alters) + this.alters.add(a); + } + } + + public Integer firstAlter() + { + return alters.get(0); + } + + public Integer secondAlter() + { + return alters.get(1); + } + + public boolean hasTwoAlters() + { + return alters.size() > 1; + } + + public boolean hasAtLeastOneAlter() + { + return alters.size() > 0; + } + + public Object clone() throws CloneNotSupportedException { + return (super.clone()); + } + + public String toString() { + return string == null ? getValue()+"" : string; + } + + public String getString() { + String str = ""; + str = "questionId=" + questionId + ", answered=" + isAnswered() + ", adjacent=" + adjacent + ", string=" + string + ", index="+getIndex()+", value=" + getValue(); + return str; + + } + + public void setValue(int value) { + this.value = value; + } + + public int getValue() { + return value; + } + + public void setIndex(int index) { + this.index = index; + } + + public int getIndex() { + return index; + } + + public List getAlters() + { + return Collections.unmodifiableList(alters); + } } \ No newline at end of file diff --git a/src/com/endlessloopsoftware/egonet/Interview.java b/src/main/java/com/endlessloopsoftware/egonet/Interview.java similarity index 100% rename from src/com/endlessloopsoftware/egonet/Interview.java rename to src/main/java/com/endlessloopsoftware/egonet/Interview.java diff --git a/src/com/endlessloopsoftware/egonet/QuestionLink.java b/src/main/java/com/endlessloopsoftware/egonet/QuestionLink.java similarity index 96% rename from src/com/endlessloopsoftware/egonet/QuestionLink.java rename to src/main/java/com/endlessloopsoftware/egonet/QuestionLink.java index 931ba6b..40c15aa 100644 --- a/src/com/endlessloopsoftware/egonet/QuestionLink.java +++ b/src/main/java/com/endlessloopsoftware/egonet/QuestionLink.java @@ -1,50 +1,50 @@ -/*** - * 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 . - */ -package com.endlessloopsoftware.egonet; -public class QuestionLink implements Cloneable -{ - private Answer answer = null; - - public Object clone() - throws CloneNotSupportedException - { - QuestionLink q; - - q = (QuestionLink) super.clone(); - - if (isActive()) - { - q.setAnswer((Answer) this.getAnswer().clone()); - } - - return(q); - } - - public void setAnswer(Answer answer) { - this.answer = answer; - } - - public Answer getAnswer() { - return answer; - } - - public boolean isActive() { - return answer != null; - } +/*** + * 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 . + */ +package com.endlessloopsoftware.egonet; +public class QuestionLink implements Cloneable +{ + private Answer answer = null; + + public Object clone() + throws CloneNotSupportedException + { + QuestionLink q; + + q = (QuestionLink) super.clone(); + + if (isActive()) + { + q.setAnswer((Answer) this.getAnswer().clone()); + } + + return(q); + } + + public void setAnswer(Answer answer) { + this.answer = answer; + } + + public Answer getAnswer() { + return answer; + } + + public boolean isActive() { + return answer != null; + } } \ No newline at end of file diff --git a/src/com/endlessloopsoftware/egonet/QuestionList.java b/src/main/java/com/endlessloopsoftware/egonet/QuestionList.java similarity index 96% rename from src/com/endlessloopsoftware/egonet/QuestionList.java rename to src/main/java/com/endlessloopsoftware/egonet/QuestionList.java index 641e513..f9083ac 100644 --- a/src/com/endlessloopsoftware/egonet/QuestionList.java +++ b/src/main/java/com/endlessloopsoftware/egonet/QuestionList.java @@ -1,77 +1,77 @@ -/*** - * 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 . - */ -package com.endlessloopsoftware.egonet; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.Set; - -import org.egonet.model.question.Question; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * A map of question id (long) to question object - * @author martins - * - */ -public class QuestionList extends HashMap -{ - final private static Logger logger = LoggerFactory.getLogger(QuestionList.class); - - public void addQuestion(Question q) - { - logger.debug("Question added: " + q.getString()); - put(q.UniqueId, q); - } - - /**** - * Returns question from map identified by its UniqueId - * @param l UniqueId of question - * @return q question in list - */ - public Question getQuestion(Long l) - { - return get(l); - } - - public String dump() - { - StringBuffer buffer = new StringBuffer(); - - Set keys = keySet(); - for (Iterator it = keys.iterator(); it.hasNext();) - { - Object key = it.next(); - buffer.append("[" + key + "," + get(key) + "]\n"); - } - - return buffer.toString(); - } - - public boolean contains(long questionId) - { - return containsKey(questionId); - } - - public boolean contains(Question question) - { - return containsValue(question); - } +/*** + * 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 . + */ +package com.endlessloopsoftware.egonet; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Set; + +import org.egonet.model.question.Question; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * A map of question id (long) to question object + * @author martins + * + */ +public class QuestionList extends HashMap +{ + final private static Logger logger = LoggerFactory.getLogger(QuestionList.class); + + public void addQuestion(Question q) + { + logger.debug("Question added: " + q.getString()); + put(q.UniqueId, q); + } + + /**** + * Returns question from map identified by its UniqueId + * @param l UniqueId of question + * @return q question in list + */ + public Question getQuestion(Long l) + { + return get(l); + } + + public String dump() + { + StringBuffer buffer = new StringBuffer(); + + Set keys = keySet(); + for (Iterator it = keys.iterator(); it.hasNext();) + { + Object key = it.next(); + buffer.append("[" + key + "," + get(key) + "]\n"); + } + + return buffer.toString(); + } + + public boolean contains(long questionId) + { + return containsKey(questionId); + } + + public boolean contains(Question question) + { + return containsValue(question); + } } \ No newline at end of file diff --git a/src/com/endlessloopsoftware/egonet/Shared.java b/src/main/java/com/endlessloopsoftware/egonet/Shared.java similarity index 100% rename from src/com/endlessloopsoftware/egonet/Shared.java rename to src/main/java/com/endlessloopsoftware/egonet/Shared.java diff --git a/src/com/endlessloopsoftware/egonet/Study.java b/src/main/java/com/endlessloopsoftware/egonet/Study.java similarity index 100% rename from src/com/endlessloopsoftware/egonet/Study.java rename to src/main/java/com/endlessloopsoftware/egonet/Study.java diff --git a/src/org/egonet/exceptions/CorruptedInterviewException.java b/src/main/java/org/egonet/exceptions/CorruptedInterviewException.java similarity index 96% rename from src/org/egonet/exceptions/CorruptedInterviewException.java rename to src/main/java/org/egonet/exceptions/CorruptedInterviewException.java index eede74c..1a9794a 100644 --- a/src/org/egonet/exceptions/CorruptedInterviewException.java +++ b/src/main/java/org/egonet/exceptions/CorruptedInterviewException.java @@ -1,39 +1,39 @@ -/*** - * 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 . - */ -package org.egonet.exceptions; - -public class CorruptedInterviewException extends org.egonet.exceptions.EgonetException -{ - - public CorruptedInterviewException() { - super(); - } - - public CorruptedInterviewException(String s, Throwable t) { - super(s, t); - } - - public CorruptedInterviewException(String s) { - super(s); - } - - public CorruptedInterviewException(Throwable t) { - super(t); - } -} +/*** + * 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 . + */ +package org.egonet.exceptions; + +public class CorruptedInterviewException extends org.egonet.exceptions.EgonetException +{ + + public CorruptedInterviewException() { + super(); + } + + public CorruptedInterviewException(String s, Throwable t) { + super(s, t); + } + + public CorruptedInterviewException(String s) { + super(s); + } + + public CorruptedInterviewException(Throwable t) { + super(t); + } +} diff --git a/src/org/egonet/exceptions/DuplicateQuestionException.java b/src/main/java/org/egonet/exceptions/DuplicateQuestionException.java similarity index 96% rename from src/org/egonet/exceptions/DuplicateQuestionException.java rename to src/main/java/org/egonet/exceptions/DuplicateQuestionException.java index f414ffd..69cae04 100644 --- a/src/org/egonet/exceptions/DuplicateQuestionException.java +++ b/src/main/java/org/egonet/exceptions/DuplicateQuestionException.java @@ -1,43 +1,43 @@ -/*** - * 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 . - */ -package org.egonet.exceptions; - -public class DuplicateQuestionException extends EgonetException -{ - - public DuplicateQuestionException() - { - super(); - } - - public DuplicateQuestionException(String s, Throwable t) - { - super(s, t); - } - - public DuplicateQuestionException(String s) - { - super(s); - } - - public DuplicateQuestionException(Throwable t) - { - super(t); - } -} +/*** + * 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 . + */ +package org.egonet.exceptions; + +public class DuplicateQuestionException extends EgonetException +{ + + public DuplicateQuestionException() + { + super(); + } + + public DuplicateQuestionException(String s, Throwable t) + { + super(s, t); + } + + public DuplicateQuestionException(String s) + { + super(s); + } + + public DuplicateQuestionException(Throwable t) + { + super(t); + } +} diff --git a/src/org/egonet/exceptions/EgonetException.java b/src/main/java/org/egonet/exceptions/EgonetException.java similarity index 100% rename from src/org/egonet/exceptions/EgonetException.java rename to src/main/java/org/egonet/exceptions/EgonetException.java diff --git a/src/org/egonet/exceptions/FileMismatchException.java b/src/main/java/org/egonet/exceptions/FileMismatchException.java similarity index 96% rename from src/org/egonet/exceptions/FileMismatchException.java rename to src/main/java/org/egonet/exceptions/FileMismatchException.java index 8d38415..bba808e 100644 --- a/src/org/egonet/exceptions/FileMismatchException.java +++ b/src/main/java/org/egonet/exceptions/FileMismatchException.java @@ -1,43 +1,43 @@ -/*** - * 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 . - */ -package org.egonet.exceptions; - -public class FileMismatchException extends org.egonet.exceptions.EgonetException -{ - public FileMismatchException() - { - super(); - } - - public FileMismatchException(String s) - { - super(s); - } - - public FileMismatchException(Throwable t) - { - super(t); - } - - public FileMismatchException(String s, Throwable t) - { - super(s,t); - } - -} +/*** + * 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 . + */ +package org.egonet.exceptions; + +public class FileMismatchException extends org.egonet.exceptions.EgonetException +{ + public FileMismatchException() + { + super(); + } + + public FileMismatchException(String s) + { + super(s); + } + + public FileMismatchException(Throwable t) + { + super(t); + } + + public FileMismatchException(String s, Throwable t) + { + super(s,t); + } + +} diff --git a/src/org/egonet/exceptions/FileNotSetException.java b/src/main/java/org/egonet/exceptions/FileNotSetException.java similarity index 100% rename from src/org/egonet/exceptions/FileNotSetException.java rename to src/main/java/org/egonet/exceptions/FileNotSetException.java diff --git a/src/org/egonet/exceptions/MalformedQuestionException.java b/src/main/java/org/egonet/exceptions/MalformedQuestionException.java similarity index 96% rename from src/org/egonet/exceptions/MalformedQuestionException.java rename to src/main/java/org/egonet/exceptions/MalformedQuestionException.java index fabed40..ab644eb 100644 --- a/src/org/egonet/exceptions/MalformedQuestionException.java +++ b/src/main/java/org/egonet/exceptions/MalformedQuestionException.java @@ -1,43 +1,43 @@ -/*** - * 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 . - */ -package org.egonet.exceptions; - -public class MalformedQuestionException extends org.egonet.exceptions.EgonetException -{ - public MalformedQuestionException() - { - super(); - } - - public MalformedQuestionException(String s) - { - super(s); - } - - public MalformedQuestionException(Throwable t) - { - super(t); - } - - public MalformedQuestionException(String s, Throwable t) - { - super(s,t); - } - -} +/*** + * 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 . + */ +package org.egonet.exceptions; + +public class MalformedQuestionException extends org.egonet.exceptions.EgonetException +{ + public MalformedQuestionException() + { + super(); + } + + public MalformedQuestionException(String s) + { + super(s); + } + + public MalformedQuestionException(Throwable t) + { + super(t); + } + + public MalformedQuestionException(String s, Throwable t) + { + super(s,t); + } + +} diff --git a/src/org/egonet/exceptions/MissingPairException.java b/src/main/java/org/egonet/exceptions/MissingPairException.java similarity index 96% rename from src/org/egonet/exceptions/MissingPairException.java rename to src/main/java/org/egonet/exceptions/MissingPairException.java index fdfa0cc..f148fd5 100644 --- a/src/org/egonet/exceptions/MissingPairException.java +++ b/src/main/java/org/egonet/exceptions/MissingPairException.java @@ -1,43 +1,43 @@ -/*** - * 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 . - */ -package org.egonet.exceptions; - -public class MissingPairException extends org.egonet.exceptions.EgonetException -{ - public MissingPairException() - { - super(); - } - - public MissingPairException(String s) - { - super(s); - } - - public MissingPairException(Throwable t) - { - super(t); - } - - public MissingPairException(String s, Throwable t) - { - super(s,t); - } - +/*** + * 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 . + */ +package org.egonet.exceptions; + +public class MissingPairException extends org.egonet.exceptions.EgonetException +{ + public MissingPairException() + { + super(); + } + + public MissingPairException(String s) + { + super(s); + } + + public MissingPairException(Throwable t) + { + super(t); + } + + public MissingPairException(String s, Throwable t) + { + super(s,t); + } + } \ No newline at end of file diff --git a/src/org/egonet/exceptions/StudyIdMismatchException.java b/src/main/java/org/egonet/exceptions/StudyIdMismatchException.java similarity index 100% rename from src/org/egonet/exceptions/StudyIdMismatchException.java rename to src/main/java/org/egonet/exceptions/StudyIdMismatchException.java diff --git a/src/org/egonet/graph/Graph.java b/src/main/java/org/egonet/graph/Graph.java similarity index 96% rename from src/org/egonet/graph/Graph.java rename to src/main/java/org/egonet/graph/Graph.java index ce15acc..1df210e 100644 --- a/src/org/egonet/graph/Graph.java +++ b/src/main/java/org/egonet/graph/Graph.java @@ -1,82 +1,82 @@ -package org.egonet.graph; - -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Random; -import java.util.Set; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; - -public class Graph { - - private Map> connections; - - public Graph() { - this(new HashMap>()); - } - public Graph(Map> connections) { - this.connections = new HashMap>(); - for(N node : connections.keySet()) { - Set set = Sets.newHashSet(); - set.addAll(connections.get(node)); - this.connections.put(node, set); - } - } - public static Graph random(Integer numNodes, Double density) { - Random rand = new Random(); - Map> connections = Maps.newHashMap(); - List nodes = Lists.newArrayList(); - for(Integer i = 0; i < numNodes; i++) { - nodes.add(i); - } - for(Integer i = 0; i < numNodes; i++) { - Collections.shuffle(nodes,rand); - Integer expectedConnections = (int) Math.round(density * (numNodes - 1)); - Integer spread = Math.min(expectedConnections, numNodes-1-expectedConnections); - Integer actual = rand.nextInt(2*spread+1) + expectedConnections - spread; - Set connectionsForThisNode = Sets.newHashSet(); - for(Integer j = 0; j < actual && j < nodes.size(); j++) { - if(nodes.get(j).equals(j)) { - actual++; - } else { - connectionsForThisNode.add(nodes.get(j)); - } - } - connections.put(i, connectionsForThisNode); - } - return new Graph(connections); - } - public Double density() { - Integer numNodes = connections.keySet().size(); - if(numNodes < 2) { - return 1.0; - } - Integer maxConnectionsTimesTwo = numNodes * (numNodes-1); - Integer actualConnectionsTimesTwo = 0; - for(N node : connections.keySet()) { - actualConnectionsTimesTwo += connections.get(node).size(); - } - return actualConnectionsTimesTwo < 1 ? 0.0 : - (actualConnectionsTimesTwo * 1.0 / maxConnectionsTimesTwo); - } - public Set nodes() { - return connections.keySet(); - } - public boolean connected(N n1, N n2) { - return connections.get(n1).contains(n2); - } - // TODO: Double distance(N n1, N n2) - public boolean equals(Object o) { - if(o == null || ! (o instanceof Graph)) { - return false; - } - return connections.equals(((Graph) o).connections); - } - public int hashCode() { - return connections.hashCode(); - } -} +package org.egonet.graph; + +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.Set; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; + +public class Graph { + + private Map> connections; + + public Graph() { + this(new HashMap>()); + } + public Graph(Map> connections) { + this.connections = new HashMap>(); + for(N node : connections.keySet()) { + Set set = Sets.newHashSet(); + set.addAll(connections.get(node)); + this.connections.put(node, set); + } + } + public static Graph random(Integer numNodes, Double density) { + Random rand = new Random(); + Map> connections = Maps.newHashMap(); + List nodes = Lists.newArrayList(); + for(Integer i = 0; i < numNodes; i++) { + nodes.add(i); + } + for(Integer i = 0; i < numNodes; i++) { + Collections.shuffle(nodes,rand); + Integer expectedConnections = (int) Math.round(density * (numNodes - 1)); + Integer spread = Math.min(expectedConnections, numNodes-1-expectedConnections); + Integer actual = rand.nextInt(2*spread+1) + expectedConnections - spread; + Set connectionsForThisNode = Sets.newHashSet(); + for(Integer j = 0; j < actual && j < nodes.size(); j++) { + if(nodes.get(j).equals(j)) { + actual++; + } else { + connectionsForThisNode.add(nodes.get(j)); + } + } + connections.put(i, connectionsForThisNode); + } + return new Graph(connections); + } + public Double density() { + Integer numNodes = connections.keySet().size(); + if(numNodes < 2) { + return 1.0; + } + Integer maxConnectionsTimesTwo = numNodes * (numNodes-1); + Integer actualConnectionsTimesTwo = 0; + for(N node : connections.keySet()) { + actualConnectionsTimesTwo += connections.get(node).size(); + } + return actualConnectionsTimesTwo < 1 ? 0.0 : + (actualConnectionsTimesTwo * 1.0 / maxConnectionsTimesTwo); + } + public Set nodes() { + return connections.keySet(); + } + public boolean connected(N n1, N n2) { + return connections.get(n1).contains(n2); + } + // TODO: Double distance(N n1, N n2) + public boolean equals(Object o) { + if(o == null || ! (o instanceof Graph)) { + return false; + } + return connections.equals(((Graph) o).connections); + } + public int hashCode() { + return connections.hashCode(); + } +} diff --git a/src/org/egonet/graph/IndexedSetOfSets.java b/src/main/java/org/egonet/graph/IndexedSetOfSets.java similarity index 94% rename from src/org/egonet/graph/IndexedSetOfSets.java rename to src/main/java/org/egonet/graph/IndexedSetOfSets.java index 8f7cbd5..73854e1 100644 --- a/src/org/egonet/graph/IndexedSetOfSets.java +++ b/src/main/java/org/egonet/graph/IndexedSetOfSets.java @@ -1,159 +1,159 @@ -package org.egonet.graph; - -import java.util.Collection; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; - -public class IndexedSetOfSets implements Set> { - - private Set> set; - private Map>> index; - - public Set> findByIndex(N item) { - Set> result = index.get(item); - return result == null ? new HashSet>() : result; - } - - public IndexedSetOfSets() { - clear(); - } - - public boolean add(Set item) { - if(set.contains(item)) { - return false; - } else { - set.add(item); - for(N n : item) { - Set> nIndex = index.get(n); - if(nIndex == null) { - nIndex = Sets.newHashSet(); - index.put(n, nIndex); - } - nIndex.add(item); - } - return true; - } - } - - public boolean addAll(Collection> items) { - boolean modified = false; - for(Set item : items) { - if(add(item)) { - modified = true; - } - } - return modified; - } - - public void clear() { - set = Sets.newHashSet(); - index = Maps.newHashMap(); - } - - public boolean contains(Object item) { - return set.contains(item); - } - - public boolean containsAll(Collection items) { - for(Object item : items) { - if(! contains(item)) { - return false; - } - } - return true; - } - - public boolean isEmpty() { - return set.isEmpty(); - } - - private class IndexedIterator implements Iterator> { - - private List> items; - int i = -1; - - public IndexedIterator() { - items = Lists.newArrayList(set); - } - - public boolean hasNext() { - return items.size() > i+1; - } - - public Set next() { - i++; - return items.get(i); - } - - public void remove() { - IndexedSetOfSets.this.remove(items.get(i)); - } - } - - public Iterator> iterator() { - return new IndexedIterator(); - } - - @SuppressWarnings("unchecked") - public boolean remove(Object obj) { - Set item = (Set) obj; - boolean modified = set.remove(item); - if(modified) { - for(N n : item) { - index.get(n).remove(item); - } - } - return modified; - } - - public boolean removeAll(Collection items) { - boolean modified = false; - for(Object item : items) { - if(remove(item)) { - modified = true; - } - } - return modified; - } - - @SuppressWarnings("unchecked") - public boolean retainAll(Collection items) { - Set> keepers = Sets.newHashSet(); - keepers.addAll((Collection>) items); - boolean modified = false; - Iterator> iter = iterator(); - while(iter.hasNext()) { - Set item = iter.next(); - if(! keepers.contains(item)) { - remove(item); - } - } - return modified; - } - - public int size() { - return set.size(); - } - - public Object[] toArray() { - return set.toArray(); - } - - public T[] toArray(T[] t) { - return set.toArray(t); - } - - public boolean equals(Object obj) { - return set.equals(obj); - } - public int hashCode() { - return set.hashCode(); - } -} +package org.egonet.graph; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; + +public class IndexedSetOfSets implements Set> { + + private Set> set; + private Map>> index; + + public Set> findByIndex(N item) { + Set> result = index.get(item); + return result == null ? new HashSet>() : result; + } + + public IndexedSetOfSets() { + clear(); + } + + public boolean add(Set item) { + if(set.contains(item)) { + return false; + } else { + set.add(item); + for(N n : item) { + Set> nIndex = index.get(n); + if(nIndex == null) { + nIndex = Sets.newHashSet(); + index.put(n, nIndex); + } + nIndex.add(item); + } + return true; + } + } + + public boolean addAll(Collection> items) { + boolean modified = false; + for(Set item : items) { + if(add(item)) { + modified = true; + } + } + return modified; + } + + public void clear() { + set = Sets.newHashSet(); + index = Maps.newHashMap(); + } + + public boolean contains(Object item) { + return set.contains(item); + } + + public boolean containsAll(Collection items) { + for(Object item : items) { + if(! contains(item)) { + return false; + } + } + return true; + } + + public boolean isEmpty() { + return set.isEmpty(); + } + + private class IndexedIterator implements Iterator> { + + private List> items; + int i = -1; + + public IndexedIterator() { + items = Lists.newArrayList(set); + } + + public boolean hasNext() { + return items.size() > i+1; + } + + public Set next() { + i++; + return items.get(i); + } + + public void remove() { + IndexedSetOfSets.this.remove(items.get(i)); + } + } + + public Iterator> iterator() { + return new IndexedIterator(); + } + + @SuppressWarnings("unchecked") + public boolean remove(Object obj) { + Set item = (Set) obj; + boolean modified = set.remove(item); + if(modified) { + for(N n : item) { + index.get(n).remove(item); + } + } + return modified; + } + + public boolean removeAll(Collection items) { + boolean modified = false; + for(Object item : items) { + if(remove(item)) { + modified = true; + } + } + return modified; + } + + @SuppressWarnings("unchecked") + public boolean retainAll(Collection items) { + Set> keepers = Sets.newHashSet(); + keepers.addAll((Collection>) items); + boolean modified = false; + Iterator> iter = iterator(); + while(iter.hasNext()) { + Set item = iter.next(); + if(! keepers.contains(item)) { + remove(item); + } + } + return modified; + } + + public int size() { + return set.size(); + } + + public Object[] toArray() { + return set.toArray(); + } + + public T[] toArray(T[] t) { + return set.toArray(t); + } + + public boolean equals(Object obj) { + return set.equals(obj); + } + public int hashCode() { + return set.hashCode(); + } +} diff --git a/src/org/egonet/graph/KPlexes.java b/src/main/java/org/egonet/graph/KPlexes.java similarity index 97% rename from src/org/egonet/graph/KPlexes.java rename to src/main/java/org/egonet/graph/KPlexes.java index 4c15ae3..5bd0a0e 100644 --- a/src/org/egonet/graph/KPlexes.java +++ b/src/main/java/org/egonet/graph/KPlexes.java @@ -1,177 +1,177 @@ -package org.egonet.graph; - -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; - -public class KPlexes { - // graph is Map> - // kplex is > - public Map connectionsByNode(Map> graph) { - Map result = Maps.newHashMap(); - for(N n : graph.keySet()) { - result.put(n, graph.get(n).size()); - } - return result; - } - // This is similar to hIndex. - // Connectedness of N for having N connections to nodes with N connections. - public Map connectednessByNode(Map> graph) { - Map connectionsByNode = connectionsByNode(graph); - Map results = Maps.newHashMap(); - for(N n1 : graph.keySet()) { - List connectednessOfConnections = Lists.newArrayList(); - for(N n2 : graph.get(n1)) { - connectednessOfConnections.add(connectionsByNode.get(n2)); - } - Collections.sort(connectednessOfConnections); - Collections.reverse(connectednessOfConnections); - Integer result = 0; - for(Integer i = 0; i < connectednessOfConnections.size(); i++) { - if(i < connectednessOfConnections.get(i)) { - result = i+1; - } - } - results.put(n1, result); - } - return results; - } - public Map connectionsWithinSubgroup(Map> graph, Set subgroup) { - Map result = Maps.newHashMap(); - for(N n : graph.keySet()) { - result.put(n, Sets.intersection(graph.get(n),subgroup).size()); - } - return result; - } - public Integer highestConnectedness(Map> graph) { - Integer highest = 0; - for(Integer connectedness : connectednessByNode(graph).values()) { - if(connectedness > highest) { - highest = connectedness; - } - } - return highest; - } - public Set meetConnectednessThreshold(Map> graph, Integer threshold) { - Set result = Sets.newHashSet(); - Map connectedness = connectednessByNode(graph); - for(N n : graph.keySet()) { - if(connectedness.get(n) > threshold-1) { - result.add(n); - } - } - return result; - } - public Integer largestPossibleKPlex(Map> graph, Integer k) { - return highestConnectedness(graph)+k; - } - public Set criticalNodesInKPlex(Map> graph, Set kplex, Integer k) { - Map connectionsWithinKPlex = connectionsWithinSubgroup(graph,kplex); - Set criticalNodes = Sets.newHashSet(); - for(N n : kplex) { - Integer connections = connectionsWithinKPlex.get(n); - if(connections == null) { - throw new RuntimeException("null connections for "+n+" in "+kplex+" of graph "+graph); - } - if(connections < kplex.size()-k+1) { - criticalNodes.add(n); - } - } - return criticalNodes; - } - public Set nodesThatCanBeAddedToKPlex(Map> graph, Set kplex, Integer k) { - if(kplex.isEmpty()) { - if(k > 0) { - return graph.keySet(); - } else { - return new HashSet(); - } - } - Set criticalNodes = criticalNodesInKPlex(graph, kplex, k); - if(criticalNodes.isEmpty()) { - Map connectionsWithinKPlex = connectionsWithinSubgroup(graph,kplex); - Set neighbors = Sets.newHashSet(); - for(N n : graph.keySet()) { - if(connectionsWithinKPlex.get(n) > 0) { - neighbors.add(n); - } - } - neighbors.removeAll(kplex); - return Sets.difference(neighbors,kplex); - } - Set eligible = Sets.difference(graph.keySet(),kplex); - for(N n : criticalNodes) { - // Must be neighbor of all critical nodes. - eligible = Sets.intersection(eligible, graph.get(n)); - } - return eligible; - } - public Map> createSubgraph(Map> graph, Set nodes) { - Map> subgraph = Maps.newHashMap(); - for(N n : nodes) { - subgraph.put(n, Sets.intersection(graph.get(n),nodes)); - } - return subgraph; - } - public Map> subgraphBoundingFinalKPlex( - Map> graph, Set kplex, Integer k, Integer targetSize) - { - Set includeInSubgraph = - Sets.union(kplex, - Sets.intersection( - meetConnectednessThreshold(graph,targetSize-k), - nodesThatCanBeAddedToKPlex(graph,kplex,k))); - return createSubgraph(graph,includeInSubgraph); - } - public N chooseNodeForInclusionInKPlex(Map> graph, Set kplex, Integer k) { - Integer highScore = 0; - N choice = null; - Map connectedness = connectednessByNode(graph); - Map connectionsWithinKPlex = connectionsWithinSubgroup(graph,kplex); - Set addable = nodesThatCanBeAddedToKPlex(graph, kplex, k); - for(N n : addable) { - Integer score = connectedness.get(n) + connectionsWithinKPlex.get(n); - if(score > highScore) { - highScore = score; - choice = n; - } - } - return choice; - } - public Set growKPlex(Map> graph, Set kplex, Integer k, Integer targetSize) { - Map> boundingGraph = subgraphBoundingFinalKPlex(graph,kplex,k,targetSize); - N newNode = chooseNodeForInclusionInKPlex(graph,kplex,k); - if(newNode == null) { - return kplex; - } - Set newKPlex = Sets.newHashSet(); - newKPlex.add(newNode); - newKPlex.addAll(kplex); - return growKPlex(boundingGraph,newKPlex,k,targetSize); - } - public Set findLargeKPlex(Map> graph, Integer k) { - Set largestFound = Sets.newHashSet(); - for(Integer targetSize = largestPossibleKPlex(graph, k); - targetSize > largestFound.size(); - targetSize--) - { - Set seeds = meetConnectednessThreshold(graph, targetSize-k); - Map> boundedGraph = createSubgraph(graph,seeds); - for(N seed : seeds) { - Set kplex = Sets.newHashSet(); - kplex.add(seed); - kplex = growKPlex(boundedGraph,kplex,k,targetSize); - if(kplex.size() > largestFound.size()) { - largestFound = kplex; - } - } - } - return largestFound; - } -} +package org.egonet.graph; + +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; + +public class KPlexes { + // graph is Map> + // kplex is > + public Map connectionsByNode(Map> graph) { + Map result = Maps.newHashMap(); + for(N n : graph.keySet()) { + result.put(n, graph.get(n).size()); + } + return result; + } + // This is similar to hIndex. + // Connectedness of N for having N connections to nodes with N connections. + public Map connectednessByNode(Map> graph) { + Map connectionsByNode = connectionsByNode(graph); + Map results = Maps.newHashMap(); + for(N n1 : graph.keySet()) { + List connectednessOfConnections = Lists.newArrayList(); + for(N n2 : graph.get(n1)) { + connectednessOfConnections.add(connectionsByNode.get(n2)); + } + Collections.sort(connectednessOfConnections); + Collections.reverse(connectednessOfConnections); + Integer result = 0; + for(Integer i = 0; i < connectednessOfConnections.size(); i++) { + if(i < connectednessOfConnections.get(i)) { + result = i+1; + } + } + results.put(n1, result); + } + return results; + } + public Map connectionsWithinSubgroup(Map> graph, Set subgroup) { + Map result = Maps.newHashMap(); + for(N n : graph.keySet()) { + result.put(n, Sets.intersection(graph.get(n),subgroup).size()); + } + return result; + } + public Integer highestConnectedness(Map> graph) { + Integer highest = 0; + for(Integer connectedness : connectednessByNode(graph).values()) { + if(connectedness > highest) { + highest = connectedness; + } + } + return highest; + } + public Set meetConnectednessThreshold(Map> graph, Integer threshold) { + Set result = Sets.newHashSet(); + Map connectedness = connectednessByNode(graph); + for(N n : graph.keySet()) { + if(connectedness.get(n) > threshold-1) { + result.add(n); + } + } + return result; + } + public Integer largestPossibleKPlex(Map> graph, Integer k) { + return highestConnectedness(graph)+k; + } + public Set criticalNodesInKPlex(Map> graph, Set kplex, Integer k) { + Map connectionsWithinKPlex = connectionsWithinSubgroup(graph,kplex); + Set criticalNodes = Sets.newHashSet(); + for(N n : kplex) { + Integer connections = connectionsWithinKPlex.get(n); + if(connections == null) { + throw new RuntimeException("null connections for "+n+" in "+kplex+" of graph "+graph); + } + if(connections < kplex.size()-k+1) { + criticalNodes.add(n); + } + } + return criticalNodes; + } + public Set nodesThatCanBeAddedToKPlex(Map> graph, Set kplex, Integer k) { + if(kplex.isEmpty()) { + if(k > 0) { + return graph.keySet(); + } else { + return new HashSet(); + } + } + Set criticalNodes = criticalNodesInKPlex(graph, kplex, k); + if(criticalNodes.isEmpty()) { + Map connectionsWithinKPlex = connectionsWithinSubgroup(graph,kplex); + Set neighbors = Sets.newHashSet(); + for(N n : graph.keySet()) { + if(connectionsWithinKPlex.get(n) > 0) { + neighbors.add(n); + } + } + neighbors.removeAll(kplex); + return Sets.difference(neighbors,kplex); + } + Set eligible = Sets.difference(graph.keySet(),kplex); + for(N n : criticalNodes) { + // Must be neighbor of all critical nodes. + eligible = Sets.intersection(eligible, graph.get(n)); + } + return eligible; + } + public Map> createSubgraph(Map> graph, Set nodes) { + Map> subgraph = Maps.newHashMap(); + for(N n : nodes) { + subgraph.put(n, Sets.intersection(graph.get(n),nodes)); + } + return subgraph; + } + public Map> subgraphBoundingFinalKPlex( + Map> graph, Set kplex, Integer k, Integer targetSize) + { + Set includeInSubgraph = + Sets.union(kplex, + Sets.intersection( + meetConnectednessThreshold(graph,targetSize-k), + nodesThatCanBeAddedToKPlex(graph,kplex,k))); + return createSubgraph(graph,includeInSubgraph); + } + public N chooseNodeForInclusionInKPlex(Map> graph, Set kplex, Integer k) { + Integer highScore = 0; + N choice = null; + Map connectedness = connectednessByNode(graph); + Map connectionsWithinKPlex = connectionsWithinSubgroup(graph,kplex); + Set addable = nodesThatCanBeAddedToKPlex(graph, kplex, k); + for(N n : addable) { + Integer score = connectedness.get(n) + connectionsWithinKPlex.get(n); + if(score > highScore) { + highScore = score; + choice = n; + } + } + return choice; + } + public Set growKPlex(Map> graph, Set kplex, Integer k, Integer targetSize) { + Map> boundingGraph = subgraphBoundingFinalKPlex(graph,kplex,k,targetSize); + N newNode = chooseNodeForInclusionInKPlex(graph,kplex,k); + if(newNode == null) { + return kplex; + } + Set newKPlex = Sets.newHashSet(); + newKPlex.add(newNode); + newKPlex.addAll(kplex); + return growKPlex(boundingGraph,newKPlex,k,targetSize); + } + public Set findLargeKPlex(Map> graph, Integer k) { + Set largestFound = Sets.newHashSet(); + for(Integer targetSize = largestPossibleKPlex(graph, k); + targetSize > largestFound.size(); + targetSize--) + { + Set seeds = meetConnectednessThreshold(graph, targetSize-k); + Map> boundedGraph = createSubgraph(graph,seeds); + for(N seed : seeds) { + Set kplex = Sets.newHashSet(); + kplex.add(seed); + kplex = growKPlex(boundedGraph,kplex,k,targetSize); + if(kplex.size() > largestFound.size()) { + largestFound = kplex; + } + } + } + return largestFound; + } +} diff --git a/src/org/egonet/graph/KPlexesTwoMode.java b/src/main/java/org/egonet/graph/KPlexesTwoMode.java similarity index 97% rename from src/org/egonet/graph/KPlexesTwoMode.java rename to src/main/java/org/egonet/graph/KPlexesTwoMode.java index f910f6b..b0c9a04 100644 --- a/src/org/egonet/graph/KPlexesTwoMode.java +++ b/src/main/java/org/egonet/graph/KPlexesTwoMode.java @@ -1,251 +1,251 @@ -package org.egonet.graph; - -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; - -public class KPlexesTwoMode { - // graph is Map> plus Set to indicate which are in first mode - // kplex is > - public Map connectionsByNode(Map> graph) { - Map result = Maps.newHashMap(); - for(N n : graph.keySet()) { - result.put(n, graph.get(n).size()); - } - return result; - } - // This is similar to hIndex. - // Connectedness of N for having N connections to nodes with N connections. - public Map connectednessByNode(Map> graph) { - Map connectionsByNode = connectionsByNode(graph); - Map results = Maps.newHashMap(); - for(N n1 : graph.keySet()) { - List connectednessOfConnections = Lists.newArrayList(); - for(N n2 : graph.get(n1)) { - connectednessOfConnections.add(connectionsByNode.get(n2)); - } - Collections.sort(connectednessOfConnections); - Collections.reverse(connectednessOfConnections); - Integer result = 0; - for(Integer i = 0; i < connectednessOfConnections.size(); i++) { - if(i < connectednessOfConnections.get(i)) { - result = i+1; - } - } - results.put(n1, result); - } - return results; - } - public Map connectionsWithinSubgroup(Map> graph, Set subgroup) { - Map result = Maps.newHashMap(); - for(N n : graph.keySet()) { - result.put(n, Sets.intersection(graph.get(n),subgroup).size()); - } - return result; - } - public Integer highestConnectedness(Map> graph) { - Integer highest = 0; - for(Integer connectedness : connectednessByNode(graph).values()) { - if(connectedness > highest) { - highest = connectedness; - } - } - return highest; - } - public Set meetConnectednessThreshold(Map> graph, Integer k, Integer targetSize) { - Integer threshold = targetSize - k; - Set result = Sets.newHashSet(); - Map connectedness = connectednessByNode(graph); - for(N n : graph.keySet()) { - if(connectedness.get(n) > threshold-1) { - result.add(n); - } - } - return result; - } - public Integer largestPossibleKPlex(Map> graph, Integer k) { - return highestConnectedness(graph)+k; - } - public Set criticalNodesInKPlex(Map> graph, Set mode1, Set kplex, Integer k) { - if(! graph.keySet().containsAll(kplex)) { - throw new RuntimeException("The kplex "+kplex+" is not a subset of the graph "+graph); - } - Integer mode1KPlexSize = Sets.intersection(mode1, kplex).size(); - Integer mode2KPlexSize = kplex.size() - mode1KPlexSize; - Map connectionsWithinKPlex = connectionsWithinSubgroup(graph,kplex); - Set criticalNodes = Sets.newHashSet(); - for(N n : kplex) { - Integer connections = connectionsWithinKPlex.get(n); - if(connections == null) { - throw new RuntimeException("null connections for "+n+" in "+kplex+" of graph "+graph); - } - Integer otherModeSize = (mode1.contains(n) ? mode2KPlexSize : mode1KPlexSize); - Integer threshold = otherModeSize-k; - if(connections < threshold+1) { - criticalNodes.add(n); - } - } - return criticalNodes; - } - - public Set nodesThatCanBeAddedToKPlex(Map> graph, Set mode1, Set kplex, Integer k) { - if(kplex.isEmpty()) { - if(k > 0) { - return graph.keySet(); - } else { - return new HashSet(); - } - } - Set criticalNodes = criticalNodesInKPlex(graph, mode1, kplex, k); - Set outsideKPlex = Sets.difference(graph.keySet(),kplex); - Set mode1Eligible = Sets.intersection(mode1, outsideKPlex); - Set mode2Eligible = Sets.difference(outsideKPlex, mode1Eligible); - for(N n : criticalNodes) { - // Must be neighbor of all critical nodes in other mode. - if(mode1.contains(n)) { - mode2Eligible = Sets.intersection(mode2Eligible, graph.get(n)); - } else { - mode1Eligible = Sets.intersection(mode1Eligible, graph.get(n)); - } - } - Set result = Sets.newHashSet(); - Map connections = connectionsWithinSubgroup(graph,kplex); - Integer kplexMode1Size = Sets.intersection(kplex, mode1).size(); - Integer kplexMode2Size = kplex.size()-kplexMode1Size; - for(N n : Sets.union(mode1Eligible, mode2Eligible)) { - if(connections.get(n) > (mode1.contains(n) ? kplexMode2Size : kplexMode1Size)-k-1) - { - result.add(n); - } - } - return result; - } - public Map> createSubgraph(Map> graph, Set nodes) { - Map> subgraph = Maps.newHashMap(); - for(N n : nodes) { - subgraph.put(n, Sets.intersection(graph.get(n),nodes)); - } - return subgraph; - } - public Set neighborsOfSubgroup(Map> graph, Set subgroup) { - Map connections = connectionsWithinSubgroup(graph, subgroup); - Set results = Sets.newHashSet(); - for(N n : graph.keySet()) { - if(connections.get(n) > 0 && !subgroup.contains(n)) { - results.add(n); - } - } - return results; - } - public Map> subgraphBoundingFinalKPlex( - Map> graph, Set mode1, Set kplex, Integer k, Integer targetSize) - { - Set includeInSubgraph = - Sets.union(kplex, - Sets.intersection( - meetConnectednessThreshold(graph,k,targetSize), - nodesThatCanBeAddedToKPlex(graph,mode1,kplex,k))); - return createSubgraph(graph,includeInSubgraph); - } - public N chooseNodeForInclusionInKPlex(Map> graph, Set mode1, Set kplex, Integer k) { - Integer highScore = 0; - N choice = null; - Map connectedness = connectednessByNode(graph); - Map connectionsWithinKPlex = connectionsWithinSubgroup(graph,kplex); - Set addable = nodesThatCanBeAddedToKPlex(graph, mode1, kplex, k); - if(!kplex.isEmpty()) { - addable = Sets.intersection(addable, neighborsOfSubgroup(graph,kplex)); - } - Integer alreadyInMode1 = Sets.intersection(mode1, kplex).size(); - Integer alreadyInMode2 = kplex.size()-alreadyInMode1; - for(N n : addable) { - Integer score = connectedness.get(n) + 5*connectionsWithinKPlex.get(n) - + 5*(mode1.contains(n) ? alreadyInMode2 : alreadyInMode1); - if(score > highScore) { - highScore = score; - choice = n; - } - } - return choice; - } - public Set growKPlex(Map> graph, Set mode1, Set kplex, Integer k, Integer targetSize) { - Map> boundingGraph = subgraphBoundingFinalKPlex(graph, mode1,kplex,k,targetSize); - N newNode = chooseNodeForInclusionInKPlex(boundingGraph, mode1,kplex,k); - if(newNode == null) { - return kplex; - } - Set newKPlex = Sets.newHashSet(); - newKPlex.add(newNode); - newKPlex.addAll(kplex); - Integer actualk = maxMissingEdgesPerNodeInSubgroup(graph,mode1,newKPlex); - if(actualk > k) { - String msg = "After adding "+newNode+", found k-plex with k that is too high. "+ - actualk+" instead of "+k+": "+newKPlex; - System.out.println(msg); - for(N n : newKPlex) { - System.out.println(n+" : "+Sets.intersection(graph.get(n), newKPlex)); - } - throw new RuntimeException(msg); - } - return growKPlex(boundingGraph, mode1,newKPlex,k,targetSize); - } - public Set findLargeKPlex(Map> graph, Set mode1, Integer k) { - Set largestFound = Sets.newHashSet(); - Integer mostInSmallMode = 0; - Integer mostInLargeMode = 0; - for(Integer targetSize = largestPossibleKPlex(graph, k); - targetSize > mostInSmallMode; - targetSize--) - { - Set seeds = meetConnectednessThreshold(graph, k, targetSize); - Map> boundedGraph = createSubgraph(graph,seeds); - for(N seed : seeds) { - Set kplex = Sets.newHashSet(); - kplex.add(seed); - kplex = growKPlex(boundedGraph,mode1,kplex,k,targetSize); - Set inMode1 = Sets.intersection(kplex,mode1); - Set inMode2 = Sets.difference(kplex, inMode1); - Integer inSmallMode = Math.min(inMode1.size(), inMode2.size()); - Integer inLargeMode = Math.max(inMode1.size(), inMode2.size()); - if(inSmallMode > mostInSmallMode || - (inSmallMode.equals(mostInSmallMode) && inLargeMode > mostInLargeMode)) - { - largestFound = kplex; - mostInSmallMode = inSmallMode; - mostInLargeMode = inLargeMode; - } - } - } - Integer actualk = maxMissingEdgesPerNodeInSubgroup(graph,mode1,largestFound); - if(actualk > k) { - throw new RuntimeException("Found k-plex with k that is too high. "+ - actualk+" instead of "+k+": "+largestFound); - } - return largestFound; - } - public Integer maxMissingEdgesPerNodeInSubgroup( - Map> graph, Set mode1, Set subgroup) - { - Integer maxMissing = 0; - Set submode1 = Sets.intersection(mode1, subgroup); - Set submode2 = Sets.difference(subgroup, submode1); - for(N n1 : subgroup) { - Set otherSubmode = mode1.contains(n1) ? submode2 : submode1; - Integer edges = Sets.intersection(otherSubmode, graph.get(n1)).size(); - Integer missing = otherSubmode.size()-edges; - if(missing > maxMissing) { - maxMissing = missing; - } - if(missing < 0) { - throw new RuntimeException("Can't be missing negative number of edges."); - } - } - return maxMissing; - } -} +package org.egonet.graph; + +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; + +public class KPlexesTwoMode { + // graph is Map> plus Set to indicate which are in first mode + // kplex is > + public Map connectionsByNode(Map> graph) { + Map result = Maps.newHashMap(); + for(N n : graph.keySet()) { + result.put(n, graph.get(n).size()); + } + return result; + } + // This is similar to hIndex. + // Connectedness of N for having N connections to nodes with N connections. + public Map connectednessByNode(Map> graph) { + Map connectionsByNode = connectionsByNode(graph); + Map results = Maps.newHashMap(); + for(N n1 : graph.keySet()) { + List connectednessOfConnections = Lists.newArrayList(); + for(N n2 : graph.get(n1)) { + connectednessOfConnections.add(connectionsByNode.get(n2)); + } + Collections.sort(connectednessOfConnections); + Collections.reverse(connectednessOfConnections); + Integer result = 0; + for(Integer i = 0; i < connectednessOfConnections.size(); i++) { + if(i < connectednessOfConnections.get(i)) { + result = i+1; + } + } + results.put(n1, result); + } + return results; + } + public Map connectionsWithinSubgroup(Map> graph, Set subgroup) { + Map result = Maps.newHashMap(); + for(N n : graph.keySet()) { + result.put(n, Sets.intersection(graph.get(n),subgroup).size()); + } + return result; + } + public Integer highestConnectedness(Map> graph) { + Integer highest = 0; + for(Integer connectedness : connectednessByNode(graph).values()) { + if(connectedness > highest) { + highest = connectedness; + } + } + return highest; + } + public Set meetConnectednessThreshold(Map> graph, Integer k, Integer targetSize) { + Integer threshold = targetSize - k; + Set result = Sets.newHashSet(); + Map connectedness = connectednessByNode(graph); + for(N n : graph.keySet()) { + if(connectedness.get(n) > threshold-1) { + result.add(n); + } + } + return result; + } + public Integer largestPossibleKPlex(Map> graph, Integer k) { + return highestConnectedness(graph)+k; + } + public Set criticalNodesInKPlex(Map> graph, Set mode1, Set kplex, Integer k) { + if(! graph.keySet().containsAll(kplex)) { + throw new RuntimeException("The kplex "+kplex+" is not a subset of the graph "+graph); + } + Integer mode1KPlexSize = Sets.intersection(mode1, kplex).size(); + Integer mode2KPlexSize = kplex.size() - mode1KPlexSize; + Map connectionsWithinKPlex = connectionsWithinSubgroup(graph,kplex); + Set criticalNodes = Sets.newHashSet(); + for(N n : kplex) { + Integer connections = connectionsWithinKPlex.get(n); + if(connections == null) { + throw new RuntimeException("null connections for "+n+" in "+kplex+" of graph "+graph); + } + Integer otherModeSize = (mode1.contains(n) ? mode2KPlexSize : mode1KPlexSize); + Integer threshold = otherModeSize-k; + if(connections < threshold+1) { + criticalNodes.add(n); + } + } + return criticalNodes; + } + + public Set nodesThatCanBeAddedToKPlex(Map> graph, Set mode1, Set kplex, Integer k) { + if(kplex.isEmpty()) { + if(k > 0) { + return graph.keySet(); + } else { + return new HashSet(); + } + } + Set criticalNodes = criticalNodesInKPlex(graph, mode1, kplex, k); + Set outsideKPlex = Sets.difference(graph.keySet(),kplex); + Set mode1Eligible = Sets.intersection(mode1, outsideKPlex); + Set mode2Eligible = Sets.difference(outsideKPlex, mode1Eligible); + for(N n : criticalNodes) { + // Must be neighbor of all critical nodes in other mode. + if(mode1.contains(n)) { + mode2Eligible = Sets.intersection(mode2Eligible, graph.get(n)); + } else { + mode1Eligible = Sets.intersection(mode1Eligible, graph.get(n)); + } + } + Set result = Sets.newHashSet(); + Map connections = connectionsWithinSubgroup(graph,kplex); + Integer kplexMode1Size = Sets.intersection(kplex, mode1).size(); + Integer kplexMode2Size = kplex.size()-kplexMode1Size; + for(N n : Sets.union(mode1Eligible, mode2Eligible)) { + if(connections.get(n) > (mode1.contains(n) ? kplexMode2Size : kplexMode1Size)-k-1) + { + result.add(n); + } + } + return result; + } + public Map> createSubgraph(Map> graph, Set nodes) { + Map> subgraph = Maps.newHashMap(); + for(N n : nodes) { + subgraph.put(n, Sets.intersection(graph.get(n),nodes)); + } + return subgraph; + } + public Set neighborsOfSubgroup(Map> graph, Set subgroup) { + Map connections = connectionsWithinSubgroup(graph, subgroup); + Set results = Sets.newHashSet(); + for(N n : graph.keySet()) { + if(connections.get(n) > 0 && !subgroup.contains(n)) { + results.add(n); + } + } + return results; + } + public Map> subgraphBoundingFinalKPlex( + Map> graph, Set mode1, Set kplex, Integer k, Integer targetSize) + { + Set includeInSubgraph = + Sets.union(kplex, + Sets.intersection( + meetConnectednessThreshold(graph,k,targetSize), + nodesThatCanBeAddedToKPlex(graph,mode1,kplex,k))); + return createSubgraph(graph,includeInSubgraph); + } + public N chooseNodeForInclusionInKPlex(Map> graph, Set mode1, Set kplex, Integer k) { + Integer highScore = 0; + N choice = null; + Map connectedness = connectednessByNode(graph); + Map connectionsWithinKPlex = connectionsWithinSubgroup(graph,kplex); + Set addable = nodesThatCanBeAddedToKPlex(graph, mode1, kplex, k); + if(!kplex.isEmpty()) { + addable = Sets.intersection(addable, neighborsOfSubgroup(graph,kplex)); + } + Integer alreadyInMode1 = Sets.intersection(mode1, kplex).size(); + Integer alreadyInMode2 = kplex.size()-alreadyInMode1; + for(N n : addable) { + Integer score = connectedness.get(n) + 5*connectionsWithinKPlex.get(n) + + 5*(mode1.contains(n) ? alreadyInMode2 : alreadyInMode1); + if(score > highScore) { + highScore = score; + choice = n; + } + } + return choice; + } + public Set growKPlex(Map> graph, Set mode1, Set kplex, Integer k, Integer targetSize) { + Map> boundingGraph = subgraphBoundingFinalKPlex(graph, mode1,kplex,k,targetSize); + N newNode = chooseNodeForInclusionInKPlex(boundingGraph, mode1,kplex,k); + if(newNode == null) { + return kplex; + } + Set newKPlex = Sets.newHashSet(); + newKPlex.add(newNode); + newKPlex.addAll(kplex); + Integer actualk = maxMissingEdgesPerNodeInSubgroup(graph,mode1,newKPlex); + if(actualk > k) { + String msg = "After adding "+newNode+", found k-plex with k that is too high. "+ + actualk+" instead of "+k+": "+newKPlex; + System.out.println(msg); + for(N n : newKPlex) { + System.out.println(n+" : "+Sets.intersection(graph.get(n), newKPlex)); + } + throw new RuntimeException(msg); + } + return growKPlex(boundingGraph, mode1,newKPlex,k,targetSize); + } + public Set findLargeKPlex(Map> graph, Set mode1, Integer k) { + Set largestFound = Sets.newHashSet(); + Integer mostInSmallMode = 0; + Integer mostInLargeMode = 0; + for(Integer targetSize = largestPossibleKPlex(graph, k); + targetSize > mostInSmallMode; + targetSize--) + { + Set seeds = meetConnectednessThreshold(graph, k, targetSize); + Map> boundedGraph = createSubgraph(graph,seeds); + for(N seed : seeds) { + Set kplex = Sets.newHashSet(); + kplex.add(seed); + kplex = growKPlex(boundedGraph,mode1,kplex,k,targetSize); + Set inMode1 = Sets.intersection(kplex,mode1); + Set inMode2 = Sets.difference(kplex, inMode1); + Integer inSmallMode = Math.min(inMode1.size(), inMode2.size()); + Integer inLargeMode = Math.max(inMode1.size(), inMode2.size()); + if(inSmallMode > mostInSmallMode || + (inSmallMode.equals(mostInSmallMode) && inLargeMode > mostInLargeMode)) + { + largestFound = kplex; + mostInSmallMode = inSmallMode; + mostInLargeMode = inLargeMode; + } + } + } + Integer actualk = maxMissingEdgesPerNodeInSubgroup(graph,mode1,largestFound); + if(actualk > k) { + throw new RuntimeException("Found k-plex with k that is too high. "+ + actualk+" instead of "+k+": "+largestFound); + } + return largestFound; + } + public Integer maxMissingEdgesPerNodeInSubgroup( + Map> graph, Set mode1, Set subgroup) + { + Integer maxMissing = 0; + Set submode1 = Sets.intersection(mode1, subgroup); + Set submode2 = Sets.difference(subgroup, submode1); + for(N n1 : subgroup) { + Set otherSubmode = mode1.contains(n1) ? submode2 : submode1; + Integer edges = Sets.intersection(otherSubmode, graph.get(n1)).size(); + Integer missing = otherSubmode.size()-edges; + if(missing > maxMissing) { + maxMissing = missing; + } + if(missing < 0) { + throw new RuntimeException("Can't be missing negative number of edges."); + } + } + return maxMissing; + } +} diff --git a/src/org/egonet/gui/EgoStore.java b/src/main/java/org/egonet/gui/EgoStore.java similarity index 100% rename from src/org/egonet/gui/EgoStore.java rename to src/main/java/org/egonet/gui/EgoStore.java diff --git a/src/org/egonet/gui/EgonetFrame.java b/src/main/java/org/egonet/gui/EgonetFrame.java similarity index 96% rename from src/org/egonet/gui/EgonetFrame.java rename to src/main/java/org/egonet/gui/EgonetFrame.java index 69307e6..7432391 100644 --- a/src/org/egonet/gui/EgonetFrame.java +++ b/src/main/java/org/egonet/gui/EgonetFrame.java @@ -1,179 +1,179 @@ -package org.egonet.gui; - -import java.awt.BorderLayout; -import java.awt.Component; -import java.awt.KeyboardFocusManager; -import java.awt.Window; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import java.beans.PropertyVetoException; - -import javax.swing.JFrame; -import javax.swing.JInternalFrame; -import javax.swing.JMenu; -import javax.swing.JMenuBar; -import javax.swing.JMenuItem; -import javax.swing.JScrollPane; - -import org.egonet.mdi.*; -import org.egonet.util.CatchingAction; -import org.egonet.util.EgonetAnalytics; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.endlessloopsoftware.ego.author.EgoFrame; -import com.endlessloopsoftware.ego.author.EgoNet; -import com.endlessloopsoftware.ego.client.EgoClient; -import com.endlessloopsoftware.egonet.Shared; - -public class EgonetFrame extends JFrame { - private final MDIDesktopPane desktop = new MDIDesktopPane(); - - - final private static Logger logger = LoggerFactory.getLogger(EgonetFrame.class); - - - // TODO: handle the initial registration in a better way - // TODO: establish the generic file menu of options - - private JMenuBar menuBar = new JMenuBar(); - - private JMenu fileMenu = new JMenu("File"); - - private JMenu helpMenu = new JMenu("Help"); - - private JMenuItem newAuthoringTool = new JMenuItem("New Authoring Tool Window"); - - private JMenuItem newInterviewingTool = new JMenuItem("New Interviewing Tool Window"); - - private JScrollPane scrollPane = new JScrollPane(); - - public EgonetFrame() throws Exception { - KeyboardFocusManager focusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager(); - focusManager.addPropertyChangeListener(new PropertyChangeListener() { - public void propertyChange(PropertyChangeEvent e) { - String prop = e.getPropertyName(); - if(!prop.equals("focusOwner")) - return; - - focusChanged(e); - } - }); - - fileMenu.add(newAuthoringTool); - fileMenu.add(newInterviewingTool); - - menuBar.add(fileMenu); - menuBar.add(new WindowMenu(desktop)); - menuBar.add(helpMenu); - - final Window me = this; - JMenuItem aboutMenu = new JMenuItem("About"); - helpMenu.add(aboutMenu); - aboutMenu.addActionListener(new CatchingAction("jMenuHelpAbout") { - public void safeActionPerformed(ActionEvent e) throws Exception { - Shared.displayAboutBox(me); - } - }); - - - - //fileMenu.add(newStudyMenu); - setJMenuBar(menuBar); - setTitle("EgoNet - Egocentric Network Analysis"); - scrollPane.getViewport().add(desktop); - getContentPane().setLayout(new BorderLayout()); - getContentPane().add(scrollPane, BorderLayout.CENTER); - - addWindowListener(new WindowAdapter() { - public void windowClosing(WindowEvent e) { - logger.info("Main frame is closed, closing all MDI frames"); - JInternalFrame[] frames = desktop.getAllFrames(); - - for(JInternalFrame frame : frames) { - try { - frame.setClosed(true); - - if(frame instanceof EgoFrame) { - EgoFrame f = (EgoFrame)frame; - f.jMenuFileExit_actionPerformed(null); - } - } - catch (PropertyVetoException ex) { - logger.warn("Vetoed close on " + frame.toString(), ex); - } - finally { - frame.dispose(); - } - } - - EgonetAnalytics.track("application shutdown"); // track! - System.exit(0); - } - }); - - newAuthoringTool.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent ae) { - desktop.add(new EgoNet().getFrame()); - } - }); - - newInterviewingTool.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent ae) { - desktop.add(new EgoClient().getFrame()); - } - }); - - desktop.add(new EgoNet().getFrame()); - desktop.add(new EgoClient().getFrame()); - } - - - - protected void focusChanged(PropertyChangeEvent e) { - - // loop through all MDIChildFrames hanging on this component, - // if one is ancestor of the old or the new - // fire an event! - - if(e.getOldValue() != null && e.getOldValue() instanceof Component) - { - Component oldValue = (Component)e.getOldValue(); - for(JInternalFrame frame : desktop.getAllFrames()) - { - if(!(frame instanceof MDIChildFrame)) - continue; - - if(!frame.isAncestorOf(oldValue)) - continue; - - MDIChildFrame child = (MDIChildFrame)frame; - child.focusDeactivated(); - break; - } - } - - if(e.getNewValue() != null && e.getNewValue() instanceof Component) - { - Component newValue = (Component)e.getNewValue(); - for(JInternalFrame frame : desktop.getAllFrames()) - { - if(!(frame instanceof MDIChildFrame)) - continue; - - if(!frame.isAncestorOf(newValue)) - continue; - - MDIChildFrame child = (MDIChildFrame)frame; - child.focusActivated(); - break; - } - } - } -} - - +package org.egonet.gui; + +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.KeyboardFocusManager; +import java.awt.Window; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.beans.PropertyVetoException; + +import javax.swing.JFrame; +import javax.swing.JInternalFrame; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JScrollPane; + +import org.egonet.mdi.*; +import org.egonet.util.CatchingAction; +import org.egonet.util.EgonetAnalytics; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.endlessloopsoftware.ego.author.EgoFrame; +import com.endlessloopsoftware.ego.author.EgoNet; +import com.endlessloopsoftware.ego.client.EgoClient; +import com.endlessloopsoftware.egonet.Shared; + +public class EgonetFrame extends JFrame { + private final MDIDesktopPane desktop = new MDIDesktopPane(); + + + final private static Logger logger = LoggerFactory.getLogger(EgonetFrame.class); + + + // TODO: handle the initial registration in a better way + // TODO: establish the generic file menu of options + + private JMenuBar menuBar = new JMenuBar(); + + private JMenu fileMenu = new JMenu("File"); + + private JMenu helpMenu = new JMenu("Help"); + + private JMenuItem newAuthoringTool = new JMenuItem("New Authoring Tool Window"); + + private JMenuItem newInterviewingTool = new JMenuItem("New Interviewing Tool Window"); + + private JScrollPane scrollPane = new JScrollPane(); + + public EgonetFrame() throws Exception { + KeyboardFocusManager focusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager(); + focusManager.addPropertyChangeListener(new PropertyChangeListener() { + public void propertyChange(PropertyChangeEvent e) { + String prop = e.getPropertyName(); + if(!prop.equals("focusOwner")) + return; + + focusChanged(e); + } + }); + + fileMenu.add(newAuthoringTool); + fileMenu.add(newInterviewingTool); + + menuBar.add(fileMenu); + menuBar.add(new WindowMenu(desktop)); + menuBar.add(helpMenu); + + final Window me = this; + JMenuItem aboutMenu = new JMenuItem("About"); + helpMenu.add(aboutMenu); + aboutMenu.addActionListener(new CatchingAction("jMenuHelpAbout") { + public void safeActionPerformed(ActionEvent e) throws Exception { + Shared.displayAboutBox(me); + } + }); + + + + //fileMenu.add(newStudyMenu); + setJMenuBar(menuBar); + setTitle("EgoNet - Egocentric Network Analysis"); + scrollPane.getViewport().add(desktop); + getContentPane().setLayout(new BorderLayout()); + getContentPane().add(scrollPane, BorderLayout.CENTER); + + addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + logger.info("Main frame is closed, closing all MDI frames"); + JInternalFrame[] frames = desktop.getAllFrames(); + + for(JInternalFrame frame : frames) { + try { + frame.setClosed(true); + + if(frame instanceof EgoFrame) { + EgoFrame f = (EgoFrame)frame; + f.jMenuFileExit_actionPerformed(null); + } + } + catch (PropertyVetoException ex) { + logger.warn("Vetoed close on " + frame.toString(), ex); + } + finally { + frame.dispose(); + } + } + + EgonetAnalytics.track("application shutdown"); // track! + System.exit(0); + } + }); + + newAuthoringTool.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent ae) { + desktop.add(new EgoNet().getFrame()); + } + }); + + newInterviewingTool.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent ae) { + desktop.add(new EgoClient().getFrame()); + } + }); + + desktop.add(new EgoNet().getFrame()); + desktop.add(new EgoClient().getFrame()); + } + + + + protected void focusChanged(PropertyChangeEvent e) { + + // loop through all MDIChildFrames hanging on this component, + // if one is ancestor of the old or the new + // fire an event! + + if(e.getOldValue() != null && e.getOldValue() instanceof Component) + { + Component oldValue = (Component)e.getOldValue(); + for(JInternalFrame frame : desktop.getAllFrames()) + { + if(!(frame instanceof MDIChildFrame)) + continue; + + if(!frame.isAncestorOf(oldValue)) + continue; + + MDIChildFrame child = (MDIChildFrame)frame; + child.focusDeactivated(); + break; + } + } + + if(e.getNewValue() != null && e.getNewValue() instanceof Component) + { + Component newValue = (Component)e.getNewValue(); + for(JInternalFrame frame : desktop.getAllFrames()) + { + if(!(frame instanceof MDIChildFrame)) + continue; + + if(!frame.isAncestorOf(newValue)) + continue; + + MDIChildFrame child = (MDIChildFrame)frame; + child.focusActivated(); + break; + } + } + } +} + + diff --git a/src/org/egonet/gui/EgonetRunner.java b/src/main/java/org/egonet/gui/EgonetRunner.java similarity index 96% rename from src/org/egonet/gui/EgonetRunner.java rename to src/main/java/org/egonet/gui/EgonetRunner.java index eb23b01..b55b73a 100644 --- a/src/org/egonet/gui/EgonetRunner.java +++ b/src/main/java/org/egonet/gui/EgonetRunner.java @@ -1,38 +1,38 @@ -package org.egonet.gui; - -import javax.swing.JFrame; -import javax.swing.SwingUtilities; -import javax.swing.UIManager; - -import org.egonet.util.EgonetAnalytics; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class EgonetRunner { - - public static void main(String[] args) throws Exception { - final EgonetUncaughtExceptionHandler eueh = new EgonetUncaughtExceptionHandler(); - Thread.setDefaultUncaughtExceptionHandler(eueh); - - Logger logger = LoggerFactory.getLogger(EgonetRunner.class); - - EgonetAnalytics.track("application startup"); // track! - - SwingUtilities.invokeLater(new Runnable() { - public void run() { - Thread.currentThread().setUncaughtExceptionHandler(eueh); - }}); - - - logger.debug("Configuring L&F to default system L&F"); - UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); - - - logger.info("EgonetRunner is building EgonetFrame"); - EgonetFrame egonetFrame = new EgonetFrame(); - egonetFrame.setSize(800, 600); - egonetFrame.setExtendedState(JFrame.NORMAL | JFrame.MAXIMIZED_BOTH); - egonetFrame.setVisible(true); - } - -} +package org.egonet.gui; + +import javax.swing.JFrame; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; + +import org.egonet.util.EgonetAnalytics; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class EgonetRunner { + + public static void main(String[] args) throws Exception { + final EgonetUncaughtExceptionHandler eueh = new EgonetUncaughtExceptionHandler(); + Thread.setDefaultUncaughtExceptionHandler(eueh); + + Logger logger = LoggerFactory.getLogger(EgonetRunner.class); + + EgonetAnalytics.track("application startup"); // track! + + SwingUtilities.invokeLater(new Runnable() { + public void run() { + Thread.currentThread().setUncaughtExceptionHandler(eueh); + }}); + + + logger.debug("Configuring L&F to default system L&F"); + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + + + logger.info("EgonetRunner is building EgonetFrame"); + EgonetFrame egonetFrame = new EgonetFrame(); + egonetFrame.setSize(800, 600); + egonetFrame.setExtendedState(JFrame.NORMAL | JFrame.MAXIMIZED_BOTH); + egonetFrame.setVisible(true); + } + +} diff --git a/src/org/egonet/gui/EgonetUncaughtExceptionHandler.java b/src/main/java/org/egonet/gui/EgonetUncaughtExceptionHandler.java similarity index 95% rename from src/org/egonet/gui/EgonetUncaughtExceptionHandler.java rename to src/main/java/org/egonet/gui/EgonetUncaughtExceptionHandler.java index 5a40c9c..a856e09 100644 --- a/src/org/egonet/gui/EgonetUncaughtExceptionHandler.java +++ b/src/main/java/org/egonet/gui/EgonetUncaughtExceptionHandler.java @@ -1,46 +1,46 @@ -package org.egonet.gui; - -import java.lang.Thread.UncaughtExceptionHandler; - -import org.jdesktop.swingx.JXErrorPane; -import org.jdesktop.swingx.error.ErrorInfo; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class EgonetUncaughtExceptionHandler implements UncaughtExceptionHandler { - - public void uncaughtException(Thread t, Throwable e) { - try { - getLogger().error("Uncaught exception", e); - } - catch (Exception t2) { - // nothing we can do here - t2.printStackTrace(); - } - - - try { - ErrorInfo ei = new ErrorInfo( - "An error has occurred", - e.getMessage() != null ? e.getMessage() : e.toString(), - null, - "EgonetUncaughtExceptionHandler", - e, - java.util.logging.Level.INFO, - null); - JXErrorPane.showDialog(null, ei); - } - catch (Throwable t2) { - // nothing we can do here - t2.printStackTrace(); - } - } - - private Logger logger = null; - public synchronized Logger getLogger() { - if(logger == null) - logger = LoggerFactory.getLogger(EgonetUncaughtExceptionHandler.class); - return logger; - } - -} +package org.egonet.gui; + +import java.lang.Thread.UncaughtExceptionHandler; + +import org.jdesktop.swingx.JXErrorPane; +import org.jdesktop.swingx.error.ErrorInfo; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class EgonetUncaughtExceptionHandler implements UncaughtExceptionHandler { + + public void uncaughtException(Thread t, Throwable e) { + try { + getLogger().error("Uncaught exception", e); + } + catch (Exception t2) { + // nothing we can do here + t2.printStackTrace(); + } + + + try { + ErrorInfo ei = new ErrorInfo( + "An error has occurred", + e.getMessage() != null ? e.getMessage() : e.toString(), + null, + "EgonetUncaughtExceptionHandler", + e, + java.util.logging.Level.INFO, + null); + JXErrorPane.showDialog(null, ei); + } + catch (Throwable t2) { + // nothing we can do here + t2.printStackTrace(); + } + } + + private Logger logger = null; + public synchronized Logger getLogger() { + if(logger == null) + logger = LoggerFactory.getLogger(EgonetUncaughtExceptionHandler.class); + return logger; + } + +} diff --git a/src/org/egonet/gui/MDIChildFrame.java b/src/main/java/org/egonet/gui/MDIChildFrame.java similarity index 96% rename from src/org/egonet/gui/MDIChildFrame.java rename to src/main/java/org/egonet/gui/MDIChildFrame.java index bbce406..bc9a136 100644 --- a/src/org/egonet/gui/MDIChildFrame.java +++ b/src/main/java/org/egonet/gui/MDIChildFrame.java @@ -1,13 +1,13 @@ -package org.egonet.gui; - -import javax.swing.*; - -import org.egonet.mdi.MDIContext; - -public abstract class MDIChildFrame extends JInternalFrame { - public abstract void setMdiContext(final MDIContext context); - public abstract JInternalFrame getInternalFrame(); - public abstract void focusActivated(); - public abstract void focusDeactivated(); - //public abstract MenuContext getMenuContext(); -} +package org.egonet.gui; + +import javax.swing.*; + +import org.egonet.mdi.MDIContext; + +public abstract class MDIChildFrame extends JInternalFrame { + public abstract void setMdiContext(final MDIContext context); + public abstract JInternalFrame getInternalFrame(); + public abstract void focusActivated(); + public abstract void focusDeactivated(); + //public abstract MenuContext getMenuContext(); +} diff --git a/src/org/egonet/gui/menus/MenuContext.java b/src/main/java/org/egonet/gui/menus/MenuContext.java similarity index 96% rename from src/org/egonet/gui/menus/MenuContext.java rename to src/main/java/org/egonet/gui/menus/MenuContext.java index 5a175c6..ab166f5 100644 --- a/src/org/egonet/gui/menus/MenuContext.java +++ b/src/main/java/org/egonet/gui/menus/MenuContext.java @@ -1,18 +1,18 @@ -package org.egonet.gui.menus; - -import java.util.List; - -/** - * This class provides a context for what menus this MDI frame can display, - * primarily for metadata that is needed to build initial JDesktopPane (the - * non-document window). Once the parent frame menus are built, state changes - * will be handled by the methods provided by each document window. - * - * @author Martin - * - */ -public abstract class MenuContext { - - public abstract String getSourceName(); - public abstract List getMenuGroups(); -} +package org.egonet.gui.menus; + +import java.util.List; + +/** + * This class provides a context for what menus this MDI frame can display, + * primarily for metadata that is needed to build initial JDesktopPane (the + * non-document window). Once the parent frame menus are built, state changes + * will be handled by the methods provided by each document window. + * + * @author Martin + * + */ +public abstract class MenuContext { + + public abstract String getSourceName(); + public abstract List getMenuGroups(); +} diff --git a/src/org/egonet/gui/menus/MenuElement.java b/src/main/java/org/egonet/gui/menus/MenuElement.java similarity index 95% rename from src/org/egonet/gui/menus/MenuElement.java rename to src/main/java/org/egonet/gui/menus/MenuElement.java index acadd0e..c7b4699 100644 --- a/src/org/egonet/gui/menus/MenuElement.java +++ b/src/main/java/org/egonet/gui/menus/MenuElement.java @@ -1,14 +1,14 @@ -package org.egonet.gui.menus; - -import javax.swing.JMenuItem; - -import net.sf.functionalj.tuple.Pair; - -/** - * Represents a menu element, which is basically a JMenuItem and a weight. - * @author Martin - * - */ -public abstract class MenuElement { - public abstract Pair getMenuItem(); -} +package org.egonet.gui.menus; + +import javax.swing.JMenuItem; + +import net.sf.functionalj.tuple.Pair; + +/** + * Represents a menu element, which is basically a JMenuItem and a weight. + * @author Martin + * + */ +public abstract class MenuElement { + public abstract Pair getMenuItem(); +} diff --git a/src/org/egonet/gui/menus/MenuGroup.java b/src/main/java/org/egonet/gui/menus/MenuGroup.java similarity index 96% rename from src/org/egonet/gui/menus/MenuGroup.java rename to src/main/java/org/egonet/gui/menus/MenuGroup.java index 4c6e1ab..4dfc05e 100644 --- a/src/org/egonet/gui/menus/MenuGroup.java +++ b/src/main/java/org/egonet/gui/menus/MenuGroup.java @@ -1,30 +1,30 @@ -package org.egonet.gui.menus; - -import net.sf.functionalj.tuple.Pair; - -/** - * A group of related menu items. Normally, the union of all MenuGroup items in - * an MDI parent frame will yield a larger, common set of MenuGroups like "File" - * or "Edit" menus. It may be combined from many individual file and edit menu - * options. These will be separated by a menu separator. - * - * @author Martin - * - */ -public abstract class MenuGroup { - - public enum CommonGroups { - FILE("File"), - EDIT("Edit"), - WINDOW("Window"), - ABOUT("About"); - - public final String name; - private CommonGroups(String name) { - this.name = name; - } - } - - public abstract Pair getMenuElements(); - public abstract String getGroupSignifier(); -} +package org.egonet.gui.menus; + +import net.sf.functionalj.tuple.Pair; + +/** + * A group of related menu items. Normally, the union of all MenuGroup items in + * an MDI parent frame will yield a larger, common set of MenuGroups like "File" + * or "Edit" menus. It may be combined from many individual file and edit menu + * options. These will be separated by a menu separator. + * + * @author Martin + * + */ +public abstract class MenuGroup { + + public enum CommonGroups { + FILE("File"), + EDIT("Edit"), + WINDOW("Window"), + ABOUT("About"); + + public final String name; + private CommonGroups(String name) { + this.name = name; + } + } + + public abstract Pair getMenuElements(); + public abstract String getGroupSignifier(); +} diff --git a/src/org/egonet/io/AdjacencyWriter.java b/src/main/java/org/egonet/io/AdjacencyWriter.java similarity index 95% rename from src/org/egonet/io/AdjacencyWriter.java rename to src/main/java/org/egonet/io/AdjacencyWriter.java index 104d64b..fc6c921 100644 --- a/src/org/egonet/io/AdjacencyWriter.java +++ b/src/main/java/org/egonet/io/AdjacencyWriter.java @@ -1,48 +1,48 @@ -package org.egonet.io; - -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; - -import org.egonet.util.FileHelpers; - -public class AdjacencyWriter extends FileWriter { - - public AdjacencyWriter(File file) throws IOException { - super(file); - } - - public void writeAdjacency(String[] labels, int [][] adj) throws IOException { - // indicate that this is an adjacency matrix. Is this really necessary? - write("Adjacency Matrix"); - write("\n"); - - // Check that the number of labels matches the size of the adjacency matrix. - assert(adj.length == labels.length); - - // Labels across the top - write(" "); - for(int i = 0; i < adj.length; i++) { - write(","+FileHelpers.formatForCSV(labels[i])); - } - write("\n"); - - for(int i = 0; i < adj.length; i++) - { - write(FileHelpers.formatForCSV(labels[i])+","); - for(int j = 0; j < adj.length; j++) - { - if(i == j) - write(""+1); - else - write(""+adj[i][j]); - - if(j < adj.length-1) - write(","); - else - write("\n"); - } - } - } - -} +package org.egonet.io; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; + +import org.egonet.util.FileHelpers; + +public class AdjacencyWriter extends FileWriter { + + public AdjacencyWriter(File file) throws IOException { + super(file); + } + + public void writeAdjacency(String[] labels, int [][] adj) throws IOException { + // indicate that this is an adjacency matrix. Is this really necessary? + write("Adjacency Matrix"); + write("\n"); + + // Check that the number of labels matches the size of the adjacency matrix. + assert(adj.length == labels.length); + + // Labels across the top + write(" "); + for(int i = 0; i < adj.length; i++) { + write(","+FileHelpers.formatForCSV(labels[i])); + } + write("\n"); + + for(int i = 0; i < adj.length; i++) + { + write(FileHelpers.formatForCSV(labels[i])+","); + for(int j = 0; j < adj.length; j++) + { + if(i == j) + write(""+1); + else + write(""+adj[i][j]); + + if(j < adj.length-1) + write(","); + else + write("\n"); + } + } + } + +} diff --git a/src/org/egonet/io/EdgeListWriter.java b/src/main/java/org/egonet/io/EdgeListWriter.java similarity index 95% rename from src/org/egonet/io/EdgeListWriter.java rename to src/main/java/org/egonet/io/EdgeListWriter.java index a3b8416..0040b35 100644 --- a/src/org/egonet/io/EdgeListWriter.java +++ b/src/main/java/org/egonet/io/EdgeListWriter.java @@ -1,58 +1,58 @@ -package org.egonet.io; - -import java.io.File; -import java.io.FileDescriptor; -import java.io.FileWriter; -import java.io.IOException; - -import org.egonet.util.FileHelpers; - -public class EdgeListWriter extends FileWriter { - - public EdgeListWriter(File file, boolean append) throws IOException { - super(file, append); - } - - public EdgeListWriter(File file) throws IOException { - super(file); - } - - public EdgeListWriter(FileDescriptor fd) { - super(fd); - } - - public EdgeListWriter(String fileName, boolean append) throws IOException { - super(fileName, append); - } - - public EdgeListWriter(String fileName) throws IOException { - super(fileName); - } - - public void writeEdgelist(String [] thisInterviewAlterlist, int [][] adj) throws IOException { - for(int i = 0; i < adj.length; i++) - { - for(int j = i+1; j < adj[i].length; j++) - { - // adj[i][j] != 0 && - if(i != j) - { - - String alter1 = thisInterviewAlterlist[i]; - String alter2 = thisInterviewAlterlist[j]; - int edgeValue = adj[i][j]; - if(edgeValue != 0) { // Don't need to include edges that don't - // represent a connection. - String line = ("\"" + - FileHelpers.formatForCSV(alter1) - + "\",\"" + - FileHelpers.formatForCSV(alter2) - + "\","+adj[i][j] +"\n"); - write(line); - } - } - } - } - } - -} +package org.egonet.io; + +import java.io.File; +import java.io.FileDescriptor; +import java.io.FileWriter; +import java.io.IOException; + +import org.egonet.util.FileHelpers; + +public class EdgeListWriter extends FileWriter { + + public EdgeListWriter(File file, boolean append) throws IOException { + super(file, append); + } + + public EdgeListWriter(File file) throws IOException { + super(file); + } + + public EdgeListWriter(FileDescriptor fd) { + super(fd); + } + + public EdgeListWriter(String fileName, boolean append) throws IOException { + super(fileName, append); + } + + public EdgeListWriter(String fileName) throws IOException { + super(fileName); + } + + public void writeEdgelist(String [] thisInterviewAlterlist, int [][] adj) throws IOException { + for(int i = 0; i < adj.length; i++) + { + for(int j = i+1; j < adj[i].length; j++) + { + // adj[i][j] != 0 && + if(i != j) + { + + String alter1 = thisInterviewAlterlist[i]; + String alter2 = thisInterviewAlterlist[j]; + int edgeValue = adj[i][j]; + if(edgeValue != 0) { // Don't need to include edges that don't + // represent a connection. + String line = ("\"" + + FileHelpers.formatForCSV(alter1) + + "\",\"" + + FileHelpers.formatForCSV(alter2) + + "\","+adj[i][j] +"\n"); + write(line); + } + } + } + } + } + +} diff --git a/src/org/egonet/io/InterviewDataWritingUtil.java b/src/main/java/org/egonet/io/InterviewDataWritingUtil.java similarity index 100% rename from src/org/egonet/io/InterviewDataWritingUtil.java rename to src/main/java/org/egonet/io/InterviewDataWritingUtil.java diff --git a/src/org/egonet/io/InterviewFileFilter.java b/src/main/java/org/egonet/io/InterviewFileFilter.java similarity index 95% rename from src/org/egonet/io/InterviewFileFilter.java rename to src/main/java/org/egonet/io/InterviewFileFilter.java index 6dafde4..c324c6c 100644 --- a/src/org/egonet/io/InterviewFileFilter.java +++ b/src/main/java/org/egonet/io/InterviewFileFilter.java @@ -1,88 +1,88 @@ -package org.egonet.io; - -import java.io.File; -import java.util.HashMap; -import java.util.Map; - -import javax.swing.ProgressMonitor; - -import org.egonet.util.ExtensionFileFilter; - -import com.endlessloopsoftware.egonet.Study; - -/** - * File filter to filter the interview files based on selected study The - * file chooser displays only the interview files compatible with the - * currently chosen study - * - * @author sonam - * - */ -public class InterviewFileFilter extends ExtensionFileFilter { - private final Map cacheResults = new HashMap(); - private final Study study; - - public InterviewFileFilter(Study study, String description, String extension) { - super(description, extension); - this.study = study; - } - - public void cacheList(File currentDirectory, final ProgressMonitor progress) { - int ct = 0; - - for (File ptr : currentDirectory.listFiles()) { - final Integer tct = ++ct; - cacheResults.put(ptr, ptr.canRead() && ptr.isFile() - && cacheAccept(ptr)); - javax.swing.SwingUtilities.invokeLater(new Runnable() { - public void run() { - progress.setProgress(tct); - } - }); - - } - } - - public boolean accept(File ptr) { - if (cacheResults.containsKey(ptr)) { - // cache hit - return cacheResults.get(ptr); - } else { - // cache miss - boolean accept = ptr.canRead() && cacheAccept(ptr); - cacheResults.put(ptr, accept); - return accept; - } - } - - public boolean cacheAccept(java.io.File f) { - - if (f.isDirectory()) - return true; - - boolean cantread = (!f.isFile()) || (!f.canRead()); - if (cantread) - return !cantread; - - boolean accept = true; - try { - // compare study id of interview file with id of currently selected study - InterviewReader sr = new InterviewReader(study, f); - try { - sr.getInterview(); - accept = true; - } catch (Throwable ex) - { - accept = false; - } - } catch (Throwable t) { - accept = false; - } - return accept; - } - - public String getDescription() { - String str = "Interview files"; - return str; - } +package org.egonet.io; + +import java.io.File; +import java.util.HashMap; +import java.util.Map; + +import javax.swing.ProgressMonitor; + +import org.egonet.util.ExtensionFileFilter; + +import com.endlessloopsoftware.egonet.Study; + +/** + * File filter to filter the interview files based on selected study The + * file chooser displays only the interview files compatible with the + * currently chosen study + * + * @author sonam + * + */ +public class InterviewFileFilter extends ExtensionFileFilter { + private final Map cacheResults = new HashMap(); + private final Study study; + + public InterviewFileFilter(Study study, String description, String extension) { + super(description, extension); + this.study = study; + } + + public void cacheList(File currentDirectory, final ProgressMonitor progress) { + int ct = 0; + + for (File ptr : currentDirectory.listFiles()) { + final Integer tct = ++ct; + cacheResults.put(ptr, ptr.canRead() && ptr.isFile() + && cacheAccept(ptr)); + javax.swing.SwingUtilities.invokeLater(new Runnable() { + public void run() { + progress.setProgress(tct); + } + }); + + } + } + + public boolean accept(File ptr) { + if (cacheResults.containsKey(ptr)) { + // cache hit + return cacheResults.get(ptr); + } else { + // cache miss + boolean accept = ptr.canRead() && cacheAccept(ptr); + cacheResults.put(ptr, accept); + return accept; + } + } + + public boolean cacheAccept(java.io.File f) { + + if (f.isDirectory()) + return true; + + boolean cantread = (!f.isFile()) || (!f.canRead()); + if (cantread) + return !cantread; + + boolean accept = true; + try { + // compare study id of interview file with id of currently selected study + InterviewReader sr = new InterviewReader(study, f); + try { + sr.getInterview(); + accept = true; + } catch (Throwable ex) + { + accept = false; + } + } catch (Throwable t) { + accept = false; + } + return accept; + } + + public String getDescription() { + String str = "Interview files"; + return str; + } } \ No newline at end of file diff --git a/src/org/egonet/io/InterviewReader.java b/src/main/java/org/egonet/io/InterviewReader.java similarity index 100% rename from src/org/egonet/io/InterviewReader.java rename to src/main/java/org/egonet/io/InterviewReader.java diff --git a/src/org/egonet/io/InterviewWriter.java b/src/main/java/org/egonet/io/InterviewWriter.java similarity index 100% rename from src/org/egonet/io/InterviewWriter.java rename to src/main/java/org/egonet/io/InterviewWriter.java diff --git a/src/org/egonet/io/PDFWriter.java b/src/main/java/org/egonet/io/PDFWriter.java similarity index 100% rename from src/org/egonet/io/PDFWriter.java rename to src/main/java/org/egonet/io/PDFWriter.java diff --git a/src/org/egonet/io/RTFWriter.java b/src/main/java/org/egonet/io/RTFWriter.java similarity index 96% rename from src/org/egonet/io/RTFWriter.java rename to src/main/java/org/egonet/io/RTFWriter.java index 89c6c62..fef4989 100644 --- a/src/org/egonet/io/RTFWriter.java +++ b/src/main/java/org/egonet/io/RTFWriter.java @@ -1,31 +1,31 @@ -package org.egonet.io; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; - -import org.egonet.exceptions.CorruptedInterviewException; - -import com.endlessloopsoftware.egonet.Interview; -import com.endlessloopsoftware.egonet.Study; -import com.lowagie.text.Document; -import com.lowagie.text.DocumentException; -import com.lowagie.text.PageSize; -import com.lowagie.text.rtf.RtfWriter2; - -public class RTFWriter extends PDFWriter { - - public RTFWriter(Study study, String name) throws CorruptedInterviewException { - super(study, name); - } - - public RTFWriter(Study study, Interview interview) throws CorruptedInterviewException { - super(study, interview); - } - - @Override - public void configureDocument(Document document, File outputfile) throws FileNotFoundException, DocumentException { - document.setPageSize(PageSize.LETTER); - RtfWriter2.getInstance(document, new FileOutputStream(outputfile)); - } -} +package org.egonet.io; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; + +import org.egonet.exceptions.CorruptedInterviewException; + +import com.endlessloopsoftware.egonet.Interview; +import com.endlessloopsoftware.egonet.Study; +import com.lowagie.text.Document; +import com.lowagie.text.DocumentException; +import com.lowagie.text.PageSize; +import com.lowagie.text.rtf.RtfWriter2; + +public class RTFWriter extends PDFWriter { + + public RTFWriter(Study study, String name) throws CorruptedInterviewException { + super(study, name); + } + + public RTFWriter(Study study, Interview interview) throws CorruptedInterviewException { + super(study, interview); + } + + @Override + public void configureDocument(Document document, File outputfile) throws FileNotFoundException, DocumentException { + document.setPageSize(PageSize.LETTER); + RtfWriter2.getInstance(document, new FileOutputStream(outputfile)); + } +} diff --git a/src/org/egonet/io/RawDataCSVWriter.java b/src/main/java/org/egonet/io/RawDataCSVWriter.java similarity index 100% rename from src/org/egonet/io/RawDataCSVWriter.java rename to src/main/java/org/egonet/io/RawDataCSVWriter.java diff --git a/src/org/egonet/io/StatisticsFileReader.java b/src/main/java/org/egonet/io/StatisticsFileReader.java similarity index 100% rename from src/org/egonet/io/StatisticsFileReader.java rename to src/main/java/org/egonet/io/StatisticsFileReader.java diff --git a/src/org/egonet/io/StatisticsFileWriter.java b/src/main/java/org/egonet/io/StatisticsFileWriter.java similarity index 100% rename from src/org/egonet/io/StatisticsFileWriter.java rename to src/main/java/org/egonet/io/StatisticsFileWriter.java diff --git a/src/org/egonet/io/StudyReader.java b/src/main/java/org/egonet/io/StudyReader.java similarity index 100% rename from src/org/egonet/io/StudyReader.java rename to src/main/java/org/egonet/io/StudyReader.java diff --git a/src/org/egonet/io/StudyWriter.java b/src/main/java/org/egonet/io/StudyWriter.java similarity index 100% rename from src/org/egonet/io/StudyWriter.java rename to src/main/java/org/egonet/io/StudyWriter.java diff --git a/src/org/egonet/io/VnaInterviewWriter.java b/src/main/java/org/egonet/io/VnaInterviewWriter.java similarity index 97% rename from src/org/egonet/io/VnaInterviewWriter.java rename to src/main/java/org/egonet/io/VnaInterviewWriter.java index 19cc047..7341d5b 100644 --- a/src/org/egonet/io/VnaInterviewWriter.java +++ b/src/main/java/org/egonet/io/VnaInterviewWriter.java @@ -1,129 +1,129 @@ -package org.egonet.io; - -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.io.PrintWriter; -import java.io.Writer; -import java.util.ArrayList; - -import net.sf.functionalj.tuple.Pair; -import net.sf.functionalj.tuple.Triple; - -import org.egonet.io.InterviewDataWritingUtil.StudyQuestionsByCategoryAndId; -import org.egonet.model.question.Question; - -import com.endlessloopsoftware.egonet.Answer; -import com.endlessloopsoftware.egonet.Interview; -import com.endlessloopsoftware.egonet.Study; -import com.google.common.base.Joiner; -import com.google.common.collect.Lists; - -public class VnaInterviewWriter { - - // See com.endlessloopsoftware.ego.client.statistics.Statistics.writeAlterArray - // and org.egonet.io.RawDataWriter - // and http://netwiki.amath.unc.edu/DataFormats/NetDrawVna - - private Study study; - private Interview interview; - - public VnaInterviewWriter(Study study, Interview interview) { - this.study = study; - this.interview = interview; - } - - public void write(File file) throws IOException { - FileWriter fw = new FileWriter(file); - write(fw); - fw.close(); - } - - public void write(Writer writer) { - - StudyQuestionsByCategoryAndId questions = - InterviewDataWritingUtil.studyQuestionsByCategoryAndId(study); - InterviewDataWritingUtil.InterviewAnswers answers = - InterviewDataWritingUtil.interviewAnswers(study, interview); - - PrintWriter pw = new PrintWriter(writer); - - pw.println("*Node data"); - ArrayList alterhead = Lists.newArrayList(); - ArrayList alterQIds = Lists.newArrayList(questions.alterQuestions.keySet()); - alterhead.add(sanitize("ID")); - for(Long qid : alterQIds) { - Question question = questions.alterQuestions.get(qid); - if(InterviewDataWritingUtil.showableAsText(question)) { - alterhead.add(sanitize(question.title+" text")); - } - if(InterviewDataWritingUtil.showableAsNumber(question)) { - alterhead.add(sanitize(question.title+" value")); - } - } - pw.println(Joiner.on(", ").join(alterhead)); - - String[] alterList = interview.getAlterList(); - Integer numAlters = alterList.length; - - for(Integer alterID = 0; alterID < numAlters; alterID++) { - ArrayList rowData = Lists.newArrayList(); - rowData.add(sanitize(alterList[alterID])); - for(Long qid : alterQIds) { - Question question = questions.alterQuestions.get(qid); - Answer answer = - answers.alterQuestionToAnswer.get( - new Pair( - qid,alterID)); - if(InterviewDataWritingUtil.showableAsText(question)) { - rowData.add(sanitize(InterviewDataWritingUtil.showAsText(answer))); - } - if(InterviewDataWritingUtil.showableAsNumber(question)) { - rowData.add(sanitize(InterviewDataWritingUtil.showAsNumber(answer)+"")); - } - } - pw.println(" "+Joiner.on(" ").join(rowData)); - } - - pw.println("*Tie data"); - ArrayList aphead = Lists.newArrayList(); - ArrayList apQIds = Lists.newArrayList(questions.linkQuestions.keySet()); - aphead.add("FROM TO"); - for(Long qid : apQIds) { - Question question = questions.linkQuestions.get(qid); - if(InterviewDataWritingUtil.showableAsNumber(question)) { - aphead.add(sanitize(question.title)); - } - } - pw.println(Joiner.on(" ").join(aphead)); - - for(Integer alterID1 = 0; alterID1 < numAlters; alterID1++) { - for(Integer alterID2 = alterID1+1; alterID2 < numAlters; alterID2++) { - ArrayList rowData = Lists.newArrayList(); - rowData.add(sanitize(alterList[alterID1])); - rowData.add(sanitize(alterList[alterID2])); - for(Long qid : apQIds) { - Question question = questions.linkQuestions.get(qid); - Answer answer = - answers.linkQuestionToAnswer.get( - new Triple( - qid,alterID1,alterID2)); - if(InterviewDataWritingUtil.showableAsNumber(question)) { - Integer number = InterviewDataWritingUtil.showAsNumber(answer); - rowData.add((number == null ? 0 : number)+""); - } - } - pw.println(Joiner.on(" ").join(rowData)); - } - } - - pw.flush(); - } - - private String sanitize(String string) { - if(string == null) { - return "_"; - } - return "\""+string.replaceAll("[^a-zA-Z_\\-0-9 ]","_")+"\""; - } -} +package org.egonet.io; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.Writer; +import java.util.ArrayList; + +import net.sf.functionalj.tuple.Pair; +import net.sf.functionalj.tuple.Triple; + +import org.egonet.io.InterviewDataWritingUtil.StudyQuestionsByCategoryAndId; +import org.egonet.model.question.Question; + +import com.endlessloopsoftware.egonet.Answer; +import com.endlessloopsoftware.egonet.Interview; +import com.endlessloopsoftware.egonet.Study; +import com.google.common.base.Joiner; +import com.google.common.collect.Lists; + +public class VnaInterviewWriter { + + // See com.endlessloopsoftware.ego.client.statistics.Statistics.writeAlterArray + // and org.egonet.io.RawDataWriter + // and http://netwiki.amath.unc.edu/DataFormats/NetDrawVna + + private Study study; + private Interview interview; + + public VnaInterviewWriter(Study study, Interview interview) { + this.study = study; + this.interview = interview; + } + + public void write(File file) throws IOException { + FileWriter fw = new FileWriter(file); + write(fw); + fw.close(); + } + + public void write(Writer writer) { + + StudyQuestionsByCategoryAndId questions = + InterviewDataWritingUtil.studyQuestionsByCategoryAndId(study); + InterviewDataWritingUtil.InterviewAnswers answers = + InterviewDataWritingUtil.interviewAnswers(study, interview); + + PrintWriter pw = new PrintWriter(writer); + + pw.println("*Node data"); + ArrayList alterhead = Lists.newArrayList(); + ArrayList alterQIds = Lists.newArrayList(questions.alterQuestions.keySet()); + alterhead.add(sanitize("ID")); + for(Long qid : alterQIds) { + Question question = questions.alterQuestions.get(qid); + if(InterviewDataWritingUtil.showableAsText(question)) { + alterhead.add(sanitize(question.title+" text")); + } + if(InterviewDataWritingUtil.showableAsNumber(question)) { + alterhead.add(sanitize(question.title+" value")); + } + } + pw.println(Joiner.on(", ").join(alterhead)); + + String[] alterList = interview.getAlterList(); + Integer numAlters = alterList.length; + + for(Integer alterID = 0; alterID < numAlters; alterID++) { + ArrayList rowData = Lists.newArrayList(); + rowData.add(sanitize(alterList[alterID])); + for(Long qid : alterQIds) { + Question question = questions.alterQuestions.get(qid); + Answer answer = + answers.alterQuestionToAnswer.get( + new Pair( + qid,alterID)); + if(InterviewDataWritingUtil.showableAsText(question)) { + rowData.add(sanitize(InterviewDataWritingUtil.showAsText(answer))); + } + if(InterviewDataWritingUtil.showableAsNumber(question)) { + rowData.add(sanitize(InterviewDataWritingUtil.showAsNumber(answer)+"")); + } + } + pw.println(" "+Joiner.on(" ").join(rowData)); + } + + pw.println("*Tie data"); + ArrayList aphead = Lists.newArrayList(); + ArrayList apQIds = Lists.newArrayList(questions.linkQuestions.keySet()); + aphead.add("FROM TO"); + for(Long qid : apQIds) { + Question question = questions.linkQuestions.get(qid); + if(InterviewDataWritingUtil.showableAsNumber(question)) { + aphead.add(sanitize(question.title)); + } + } + pw.println(Joiner.on(" ").join(aphead)); + + for(Integer alterID1 = 0; alterID1 < numAlters; alterID1++) { + for(Integer alterID2 = alterID1+1; alterID2 < numAlters; alterID2++) { + ArrayList rowData = Lists.newArrayList(); + rowData.add(sanitize(alterList[alterID1])); + rowData.add(sanitize(alterList[alterID2])); + for(Long qid : apQIds) { + Question question = questions.linkQuestions.get(qid); + Answer answer = + answers.linkQuestionToAnswer.get( + new Triple( + qid,alterID1,alterID2)); + if(InterviewDataWritingUtil.showableAsNumber(question)) { + Integer number = InterviewDataWritingUtil.showAsNumber(answer); + rowData.add((number == null ? 0 : number)+""); + } + } + pw.println(Joiner.on(" ").join(rowData)); + } + } + + pw.flush(); + } + + private String sanitize(String string) { + if(string == null) { + return "_"; + } + return "\""+string.replaceAll("[^a-zA-Z_\\-0-9 ]","_")+"\""; + } +} diff --git a/src/org/egonet/mdi/MDIContext.java b/src/main/java/org/egonet/mdi/MDIContext.java similarity index 93% rename from src/org/egonet/mdi/MDIContext.java rename to src/main/java/org/egonet/mdi/MDIContext.java index d7dd78b..25f59cb 100644 --- a/src/org/egonet/mdi/MDIContext.java +++ b/src/main/java/org/egonet/mdi/MDIContext.java @@ -1,8 +1,8 @@ -package org.egonet.mdi; - -import javax.swing.JMenu; - -public interface MDIContext { - public abstract JMenu getFileMenu(); - -} +package org.egonet.mdi; + +import javax.swing.JMenu; + +public interface MDIContext { + public abstract JMenu getFileMenu(); + +} diff --git a/src/org/egonet/mdi/MDIDesktopManager.java b/src/main/java/org/egonet/mdi/MDIDesktopManager.java similarity index 96% rename from src/org/egonet/mdi/MDIDesktopManager.java rename to src/main/java/org/egonet/mdi/MDIDesktopManager.java index 242789b..ccbce2f 100644 --- a/src/org/egonet/mdi/MDIDesktopManager.java +++ b/src/main/java/org/egonet/mdi/MDIDesktopManager.java @@ -1,104 +1,104 @@ -package org.egonet.mdi; - -import java.awt.Dimension; -import java.awt.Insets; - -import javax.swing.DefaultDesktopManager; -import javax.swing.JComponent; -import javax.swing.JInternalFrame; -import javax.swing.JScrollPane; -import javax.swing.JViewport; - -/** - * Private class used to replace the standard DesktopManager for JDesktopPane. - * Used to provide scrollbar functionality. - */ -public class MDIDesktopManager extends DefaultDesktopManager { - private MDIDesktopPane desktop; - - public MDIDesktopManager(MDIDesktopPane desktop) { - this.desktop = desktop; - } - - public void endResizingFrame(JComponent f) { - super.endResizingFrame(f); - resizeDesktop(); - } - - public void endDraggingFrame(JComponent f) { - super.endDraggingFrame(f); - resizeDesktop(); - } - - public void setNormalSize() { - JScrollPane scrollPane = getScrollPane(); - int x = 0; - int y = 0; - Insets scrollInsets = getScrollPaneInsets(); - - if (scrollPane != null) { - Dimension d = scrollPane.getVisibleRect().getSize(); - if (scrollPane.getBorder() != null) { - d.setSize( - d.getWidth() - scrollInsets.left - scrollInsets.right, - d.getHeight() - scrollInsets.top - scrollInsets.bottom); - } - - d.setSize(d.getWidth() - 20, d.getHeight() - 20); - desktop.setAllSize(x, y); - scrollPane.invalidate(); - scrollPane.validate(); - } - } - - private Insets getScrollPaneInsets() { - JScrollPane scrollPane = getScrollPane(); - if (scrollPane == null) - return new Insets(0, 0, 0, 0); - else - return getScrollPane().getBorder().getBorderInsets(scrollPane); - } - - private JScrollPane getScrollPane() { - if (desktop.getParent() instanceof JViewport) { - JViewport viewPort = (JViewport) desktop.getParent(); - if (viewPort.getParent() instanceof JScrollPane) - return (JScrollPane) viewPort.getParent(); - } - return null; - } - - protected void resizeDesktop() { - int x = 0; - int y = 0; - JScrollPane scrollPane = getScrollPane(); - Insets scrollInsets = getScrollPaneInsets(); - - if (scrollPane != null) { - JInternalFrame allFrames[] = desktop.getAllFrames(); - for (int i = 0; i < allFrames.length; i++) { - if (allFrames[i].getX() + allFrames[i].getWidth() > x) { - x = allFrames[i].getX() + allFrames[i].getWidth(); - } - if (allFrames[i].getY() + allFrames[i].getHeight() > y) { - y = allFrames[i].getY() + allFrames[i].getHeight(); - } - } - Dimension d = scrollPane.getVisibleRect().getSize(); - if (scrollPane.getBorder() != null) { - d.setSize( - d.getWidth() - scrollInsets.left - scrollInsets.right, - d.getHeight() - scrollInsets.top - scrollInsets.bottom); - } - - if (x <= d.getWidth()) - x = ((int) d.getWidth()) - 20; - if (y <= d.getHeight()) - y = ((int) d.getHeight()) - 20; - desktop.setAllSize(x, y); - scrollPane.invalidate(); - scrollPane.validate(); - } - } -} - +package org.egonet.mdi; + +import java.awt.Dimension; +import java.awt.Insets; + +import javax.swing.DefaultDesktopManager; +import javax.swing.JComponent; +import javax.swing.JInternalFrame; +import javax.swing.JScrollPane; +import javax.swing.JViewport; + +/** + * Private class used to replace the standard DesktopManager for JDesktopPane. + * Used to provide scrollbar functionality. + */ +public class MDIDesktopManager extends DefaultDesktopManager { + private MDIDesktopPane desktop; + + public MDIDesktopManager(MDIDesktopPane desktop) { + this.desktop = desktop; + } + + public void endResizingFrame(JComponent f) { + super.endResizingFrame(f); + resizeDesktop(); + } + + public void endDraggingFrame(JComponent f) { + super.endDraggingFrame(f); + resizeDesktop(); + } + + public void setNormalSize() { + JScrollPane scrollPane = getScrollPane(); + int x = 0; + int y = 0; + Insets scrollInsets = getScrollPaneInsets(); + + if (scrollPane != null) { + Dimension d = scrollPane.getVisibleRect().getSize(); + if (scrollPane.getBorder() != null) { + d.setSize( + d.getWidth() - scrollInsets.left - scrollInsets.right, + d.getHeight() - scrollInsets.top - scrollInsets.bottom); + } + + d.setSize(d.getWidth() - 20, d.getHeight() - 20); + desktop.setAllSize(x, y); + scrollPane.invalidate(); + scrollPane.validate(); + } + } + + private Insets getScrollPaneInsets() { + JScrollPane scrollPane = getScrollPane(); + if (scrollPane == null) + return new Insets(0, 0, 0, 0); + else + return getScrollPane().getBorder().getBorderInsets(scrollPane); + } + + private JScrollPane getScrollPane() { + if (desktop.getParent() instanceof JViewport) { + JViewport viewPort = (JViewport) desktop.getParent(); + if (viewPort.getParent() instanceof JScrollPane) + return (JScrollPane) viewPort.getParent(); + } + return null; + } + + protected void resizeDesktop() { + int x = 0; + int y = 0; + JScrollPane scrollPane = getScrollPane(); + Insets scrollInsets = getScrollPaneInsets(); + + if (scrollPane != null) { + JInternalFrame allFrames[] = desktop.getAllFrames(); + for (int i = 0; i < allFrames.length; i++) { + if (allFrames[i].getX() + allFrames[i].getWidth() > x) { + x = allFrames[i].getX() + allFrames[i].getWidth(); + } + if (allFrames[i].getY() + allFrames[i].getHeight() > y) { + y = allFrames[i].getY() + allFrames[i].getHeight(); + } + } + Dimension d = scrollPane.getVisibleRect().getSize(); + if (scrollPane.getBorder() != null) { + d.setSize( + d.getWidth() - scrollInsets.left - scrollInsets.right, + d.getHeight() - scrollInsets.top - scrollInsets.bottom); + } + + if (x <= d.getWidth()) + x = ((int) d.getWidth()) - 20; + if (y <= d.getHeight()) + y = ((int) d.getHeight()) - 20; + desktop.setAllSize(x, y); + scrollPane.invalidate(); + scrollPane.validate(); + } + } +} + diff --git a/src/org/egonet/mdi/MDIDesktopPane.java b/src/main/java/org/egonet/mdi/MDIDesktopPane.java similarity index 96% rename from src/org/egonet/mdi/MDIDesktopPane.java rename to src/main/java/org/egonet/mdi/MDIDesktopPane.java index d87b673..8b37f13 100644 --- a/src/org/egonet/mdi/MDIDesktopPane.java +++ b/src/main/java/org/egonet/mdi/MDIDesktopPane.java @@ -1,131 +1,131 @@ -package org.egonet.mdi; - -import java.awt.Component; -import java.awt.Dimension; -import java.awt.Point; -import java.beans.PropertyVetoException; - -import javax.swing.JDesktopPane; -import javax.swing.JInternalFrame; - -/** - * An extension of WDesktopPane that supports often used MDI functionality. This - * class also handles setting scroll bars for when windows move too far to the - * left or bottom, providing the MDIDesktopPane is in a ScrollPane. - */ -public class MDIDesktopPane extends JDesktopPane { - private static int FRAME_OFFSET = 20; - - private MDIDesktopManager manager; - - public MDIDesktopPane() { - manager = new MDIDesktopManager(this); - setDesktopManager(manager); - setDragMode(JDesktopPane.OUTLINE_DRAG_MODE); - } - - public void setBounds(int x, int y, int w, int h) { - super.setBounds(x, y, w, h); - checkDesktopSize(); - } - - public Component add(JInternalFrame frame) { - JInternalFrame[] array = getAllFrames(); - Point p; - int w; - int h; - - Component retval = super.add(frame); - checkDesktopSize(); - if (array.length > 0) { - p = array[0].getLocation(); - p.x = p.x + FRAME_OFFSET; - p.y = p.y + FRAME_OFFSET; - } else { - p = new Point(0, 0); - } - frame.setLocation(p.x, p.y); - if (frame.isResizable()) { - w = getWidth() - (getWidth() / 3); - h = getHeight() - (getHeight() / 3); - if (w < frame.getMinimumSize().getWidth()) - w = (int) frame.getMinimumSize().getWidth(); - if (h < frame.getMinimumSize().getHeight()) - h = (int) frame.getMinimumSize().getHeight(); - frame.setSize(w, h); - } - moveToFront(frame); - frame.setVisible(true); - try { - frame.setSelected(true); - } catch (PropertyVetoException e) { - frame.toBack(); - } - return retval; - } - - public void remove(Component c) { - super.remove(c); - checkDesktopSize(); - } - - /** - * Cascade all internal frames - */ - public void cascadeFrames() { - int x = 0; - int y = 0; - JInternalFrame allFrames[] = getAllFrames(); - - manager.setNormalSize(); - int frameHeight = (getBounds().height - 5) - allFrames.length - * FRAME_OFFSET; - int frameWidth = (getBounds().width - 5) - allFrames.length - * FRAME_OFFSET; - for (int i = allFrames.length - 1; i >= 0; i--) { - allFrames[i].setSize(frameWidth, frameHeight); - allFrames[i].setLocation(x, y); - x = x + FRAME_OFFSET; - y = y + FRAME_OFFSET; - } - } - - /** - * Tile all internal frames - */ - public void tileFrames() { - java.awt.Component allFrames[] = getAllFrames(); - manager.setNormalSize(); - int frameHeight = getBounds().height / allFrames.length; - int y = 0; - for (int i = 0; i < allFrames.length; i++) { - allFrames[i].setSize(getBounds().width, frameHeight); - allFrames[i].setLocation(0, y); - y = y + frameHeight; - } - } - - /** - * Sets all component size properties ( maximum, minimum, preferred) to the - * given dimension. - */ - public void setAllSize(Dimension d) { - setMinimumSize(d); - setMaximumSize(d); - setPreferredSize(d); - } - - /** - * Sets all component size properties ( maximum, minimum, preferred) to the - * given width and height. - */ - public void setAllSize(int width, int height) { - setAllSize(new Dimension(width, height)); - } - - private void checkDesktopSize() { - if (getParent() != null && isVisible()) - manager.resizeDesktop(); - } -} - +package org.egonet.mdi; + +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Point; +import java.beans.PropertyVetoException; + +import javax.swing.JDesktopPane; +import javax.swing.JInternalFrame; + +/** + * An extension of WDesktopPane that supports often used MDI functionality. This + * class also handles setting scroll bars for when windows move too far to the + * left or bottom, providing the MDIDesktopPane is in a ScrollPane. + */ +public class MDIDesktopPane extends JDesktopPane { + private static int FRAME_OFFSET = 20; + + private MDIDesktopManager manager; + + public MDIDesktopPane() { + manager = new MDIDesktopManager(this); + setDesktopManager(manager); + setDragMode(JDesktopPane.OUTLINE_DRAG_MODE); + } + + public void setBounds(int x, int y, int w, int h) { + super.setBounds(x, y, w, h); + checkDesktopSize(); + } + + public Component add(JInternalFrame frame) { + JInternalFrame[] array = getAllFrames(); + Point p; + int w; + int h; + + Component retval = super.add(frame); + checkDesktopSize(); + if (array.length > 0) { + p = array[0].getLocation(); + p.x = p.x + FRAME_OFFSET; + p.y = p.y + FRAME_OFFSET; + } else { + p = new Point(0, 0); + } + frame.setLocation(p.x, p.y); + if (frame.isResizable()) { + w = getWidth() - (getWidth() / 3); + h = getHeight() - (getHeight() / 3); + if (w < frame.getMinimumSize().getWidth()) + w = (int) frame.getMinimumSize().getWidth(); + if (h < frame.getMinimumSize().getHeight()) + h = (int) frame.getMinimumSize().getHeight(); + frame.setSize(w, h); + } + moveToFront(frame); + frame.setVisible(true); + try { + frame.setSelected(true); + } catch (PropertyVetoException e) { + frame.toBack(); + } + return retval; + } + + public void remove(Component c) { + super.remove(c); + checkDesktopSize(); + } + + /** + * Cascade all internal frames + */ + public void cascadeFrames() { + int x = 0; + int y = 0; + JInternalFrame allFrames[] = getAllFrames(); + + manager.setNormalSize(); + int frameHeight = (getBounds().height - 5) - allFrames.length + * FRAME_OFFSET; + int frameWidth = (getBounds().width - 5) - allFrames.length + * FRAME_OFFSET; + for (int i = allFrames.length - 1; i >= 0; i--) { + allFrames[i].setSize(frameWidth, frameHeight); + allFrames[i].setLocation(x, y); + x = x + FRAME_OFFSET; + y = y + FRAME_OFFSET; + } + } + + /** + * Tile all internal frames + */ + public void tileFrames() { + java.awt.Component allFrames[] = getAllFrames(); + manager.setNormalSize(); + int frameHeight = getBounds().height / allFrames.length; + int y = 0; + for (int i = 0; i < allFrames.length; i++) { + allFrames[i].setSize(getBounds().width, frameHeight); + allFrames[i].setLocation(0, y); + y = y + frameHeight; + } + } + + /** + * Sets all component size properties ( maximum, minimum, preferred) to the + * given dimension. + */ + public void setAllSize(Dimension d) { + setMinimumSize(d); + setMaximumSize(d); + setPreferredSize(d); + } + + /** + * Sets all component size properties ( maximum, minimum, preferred) to the + * given width and height. + */ + public void setAllSize(int width, int height) { + setAllSize(new Dimension(width, height)); + } + + private void checkDesktopSize() { + if (getParent() != null && isVisible()) + manager.resizeDesktop(); + } +} + diff --git a/src/org/egonet/mdi/TextFrame.java b/src/main/java/org/egonet/mdi/TextFrame.java similarity index 96% rename from src/org/egonet/mdi/TextFrame.java rename to src/main/java/org/egonet/mdi/TextFrame.java index 68bcf30..d9fcaeb 100644 --- a/src/org/egonet/mdi/TextFrame.java +++ b/src/main/java/org/egonet/mdi/TextFrame.java @@ -1,25 +1,25 @@ -package org.egonet.mdi; - -import java.awt.BorderLayout; - -import javax.swing.JInternalFrame; -import javax.swing.JScrollPane; -import javax.swing.JTextArea; - -public class TextFrame extends JInternalFrame { - private JTextArea textArea = new JTextArea(); - - private JScrollPane scrollPane = new JScrollPane(); - - public TextFrame() { - setSize(200, 300); - setTitle("Edit Text"); - setMaximizable(true); - setIconifiable(true); - setClosable(true); - setResizable(true); - scrollPane.getViewport().add(textArea); - getContentPane().setLayout(new BorderLayout()); - getContentPane().add(scrollPane, BorderLayout.CENTER); - } -} +package org.egonet.mdi; + +import java.awt.BorderLayout; + +import javax.swing.JInternalFrame; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; + +public class TextFrame extends JInternalFrame { + private JTextArea textArea = new JTextArea(); + + private JScrollPane scrollPane = new JScrollPane(); + + public TextFrame() { + setSize(200, 300); + setTitle("Edit Text"); + setMaximizable(true); + setIconifiable(true); + setClosable(true); + setResizable(true); + scrollPane.getViewport().add(textArea); + getContentPane().setLayout(new BorderLayout()); + getContentPane().add(scrollPane, BorderLayout.CENTER); + } +} diff --git a/src/org/egonet/mdi/WindowMenu.java b/src/main/java/org/egonet/mdi/WindowMenu.java similarity index 96% rename from src/org/egonet/mdi/WindowMenu.java rename to src/main/java/org/egonet/mdi/WindowMenu.java index 1ee9a22..9e391f5 100644 --- a/src/org/egonet/mdi/WindowMenu.java +++ b/src/main/java/org/egonet/mdi/WindowMenu.java @@ -1,108 +1,108 @@ -package org.egonet.mdi; - -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.beans.PropertyVetoException; - -import javax.swing.JCheckBoxMenuItem; -import javax.swing.JInternalFrame; -import javax.swing.JMenu; -import javax.swing.JMenuItem; -import javax.swing.event.MenuEvent; -import javax.swing.event.MenuListener; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Menu component that handles the functionality expected of a standard - * "Windows" menu for MDI applications. - */ -public class WindowMenu extends JMenu { - - final private static Logger logger = LoggerFactory.getLogger(WindowMenu.class); - - private MDIDesktopPane desktop; - - private JMenuItem cascade = new JMenuItem("Cascade"); - - private JMenuItem tile = new JMenuItem("Tile"); - - public WindowMenu(MDIDesktopPane desktop) { - this.desktop = desktop; - setText("Window"); - cascade.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent ae) { - WindowMenu.this.desktop.cascadeFrames(); - } - }); - tile.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent ae) { - WindowMenu.this.desktop.tileFrames(); - } - }); - addMenuListener(new MenuListener() { - public void menuCanceled(MenuEvent e) { - } - - public void menuDeselected(MenuEvent e) { - removeAll(); - } - - public void menuSelected(MenuEvent e) { - buildChildMenus(); - } - }); - } - - /* Sets up the children menus depending on the current desktop state */ - private void buildChildMenus() { - int i; - ChildMenuItem menu; - JInternalFrame[] array = desktop.getAllFrames(); - - add(cascade); - add(tile); - if (array.length > 0) - addSeparator(); - cascade.setEnabled(array.length > 0); - tile.setEnabled(array.length > 0); - - for (i = 0; i < array.length; i++) { - menu = new ChildMenuItem(array[i]); - menu.setState(i == 0); - menu.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent ae) { - JInternalFrame frame = ((ChildMenuItem) ae.getSource()) - .getFrame(); - frame.moveToFront(); - try { - frame.setSelected(true); - } catch (PropertyVetoException ex) { - logger.error(ex.toString()); - } - } - }); - menu.setIcon(array[i].getFrameIcon()); - add(menu); - } - } - - /* - * This JCheckBoxMenuItem descendant is used to track the child frame that - * corresponds to a give menu. - */ - class ChildMenuItem extends JCheckBoxMenuItem { - private JInternalFrame frame; - - public ChildMenuItem(JInternalFrame frame) { - super(frame.getTitle()); - this.frame = frame; - } - - public JInternalFrame getFrame() { - return frame; - } - } -} - +package org.egonet.mdi; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.beans.PropertyVetoException; + +import javax.swing.JCheckBoxMenuItem; +import javax.swing.JInternalFrame; +import javax.swing.JMenu; +import javax.swing.JMenuItem; +import javax.swing.event.MenuEvent; +import javax.swing.event.MenuListener; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Menu component that handles the functionality expected of a standard + * "Windows" menu for MDI applications. + */ +public class WindowMenu extends JMenu { + + final private static Logger logger = LoggerFactory.getLogger(WindowMenu.class); + + private MDIDesktopPane desktop; + + private JMenuItem cascade = new JMenuItem("Cascade"); + + private JMenuItem tile = new JMenuItem("Tile"); + + public WindowMenu(MDIDesktopPane desktop) { + this.desktop = desktop; + setText("Window"); + cascade.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent ae) { + WindowMenu.this.desktop.cascadeFrames(); + } + }); + tile.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent ae) { + WindowMenu.this.desktop.tileFrames(); + } + }); + addMenuListener(new MenuListener() { + public void menuCanceled(MenuEvent e) { + } + + public void menuDeselected(MenuEvent e) { + removeAll(); + } + + public void menuSelected(MenuEvent e) { + buildChildMenus(); + } + }); + } + + /* Sets up the children menus depending on the current desktop state */ + private void buildChildMenus() { + int i; + ChildMenuItem menu; + JInternalFrame[] array = desktop.getAllFrames(); + + add(cascade); + add(tile); + if (array.length > 0) + addSeparator(); + cascade.setEnabled(array.length > 0); + tile.setEnabled(array.length > 0); + + for (i = 0; i < array.length; i++) { + menu = new ChildMenuItem(array[i]); + menu.setState(i == 0); + menu.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent ae) { + JInternalFrame frame = ((ChildMenuItem) ae.getSource()) + .getFrame(); + frame.moveToFront(); + try { + frame.setSelected(true); + } catch (PropertyVetoException ex) { + logger.error(ex.toString()); + } + } + }); + menu.setIcon(array[i].getFrameIcon()); + add(menu); + } + } + + /* + * This JCheckBoxMenuItem descendant is used to track the child frame that + * corresponds to a give menu. + */ + class ChildMenuItem extends JCheckBoxMenuItem { + private JInternalFrame frame; + + public ChildMenuItem(JInternalFrame frame) { + super(frame.getTitle()); + this.frame = frame; + } + + public JInternalFrame getFrame() { + return frame; + } + } +} + diff --git a/src/org/egonet/model/question/AlterPairQuestion.java b/src/main/java/org/egonet/model/question/AlterPairQuestion.java similarity index 100% rename from src/org/egonet/model/question/AlterPairQuestion.java rename to src/main/java/org/egonet/model/question/AlterPairQuestion.java diff --git a/src/org/egonet/model/question/AlterPromptQuestion.java b/src/main/java/org/egonet/model/question/AlterPromptQuestion.java similarity index 100% rename from src/org/egonet/model/question/AlterPromptQuestion.java rename to src/main/java/org/egonet/model/question/AlterPromptQuestion.java diff --git a/src/org/egonet/model/question/AlterQuestion.java b/src/main/java/org/egonet/model/question/AlterQuestion.java similarity index 100% rename from src/org/egonet/model/question/AlterQuestion.java rename to src/main/java/org/egonet/model/question/AlterQuestion.java diff --git a/src/org/egonet/model/question/EgoQuestion.java b/src/main/java/org/egonet/model/question/EgoQuestion.java similarity index 100% rename from src/org/egonet/model/question/EgoQuestion.java rename to src/main/java/org/egonet/model/question/EgoQuestion.java diff --git a/src/org/egonet/model/question/Question.java b/src/main/java/org/egonet/model/question/Question.java similarity index 96% rename from src/org/egonet/model/question/Question.java rename to src/main/java/org/egonet/model/question/Question.java index 3cfafda..60d8a16 100644 --- a/src/org/egonet/model/question/Question.java +++ b/src/main/java/org/egonet/model/question/Question.java @@ -1,260 +1,260 @@ -/*** - * 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 . - */ -package org.egonet.model.question; -import java.util.Date; - -import org.egonet.exceptions.MalformedQuestionException; -import org.egonet.util.listbuilder.Selection; - -import com.endlessloopsoftware.egonet.Answer; -import com.endlessloopsoftware.egonet.QuestionLink; -import com.endlessloopsoftware.egonet.Shared.AnswerType; - - -/******************************************************************************* - * Routines for creating and handling atomic question elements - * - * - * - public enum QuestionType { - QuestionType(String niceName, String title) - { - this.niceName = niceName; - this.title = title; - } - } - * - * - */ -public abstract class Question implements Cloneable { - - public static String getNiceName(Class clazz) { - try { - Question instance = clazz.newInstance(); - return instance.getNiceName(); - } - catch (Exception ex) { - throw new RuntimeException(ex); - } - } - - public static String getTitle(Class clazz) { - try { - Question instance = clazz.newInstance(); - return instance.getNiceName(); - } - catch (Exception ex) { - throw new RuntimeException(ex); - } - } - - - public abstract String getNiceName(); - public abstract String getTitle(); - - public boolean centralMarker = false; - - private boolean statable = false; - - public boolean followupOnly = false; - - public boolean isFollowupOnly() { - return followupOnly; - } - - public void setFollowupOnly(boolean followupOnly) { - this.followupOnly = followupOnly; - } - - public Long UniqueId = new Long(new Date().getTime()); - - public String title = ""; - - public String text = ""; - - public String citation = ""; - - public AnswerType answerType = AnswerType.TEXT; - - public int numQAlters = -1; - - public QuestionLink link = new QuestionLink(); - - private Selection[] selections = new Selection[0]; - - private Answer answer = new Answer(new Long(-1)); - - public static final int MAX_CATEGORICAL_CHOICES = 9; - - /*************************************************************************** - * Creates question - * - * @return question new question - */ - public Question() { - } - - /*************************************************************************** - * Creates question with string as title - * - * @param s - * question title - * @return question new question - */ - public Question(String s) { - this.title = s; - } - - - /*************************************************************************** - * Returns whether a given selection is adjacent based on the values stored - * in the question. Is used to override value found in an interview file - * - * @param value - * @return true iff that selection is marked as adjacent - */ - public boolean selectionAdjacent(int value) { - boolean rval = false; - - if (this.getSelections().length > 0) { - int size = this.getSelections().length; - - for (int i = 0; i < size; i++) { - if (value == this.getSelections()[i].getValue()) { - rval = this.getSelections()[i].isAdjacent(); - break; - } - } - } - return rval; - } - - /** - * Does the answer to this question determine whether alters are adjacent? - */ - public boolean determinesAdjacency() { - for(Selection selection : getSelections()) { - if(selection.isAdjacent()) { - return true; - } - } - return false; - } - - /*************************************************************************** - * Overrides toString method for question, returns title - * - * @return String title of question - */ - public String toString() { - if (title == null) { - return (new String("Untitled")); - } else { - return (title); - } - } - - /*************************************************************************** - * Implements Clone interface for conducting an interview and cloning the study question. The clone is attached to the interview. - * - * @return Clone of Question - */ - public Object clone() { - Question q; - - try { - q = (Question) super.clone(); - q.link = (QuestionLink) this.link.clone(); - q.followupOnly = this.followupOnly; - - /******************************************************************* - * Dangerous to clone answers as multiple answers refer to same - * question Make sure they are assigned explicitly - */ - q.setAnswer(null); - } catch (CloneNotSupportedException ex) { - q = null; - } - - return q; - } - - public String getString() { - String str = ""; - str = "ID : " + UniqueId + ", Qtype="+getClass().getSimpleName()+",Atype="+answerType+", Title : " + title + " text : " + text - + "\nAnswer : " + getAnswer().getString(); - return str; - } - - public void setSelections(Selection[] selections) { - this.selections = selections; - } - - public Selection[] getSelections() { - return selections; - } - - public Answer getAnswer() { - return answer; - } - - public void setAnswer(Answer answer) { - this.answer = answer; - } - - public boolean isStatable() { - return statable; - } - - public void setStatable(boolean statable) { - this.statable = statable; - } - - public static Question newInstance(String questionType) { - try { - Class clazz = asSubclass(questionType); - - return newInstance(clazz); - } - catch (Exception ex) { - throw new MalformedQuestionException(ex); - } - } - - public static Question newInstance(Class clazz) { - try { - return clazz.newInstance(); - } - catch (Exception ex) { - throw new MalformedQuestionException(ex); - } - } - - public static Class asSubclass(String questionType) { - try { - @SuppressWarnings("unchecked") - Class clazz = (Class)Class.forName(questionType); - - return clazz; - } - catch (Exception ex) { - throw new MalformedQuestionException(ex); - } - } -} +/*** + * 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 . + */ +package org.egonet.model.question; +import java.util.Date; + +import org.egonet.exceptions.MalformedQuestionException; +import org.egonet.util.listbuilder.Selection; + +import com.endlessloopsoftware.egonet.Answer; +import com.endlessloopsoftware.egonet.QuestionLink; +import com.endlessloopsoftware.egonet.Shared.AnswerType; + + +/******************************************************************************* + * Routines for creating and handling atomic question elements + * + * + * + public enum QuestionType { + QuestionType(String niceName, String title) + { + this.niceName = niceName; + this.title = title; + } + } + * + * + */ +public abstract class Question implements Cloneable { + + public static String getNiceName(Class clazz) { + try { + Question instance = clazz.newInstance(); + return instance.getNiceName(); + } + catch (Exception ex) { + throw new RuntimeException(ex); + } + } + + public static String getTitle(Class clazz) { + try { + Question instance = clazz.newInstance(); + return instance.getNiceName(); + } + catch (Exception ex) { + throw new RuntimeException(ex); + } + } + + + public abstract String getNiceName(); + public abstract String getTitle(); + + public boolean centralMarker = false; + + private boolean statable = false; + + public boolean followupOnly = false; + + public boolean isFollowupOnly() { + return followupOnly; + } + + public void setFollowupOnly(boolean followupOnly) { + this.followupOnly = followupOnly; + } + + public Long UniqueId = new Long(new Date().getTime()); + + public String title = ""; + + public String text = ""; + + public String citation = ""; + + public AnswerType answerType = AnswerType.TEXT; + + public int numQAlters = -1; + + public QuestionLink link = new QuestionLink(); + + private Selection[] selections = new Selection[0]; + + private Answer answer = new Answer(new Long(-1)); + + public static final int MAX_CATEGORICAL_CHOICES = 9; + + /*************************************************************************** + * Creates question + * + * @return question new question + */ + public Question() { + } + + /*************************************************************************** + * Creates question with string as title + * + * @param s + * question title + * @return question new question + */ + public Question(String s) { + this.title = s; + } + + + /*************************************************************************** + * Returns whether a given selection is adjacent based on the values stored + * in the question. Is used to override value found in an interview file + * + * @param value + * @return true iff that selection is marked as adjacent + */ + public boolean selectionAdjacent(int value) { + boolean rval = false; + + if (this.getSelections().length > 0) { + int size = this.getSelections().length; + + for (int i = 0; i < size; i++) { + if (value == this.getSelections()[i].getValue()) { + rval = this.getSelections()[i].isAdjacent(); + break; + } + } + } + return rval; + } + + /** + * Does the answer to this question determine whether alters are adjacent? + */ + public boolean determinesAdjacency() { + for(Selection selection : getSelections()) { + if(selection.isAdjacent()) { + return true; + } + } + return false; + } + + /*************************************************************************** + * Overrides toString method for question, returns title + * + * @return String title of question + */ + public String toString() { + if (title == null) { + return (new String("Untitled")); + } else { + return (title); + } + } + + /*************************************************************************** + * Implements Clone interface for conducting an interview and cloning the study question. The clone is attached to the interview. + * + * @return Clone of Question + */ + public Object clone() { + Question q; + + try { + q = (Question) super.clone(); + q.link = (QuestionLink) this.link.clone(); + q.followupOnly = this.followupOnly; + + /******************************************************************* + * Dangerous to clone answers as multiple answers refer to same + * question Make sure they are assigned explicitly + */ + q.setAnswer(null); + } catch (CloneNotSupportedException ex) { + q = null; + } + + return q; + } + + public String getString() { + String str = ""; + str = "ID : " + UniqueId + ", Qtype="+getClass().getSimpleName()+",Atype="+answerType+", Title : " + title + " text : " + text + + "\nAnswer : " + getAnswer().getString(); + return str; + } + + public void setSelections(Selection[] selections) { + this.selections = selections; + } + + public Selection[] getSelections() { + return selections; + } + + public Answer getAnswer() { + return answer; + } + + public void setAnswer(Answer answer) { + this.answer = answer; + } + + public boolean isStatable() { + return statable; + } + + public void setStatable(boolean statable) { + this.statable = statable; + } + + public static Question newInstance(String questionType) { + try { + Class clazz = asSubclass(questionType); + + return newInstance(clazz); + } + catch (Exception ex) { + throw new MalformedQuestionException(ex); + } + } + + public static Question newInstance(Class clazz) { + try { + return clazz.newInstance(); + } + catch (Exception ex) { + throw new MalformedQuestionException(ex); + } + } + + public static Class asSubclass(String questionType) { + try { + @SuppressWarnings("unchecked") + Class clazz = (Class)Class.forName(questionType); + + return clazz; + } + catch (Exception ex) { + throw new MalformedQuestionException(ex); + } + } +} diff --git a/src/org/egonet/model/question/StudyQuestion.java b/src/main/java/org/egonet/model/question/StudyQuestion.java similarity index 100% rename from src/org/egonet/model/question/StudyQuestion.java rename to src/main/java/org/egonet/model/question/StudyQuestion.java diff --git a/src/org/egonet/util/AboutBox.java b/src/main/java/org/egonet/util/AboutBox.java similarity index 100% rename from src/org/egonet/util/AboutBox.java rename to src/main/java/org/egonet/util/AboutBox.java diff --git a/src/org/egonet/util/AlphaDocument.java b/src/main/java/org/egonet/util/AlphaDocument.java similarity index 100% rename from src/org/egonet/util/AlphaDocument.java rename to src/main/java/org/egonet/util/AlphaDocument.java diff --git a/src/org/egonet/util/ArrowIcon.java b/src/main/java/org/egonet/util/ArrowIcon.java similarity index 100% rename from src/org/egonet/util/ArrowIcon.java rename to src/main/java/org/egonet/util/ArrowIcon.java diff --git a/src/org/egonet/util/AsymmetricEncryption.java b/src/main/java/org/egonet/util/AsymmetricEncryption.java similarity index 100% rename from src/org/egonet/util/AsymmetricEncryption.java rename to src/main/java/org/egonet/util/AsymmetricEncryption.java diff --git a/src/org/egonet/util/Back24.gif b/src/main/java/org/egonet/util/Back24.gif similarity index 100% rename from src/org/egonet/util/Back24.gif rename to src/main/java/org/egonet/util/Back24.gif diff --git a/src/org/egonet/util/CardPanel.java b/src/main/java/org/egonet/util/CardPanel.java similarity index 100% rename from src/org/egonet/util/CardPanel.java rename to src/main/java/org/egonet/util/CardPanel.java diff --git a/src/org/egonet/util/CatchingAction.java b/src/main/java/org/egonet/util/CatchingAction.java similarity index 100% rename from src/org/egonet/util/CatchingAction.java rename to src/main/java/org/egonet/util/CatchingAction.java diff --git a/src/org/egonet/util/Console.java b/src/main/java/org/egonet/util/Console.java similarity index 100% rename from src/org/egonet/util/Console.java rename to src/main/java/org/egonet/util/Console.java diff --git a/src/org/egonet/util/CyclingSpinnerListModel.java b/src/main/java/org/egonet/util/CyclingSpinnerListModel.java similarity index 100% rename from src/org/egonet/util/CyclingSpinnerListModel.java rename to src/main/java/org/egonet/util/CyclingSpinnerListModel.java diff --git a/src/org/egonet/util/DateUtils.java b/src/main/java/org/egonet/util/DateUtils.java similarity index 100% rename from src/org/egonet/util/DateUtils.java rename to src/main/java/org/egonet/util/DateUtils.java diff --git a/src/org/egonet/util/EJBUtils.java b/src/main/java/org/egonet/util/EJBUtils.java similarity index 100% rename from src/org/egonet/util/EJBUtils.java rename to src/main/java/org/egonet/util/EJBUtils.java diff --git a/src/org/egonet/util/ELSCalendar.java b/src/main/java/org/egonet/util/ELSCalendar.java similarity index 100% rename from src/org/egonet/util/ELSCalendar.java rename to src/main/java/org/egonet/util/ELSCalendar.java diff --git a/src/org/egonet/util/ELSMath.java b/src/main/java/org/egonet/util/ELSMath.java similarity index 100% rename from src/org/egonet/util/ELSMath.java rename to src/main/java/org/egonet/util/ELSMath.java diff --git a/src/org/egonet/util/ELSProgressBar.java b/src/main/java/org/egonet/util/ELSProgressBar.java similarity index 100% rename from src/org/egonet/util/ELSProgressBar.java rename to src/main/java/org/egonet/util/ELSProgressBar.java diff --git a/src/org/egonet/util/EgonetAnalytics.java b/src/main/java/org/egonet/util/EgonetAnalytics.java similarity index 100% rename from src/org/egonet/util/EgonetAnalytics.java rename to src/main/java/org/egonet/util/EgonetAnalytics.java diff --git a/src/org/egonet/util/ExtensionFileFilter.java b/src/main/java/org/egonet/util/ExtensionFileFilter.java similarity index 100% rename from src/org/egonet/util/ExtensionFileFilter.java rename to src/main/java/org/egonet/util/ExtensionFileFilter.java diff --git a/src/org/egonet/util/FileHelpers.java b/src/main/java/org/egonet/util/FileHelpers.java similarity index 100% rename from src/org/egonet/util/FileHelpers.java rename to src/main/java/org/egonet/util/FileHelpers.java diff --git a/src/org/egonet/util/Forward24.gif b/src/main/java/org/egonet/util/Forward24.gif similarity index 100% rename from src/org/egonet/util/Forward24.gif rename to src/main/java/org/egonet/util/Forward24.gif diff --git a/src/org/egonet/util/GifEncoder.java b/src/main/java/org/egonet/util/GifEncoder.java similarity index 100% rename from src/org/egonet/util/GifEncoder.java rename to src/main/java/org/egonet/util/GifEncoder.java diff --git a/src/org/egonet/util/ImageEncoder.java b/src/main/java/org/egonet/util/ImageEncoder.java similarity index 100% rename from src/org/egonet/util/ImageEncoder.java rename to src/main/java/org/egonet/util/ImageEncoder.java diff --git a/src/org/egonet/util/ImageFilter.java b/src/main/java/org/egonet/util/ImageFilter.java similarity index 100% rename from src/org/egonet/util/ImageFilter.java rename to src/main/java/org/egonet/util/ImageFilter.java diff --git a/src/org/egonet/util/Interval.java b/src/main/java/org/egonet/util/Interval.java similarity index 100% rename from src/org/egonet/util/Interval.java rename to src/main/java/org/egonet/util/Interval.java diff --git a/src/org/egonet/util/ListFormPanel.java b/src/main/java/org/egonet/util/ListFormPanel.java similarity index 100% rename from src/org/egonet/util/ListFormPanel.java rename to src/main/java/org/egonet/util/ListFormPanel.java diff --git a/src/org/egonet/util/Name.java b/src/main/java/org/egonet/util/Name.java similarity index 95% rename from src/org/egonet/util/Name.java rename to src/main/java/org/egonet/util/Name.java index 24a403d..13dfec2 100644 --- a/src/org/egonet/util/Name.java +++ b/src/main/java/org/egonet/util/Name.java @@ -1,23 +1,23 @@ -package org.egonet.util; - -public class Name { - private String first,last; - public Name(String first, String last) { - this.first = first; - this.last = last; - } - public Name(String only) { - this.first = only; - this.last = null; - } - public String toString(String separator) { - return - (first == null ? "" : first) + - (first == null || last == null ? "" : separator) + - (last == null ? "" : last); - - } - public String toString() { - return toString(" "); - } -} +package org.egonet.util; + +public class Name { + private String first,last; + public Name(String first, String last) { + this.first = first; + this.last = last; + } + public Name(String only) { + this.first = only; + this.last = null; + } + public String toString(String separator) { + return + (first == null ? "" : first) + + (first == null || last == null ? "" : separator) + + (last == null ? "" : last); + + } + public String toString() { + return toString(" "); + } +} diff --git a/src/org/egonet/util/ObservableList.java b/src/main/java/org/egonet/util/ObservableList.java similarity index 100% rename from src/org/egonet/util/ObservableList.java rename to src/main/java/org/egonet/util/ObservableList.java diff --git a/src/org/egonet/util/PagePreview.java b/src/main/java/org/egonet/util/PagePreview.java similarity index 100% rename from src/org/egonet/util/PagePreview.java rename to src/main/java/org/egonet/util/PagePreview.java diff --git a/src/org/egonet/util/PhoneBean.java b/src/main/java/org/egonet/util/PhoneBean.java similarity index 100% rename from src/org/egonet/util/PhoneBean.java rename to src/main/java/org/egonet/util/PhoneBean.java diff --git a/src/org/egonet/util/Print24.gif b/src/main/java/org/egonet/util/Print24.gif similarity index 100% rename from src/org/egonet/util/Print24.gif rename to src/main/java/org/egonet/util/Print24.gif diff --git a/src/org/egonet/util/PrintPreview.java b/src/main/java/org/egonet/util/PrintPreview.java similarity index 100% rename from src/org/egonet/util/PrintPreview.java rename to src/main/java/org/egonet/util/PrintPreview.java diff --git a/src/org/egonet/util/PronouncablePassword.java b/src/main/java/org/egonet/util/PronouncablePassword.java similarity index 100% rename from src/org/egonet/util/PronouncablePassword.java rename to src/main/java/org/egonet/util/PronouncablePassword.java diff --git a/src/org/egonet/util/RegexFormatter.java b/src/main/java/org/egonet/util/RegexFormatter.java similarity index 100% rename from src/org/egonet/util/RegexFormatter.java rename to src/main/java/org/egonet/util/RegexFormatter.java diff --git a/src/org/egonet/util/Selection.java b/src/main/java/org/egonet/util/Selection.java similarity index 100% rename from src/org/egonet/util/Selection.java rename to src/main/java/org/egonet/util/Selection.java diff --git a/src/org/egonet/util/SizeConstrainedDocument.java b/src/main/java/org/egonet/util/SizeConstrainedDocument.java similarity index 100% rename from src/org/egonet/util/SizeConstrainedDocument.java rename to src/main/java/org/egonet/util/SizeConstrainedDocument.java diff --git a/src/org/egonet/util/SortByField.java b/src/main/java/org/egonet/util/SortByField.java similarity index 100% rename from src/org/egonet/util/SortByField.java rename to src/main/java/org/egonet/util/SortByField.java diff --git a/src/org/egonet/util/StringUtils.java b/src/main/java/org/egonet/util/StringUtils.java similarity index 100% rename from src/org/egonet/util/StringUtils.java rename to src/main/java/org/egonet/util/StringUtils.java diff --git a/src/org/egonet/util/SwingWorker.java b/src/main/java/org/egonet/util/SwingWorker.java similarity index 100% rename from src/org/egonet/util/SwingWorker.java rename to src/main/java/org/egonet/util/SwingWorker.java diff --git a/src/org/egonet/util/SymmetricKeyEncryption.java b/src/main/java/org/egonet/util/SymmetricKeyEncryption.java similarity index 100% rename from src/org/egonet/util/SymmetricKeyEncryption.java rename to src/main/java/org/egonet/util/SymmetricKeyEncryption.java diff --git a/src/org/egonet/util/TestProgress.java b/src/main/java/org/egonet/util/TestProgress.java similarity index 100% rename from src/org/egonet/util/TestProgress.java rename to src/main/java/org/egonet/util/TestProgress.java diff --git a/src/org/egonet/util/Tuple.java b/src/main/java/org/egonet/util/Tuple.java similarity index 95% rename from src/org/egonet/util/Tuple.java rename to src/main/java/org/egonet/util/Tuple.java index 5867838..7cedad5 100644 --- a/src/org/egonet/util/Tuple.java +++ b/src/main/java/org/egonet/util/Tuple.java @@ -1,38 +1,38 @@ -package org.egonet.util; - -public class Tuple, B extends Comparable> extends Object { - private final A a; - private final B b; - public Tuple(A a, B b) { - this.a = a; - this.b = b; - } - public A first() { - return a; - } - public B second() { - return b; - } - @Override - public int hashCode() { - return 13*a.hashCode() + 27*b.hashCode(); - } - @Override - public boolean equals(Object o) { - // we don't really need generics in this implementation, since we delegate to A#equals which - // always exists because the type A is always somehow a subtype of Object which has #equals. - - if(!(o instanceof Tuple)) - return false; - - //@SuppressWarnings("unchecked") - Tuple p = (Tuple)o; - - return p.first().equals(first()) && p.second().equals(second()); - } - @Override - public String toString() { - return "Tuple("+first()+","+second()+")"; - } -} - +package org.egonet.util; + +public class Tuple, B extends Comparable> extends Object { + private final A a; + private final B b; + public Tuple(A a, B b) { + this.a = a; + this.b = b; + } + public A first() { + return a; + } + public B second() { + return b; + } + @Override + public int hashCode() { + return 13*a.hashCode() + 27*b.hashCode(); + } + @Override + public boolean equals(Object o) { + // we don't really need generics in this implementation, since we delegate to A#equals which + // always exists because the type A is always somehow a subtype of Object which has #equals. + + if(!(o instanceof Tuple)) + return false; + + //@SuppressWarnings("unchecked") + Tuple p = (Tuple)o; + + return p.first().equals(first()) && p.second().equals(second()); + } + @Override + public String toString() { + return "Tuple("+first()+","+second()+")"; + } +} + diff --git a/src/org/egonet/util/WholeNumberDocument.java b/src/main/java/org/egonet/util/WholeNumberDocument.java similarity index 100% rename from src/org/egonet/util/WholeNumberDocument.java rename to src/main/java/org/egonet/util/WholeNumberDocument.java diff --git a/src/org/egonet/util/ZoomIn24.gif b/src/main/java/org/egonet/util/ZoomIn24.gif similarity index 100% rename from src/org/egonet/util/ZoomIn24.gif rename to src/main/java/org/egonet/util/ZoomIn24.gif diff --git a/src/org/egonet/util/ZoomOut24.gif b/src/main/java/org/egonet/util/ZoomOut24.gif similarity index 100% rename from src/org/egonet/util/ZoomOut24.gif rename to src/main/java/org/egonet/util/ZoomOut24.gif diff --git a/src/org/egonet/util/listbuilder/ListBuilder.java b/src/main/java/org/egonet/util/listbuilder/ListBuilder.java similarity index 100% rename from src/org/egonet/util/listbuilder/ListBuilder.java rename to src/main/java/org/egonet/util/listbuilder/ListBuilder.java diff --git a/src/org/egonet/util/listbuilder/ListBuilderPresets.java b/src/main/java/org/egonet/util/listbuilder/ListBuilderPresets.java similarity index 100% rename from src/org/egonet/util/listbuilder/ListBuilderPresets.java rename to src/main/java/org/egonet/util/listbuilder/ListBuilderPresets.java diff --git a/src/org/egonet/util/listbuilder/ObservableList.java b/src/main/java/org/egonet/util/listbuilder/ObservableList.java similarity index 100% rename from src/org/egonet/util/listbuilder/ObservableList.java rename to src/main/java/org/egonet/util/listbuilder/ObservableList.java diff --git a/src/org/egonet/util/listbuilder/OldListTester.java b/src/main/java/org/egonet/util/listbuilder/OldListTester.java similarity index 100% rename from src/org/egonet/util/listbuilder/OldListTester.java rename to src/main/java/org/egonet/util/listbuilder/OldListTester.java diff --git a/src/org/egonet/util/listbuilder/Selection.java b/src/main/java/org/egonet/util/listbuilder/Selection.java similarity index 100% rename from src/org/egonet/util/listbuilder/Selection.java rename to src/main/java/org/egonet/util/listbuilder/Selection.java diff --git a/src/org/egonet/util/listbuilder/SelectionListCellRenderer.java b/src/main/java/org/egonet/util/listbuilder/SelectionListCellRenderer.java similarity index 100% rename from src/org/egonet/util/listbuilder/SelectionListCellRenderer.java rename to src/main/java/org/egonet/util/listbuilder/SelectionListCellRenderer.java diff --git a/src/org/egonet/util/print.gif b/src/main/java/org/egonet/util/print.gif similarity index 100% rename from src/org/egonet/util/print.gif rename to src/main/java/org/egonet/util/print.gif diff --git a/src/org/egonet/util/table/ChoosablePropertyTableModel.java b/src/main/java/org/egonet/util/table/ChoosablePropertyTableModel.java similarity index 100% rename from src/org/egonet/util/table/ChoosablePropertyTableModel.java rename to src/main/java/org/egonet/util/table/ChoosablePropertyTableModel.java diff --git a/src/org/egonet/util/table/ColorChooserEditor.java b/src/main/java/org/egonet/util/table/ColorChooserEditor.java similarity index 100% rename from src/org/egonet/util/table/ColorChooserEditor.java rename to src/main/java/org/egonet/util/table/ColorChooserEditor.java diff --git a/src/org/egonet/util/table/ColorEditor.java b/src/main/java/org/egonet/util/table/ColorEditor.java similarity index 100% rename from src/org/egonet/util/table/ColorEditor.java rename to src/main/java/org/egonet/util/table/ColorEditor.java diff --git a/src/org/egonet/util/table/ColorRenderer.java b/src/main/java/org/egonet/util/table/ColorRenderer.java similarity index 100% rename from src/org/egonet/util/table/ColorRenderer.java rename to src/main/java/org/egonet/util/table/ColorRenderer.java diff --git a/src/org/egonet/util/table/ComboTableCellRenderer.java b/src/main/java/org/egonet/util/table/ComboTableCellRenderer.java similarity index 100% rename from src/org/egonet/util/table/ComboTableCellRenderer.java rename to src/main/java/org/egonet/util/table/ComboTableCellRenderer.java diff --git a/src/org/egonet/util/table/DiamondIcon.java b/src/main/java/org/egonet/util/table/DiamondIcon.java similarity index 100% rename from src/org/egonet/util/table/DiamondIcon.java rename to src/main/java/org/egonet/util/table/DiamondIcon.java diff --git a/src/org/egonet/util/table/EgonetTableModel.java b/src/main/java/org/egonet/util/table/EgonetTableModel.java similarity index 100% rename from src/org/egonet/util/table/EgonetTableModel.java rename to src/main/java/org/egonet/util/table/EgonetTableModel.java diff --git a/src/org/egonet/util/table/LabelRenderer.java b/src/main/java/org/egonet/util/table/LabelRenderer.java similarity index 100% rename from src/org/egonet/util/table/LabelRenderer.java rename to src/main/java/org/egonet/util/table/LabelRenderer.java diff --git a/src/org/egonet/util/table/LabelTableModel.java b/src/main/java/org/egonet/util/table/LabelTableModel.java similarity index 100% rename from src/org/egonet/util/table/LabelTableModel.java rename to src/main/java/org/egonet/util/table/LabelTableModel.java diff --git a/src/org/egonet/util/table/PropertyTableModel.java b/src/main/java/org/egonet/util/table/PropertyTableModel.java similarity index 100% rename from src/org/egonet/util/table/PropertyTableModel.java rename to src/main/java/org/egonet/util/table/PropertyTableModel.java diff --git a/src/org/egonet/util/table/SelectionTableModel.java b/src/main/java/org/egonet/util/table/SelectionTableModel.java similarity index 100% rename from src/org/egonet/util/table/SelectionTableModel.java rename to src/main/java/org/egonet/util/table/SelectionTableModel.java diff --git a/src/org/egonet/util/table/TableComboBoxRenderer.java b/src/main/java/org/egonet/util/table/TableComboBoxRenderer.java similarity index 100% rename from src/org/egonet/util/table/TableComboBoxRenderer.java rename to src/main/java/org/egonet/util/table/TableComboBoxRenderer.java diff --git a/src/org/egonet/util/table/TableModelBoolean.java b/src/main/java/org/egonet/util/table/TableModelBoolean.java similarity index 100% rename from src/org/egonet/util/table/TableModelBoolean.java rename to src/main/java/org/egonet/util/table/TableModelBoolean.java diff --git a/src/org/egonet/wholenet/graph/WholeNetwork.java b/src/main/java/org/egonet/wholenet/graph/WholeNetwork.java similarity index 97% rename from src/org/egonet/wholenet/graph/WholeNetwork.java rename to src/main/java/org/egonet/wholenet/graph/WholeNetwork.java index 8a0e3a9..c90cb37 100644 --- a/src/org/egonet/wholenet/graph/WholeNetwork.java +++ b/src/main/java/org/egonet/wholenet/graph/WholeNetwork.java @@ -1,278 +1,278 @@ -package org.egonet.wholenet.graph; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.Map.Entry; - -import net.sf.functionalj.Function2; -import net.sf.functionalj.tuple.Pair; - -import org.egonet.exceptions.MissingPairException; -import org.egonet.model.question.AlterPairQuestion; -import org.egonet.model.question.Question; -import org.egonet.wholenet.graph.WholeNetworkTie.DiscrepancyStrategy; -import org.egonet.wholenet.gui.NameMapperFrame.NameMapping; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.endlessloopsoftware.egonet.Interview; -import com.endlessloopsoftware.egonet.Study; -import com.google.common.collect.Sets; - -/** - * This class encapsulates everything necessary to compile and retain data from - * a set of Egonet interviews into a whole network, including alter mappings. - * - * @author Martin - * - */ -public class WholeNetwork { - - final private static Logger logger = LoggerFactory.getLogger(WholeNetwork.class); - - final private Study study; - final private List interviews; - final private List nameMap; - - // maps for fast access - private Map wholeNetworkAlters; - private Map,WholeNetworkTie> wholeNetworkTies; - - private Settings settings; - - public WholeNetwork(Study study, List interviews, - List nameMap, Settings settings, - Function2,Interview,Integer> getAlterAttributes) - { - super(); - this.study = study; - this.interviews = interviews; - this.nameMap = nameMap; - this.settings = settings; - build(getAlterAttributes); - } - - public static class Settings { - public Integer inclusionThreshold = 1; - public Boolean alwaysIncludeEgo = true; - public Boolean egoAlwaysTiedToOwnAlters = true; - public DiscrepancyStrategy discrepancyStrategy = DiscrepancyStrategy.Majority; - } - - public void build(Function2,Interview,Integer> getAlterAttributes) { - wholeNetworkAlters = new HashMap(); - wholeNetworkTies = new HashMap,WholeNetworkTie>(); - - // add all alters - for(NameMapping mapping : nameMap) { - int group = mapping.getGroup(); - if(!wholeNetworkAlters.containsKey(group)) { - wholeNetworkAlters.put(group, new WholeNetworkAlter(group)); - } - - WholeNetworkAlter alter = wholeNetworkAlters.get(group); - alter.addOccurence(mapping); - } - - // remove WholeNetworkAlters that are not mentioned in enough interviews - Map remainingAlters = new HashMap(); - for(Entry entry : wholeNetworkAlters.entrySet()) { - if(entry.getValue().getOccurences().size() < settings.inclusionThreshold) { - if(settings.alwaysIncludeEgo) { - boolean isEgo = false; - for(NameMapping occurrence : entry.getValue().getOccurences()) { - if(occurrence.getAlterNumber().equals(-1)) { - isEgo = true; - } - } - if(isEgo) { - remainingAlters.put(entry.getKey(), entry.getValue()); - } - } - } else { - // Include alter only if mentioned in enough interviews. - remainingAlters.put(entry.getKey(), entry.getValue()); - } - } - wholeNetworkAlters = remainingAlters; - - // Set attributes for remaining alters - for(WholeNetworkAlter wholeNetworkAlter : wholeNetworkAlters.values()) { - for(NameMapping mapping : wholeNetworkAlter.getOccurences()) { - wholeNetworkAlter.addAttributes( - getAlterAttributes.call( - mapping.getInterview(), - mapping.getAlterNumber())); - } - } - - for(Interview interview : interviews) { - - String [] thisInterviewAlterlist = interview.getAlterList(); - - // tie the ego to all alters - Pair ego = findAlter(interview, -1); - if(ego != null) { - for(int i = 0; i < interview.getAlterList().length; i++) { - Pair alter = findAlter(interview, i); - if(alter != null) { - tie(ego, alter, ego.getFirst().getId(), true, true); - } - } - } - - // tie adjacent alters together - Iterator questions = study.getQuestionOrder(AlterPairQuestion.class).iterator(); - while (questions.hasNext()) { - Question q = study.getQuestion((Long) questions.next()); - if(q.determinesAdjacency()) { - try { - int [][] adj = interview.generateAdjacencyMatrix(q, false); - //int [][] adjWeight = interview.generateAdjacencyMatrix(q, true); - - // loop through adj - // if adj[i][j] == 1, thisInterviewAlters[i] && thisInterviewAlters[j] are adjacent in final matrix - - int alters = Math.min(adj.length,thisInterviewAlterlist.length); - for(int i = 0; i < alters; i++) { - for(int j = i+1; j < alters; j++) { - boolean adjacent = adj[i][j] == 1; - String alter1 = thisInterviewAlterlist[i]; - String alter2 = thisInterviewAlterlist[j]; - logger.debug(alter1 + "("+i+") and " + alter2 + "("+j+") are" + - (adjacent ? " " : " not ")+"adjacent"); - - // find whole network alters - Pair wholeAlter1 = findAlter(interview, i); - Pair wholeAlter2 = findAlter(interview, j); - - if(wholeAlter1 != null && wholeAlter2 != null) { - if(wholeAlter1.getFirst().compareTo(wholeAlter2.getFirst()) > 0) { - Pair swap = wholeAlter1; - wholeAlter1 = wholeAlter2; - wholeAlter2 = swap; - } - - // TODO: strength of tie, even if not adjacent - tie(wholeAlter1, wholeAlter2, - ego == null ? null : ego.getFirst().getId(), - adjacent,false); - } - } - } - } catch (MissingPairException ex) { - logger.error("Couldn't create adjacency matrix for question " + q, ex); - } - } - } - } - - logger.info("# Alters: " + wholeNetworkAlters.size() + ", # Ties: " + wholeNetworkTies.size()); - } - - private Pair findAlter(Interview interview, Integer alterNumber) { - - for(WholeNetworkAlter alter : wholeNetworkAlters.values()) { - for(NameMapping mapping : alter.getOccurences()) { - if(mapping.getInterview().equals(interview) && mapping.getAlterNumber().equals(alterNumber)) - return new Pair(alter,mapping); - } - } - return null; - //throw new IllegalArgumentException("Alter did not exist -- it must have been derived from somewhere, so we *must* find it"); - } - - public Map getWholeNetworkAlters() { - return wholeNetworkAlters; - } - - public Set getWholeNetworkTies() { - Set ties = Sets.newHashSet(); - for(WholeNetworkTie tie : wholeNetworkTies.values()) { - if(tie.isTied(settings.discrepancyStrategy,settings.egoAlwaysTiedToOwnAlters)) { - ties.add(tie); - } - } - return ties; - } - - public WholeNetworkTie getTie(WholeNetworkAlter alter1, WholeNetworkAlter alter2) { - WholeNetworkTie tie1 = - wholeNetworkTies.get(new Pair(alter1,alter2)); - if(tie1 != null) { - return tie1; - } - WholeNetworkTie tie2 = - wholeNetworkTies.get(new Pair(alter2,alter1)); - if(tie2 != null) { - return tie2; - } - return null; - } - - private void tie(Pair wholeAlter1, Pair wholeAlter2, - Integer reporterMappingId, boolean isTied, boolean egoReportingOnSelf) - { - - Pair tieKey = new Pair(wholeAlter1.getFirst(), wholeAlter2.getFirst()); - - if(!wholeNetworkTies.containsKey(tieKey)) { - wholeNetworkTies.put(tieKey, new WholeNetworkTie(tieKey)); - logger.info("Saw new tie for first time: " + tieKey); - } - - WholeNetworkTie tieEntry = wholeNetworkTies.get(tieKey); - if(isTied && egoReportingOnSelf) { - tieEntry.addEvidenceEgoSaysTied(reporterMappingId); - } else { - tieEntry.addEvidence(reporterMappingId, isTied); - } - } - - public Pair getAdjacencyMatrix() { - - List alterList = - new ArrayList(wholeNetworkAlters.values()); - - - int size = alterList.size(); - - String [] names = new String[size]; - for(int i = 0; i < names.length; i++) { - names[i] = alterList.get(i).getId()+""; - } - - int [][] adj = new int[size][size]; - for(int x = 0; x < size; x++) { - for(int y = 0; y < size; y++) { - WholeNetworkAlter wholeAlter1 = alterList.get(x); - WholeNetworkAlter wholeAlter2 = alterList.get(y); - - if(wholeAlter1.compareTo(wholeAlter2) > 0) { - WholeNetworkAlter swap = wholeAlter1; - wholeAlter1 = wholeAlter2; - wholeAlter2 = swap; - } - - Pair tieKey = new Pair(wholeAlter1, wholeAlter2); - if(wholeNetworkTies.containsKey(tieKey)) { - WholeNetworkTie tie = wholeNetworkTies.get(tieKey); - adj[x][y] = - tie.isTied( - settings.discrepancyStrategy, - settings.egoAlwaysTiedToOwnAlters) - ? 1 : 0; - } - else { - adj[x][y] = 0; - } - } - } - - return new Pair(names,adj); - } -} +package org.egonet.wholenet.graph; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.Map.Entry; + +import net.sf.functionalj.Function2; +import net.sf.functionalj.tuple.Pair; + +import org.egonet.exceptions.MissingPairException; +import org.egonet.model.question.AlterPairQuestion; +import org.egonet.model.question.Question; +import org.egonet.wholenet.graph.WholeNetworkTie.DiscrepancyStrategy; +import org.egonet.wholenet.gui.NameMapperFrame.NameMapping; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.endlessloopsoftware.egonet.Interview; +import com.endlessloopsoftware.egonet.Study; +import com.google.common.collect.Sets; + +/** + * This class encapsulates everything necessary to compile and retain data from + * a set of Egonet interviews into a whole network, including alter mappings. + * + * @author Martin + * + */ +public class WholeNetwork { + + final private static Logger logger = LoggerFactory.getLogger(WholeNetwork.class); + + final private Study study; + final private List interviews; + final private List nameMap; + + // maps for fast access + private Map wholeNetworkAlters; + private Map,WholeNetworkTie> wholeNetworkTies; + + private Settings settings; + + public WholeNetwork(Study study, List interviews, + List nameMap, Settings settings, + Function2,Interview,Integer> getAlterAttributes) + { + super(); + this.study = study; + this.interviews = interviews; + this.nameMap = nameMap; + this.settings = settings; + build(getAlterAttributes); + } + + public static class Settings { + public Integer inclusionThreshold = 1; + public Boolean alwaysIncludeEgo = true; + public Boolean egoAlwaysTiedToOwnAlters = true; + public DiscrepancyStrategy discrepancyStrategy = DiscrepancyStrategy.Majority; + } + + public void build(Function2,Interview,Integer> getAlterAttributes) { + wholeNetworkAlters = new HashMap(); + wholeNetworkTies = new HashMap,WholeNetworkTie>(); + + // add all alters + for(NameMapping mapping : nameMap) { + int group = mapping.getGroup(); + if(!wholeNetworkAlters.containsKey(group)) { + wholeNetworkAlters.put(group, new WholeNetworkAlter(group)); + } + + WholeNetworkAlter alter = wholeNetworkAlters.get(group); + alter.addOccurence(mapping); + } + + // remove WholeNetworkAlters that are not mentioned in enough interviews + Map remainingAlters = new HashMap(); + for(Entry entry : wholeNetworkAlters.entrySet()) { + if(entry.getValue().getOccurences().size() < settings.inclusionThreshold) { + if(settings.alwaysIncludeEgo) { + boolean isEgo = false; + for(NameMapping occurrence : entry.getValue().getOccurences()) { + if(occurrence.getAlterNumber().equals(-1)) { + isEgo = true; + } + } + if(isEgo) { + remainingAlters.put(entry.getKey(), entry.getValue()); + } + } + } else { + // Include alter only if mentioned in enough interviews. + remainingAlters.put(entry.getKey(), entry.getValue()); + } + } + wholeNetworkAlters = remainingAlters; + + // Set attributes for remaining alters + for(WholeNetworkAlter wholeNetworkAlter : wholeNetworkAlters.values()) { + for(NameMapping mapping : wholeNetworkAlter.getOccurences()) { + wholeNetworkAlter.addAttributes( + getAlterAttributes.call( + mapping.getInterview(), + mapping.getAlterNumber())); + } + } + + for(Interview interview : interviews) { + + String [] thisInterviewAlterlist = interview.getAlterList(); + + // tie the ego to all alters + Pair ego = findAlter(interview, -1); + if(ego != null) { + for(int i = 0; i < interview.getAlterList().length; i++) { + Pair alter = findAlter(interview, i); + if(alter != null) { + tie(ego, alter, ego.getFirst().getId(), true, true); + } + } + } + + // tie adjacent alters together + Iterator questions = study.getQuestionOrder(AlterPairQuestion.class).iterator(); + while (questions.hasNext()) { + Question q = study.getQuestion((Long) questions.next()); + if(q.determinesAdjacency()) { + try { + int [][] adj = interview.generateAdjacencyMatrix(q, false); + //int [][] adjWeight = interview.generateAdjacencyMatrix(q, true); + + // loop through adj + // if adj[i][j] == 1, thisInterviewAlters[i] && thisInterviewAlters[j] are adjacent in final matrix + + int alters = Math.min(adj.length,thisInterviewAlterlist.length); + for(int i = 0; i < alters; i++) { + for(int j = i+1; j < alters; j++) { + boolean adjacent = adj[i][j] == 1; + String alter1 = thisInterviewAlterlist[i]; + String alter2 = thisInterviewAlterlist[j]; + logger.debug(alter1 + "("+i+") and " + alter2 + "("+j+") are" + + (adjacent ? " " : " not ")+"adjacent"); + + // find whole network alters + Pair wholeAlter1 = findAlter(interview, i); + Pair wholeAlter2 = findAlter(interview, j); + + if(wholeAlter1 != null && wholeAlter2 != null) { + if(wholeAlter1.getFirst().compareTo(wholeAlter2.getFirst()) > 0) { + Pair swap = wholeAlter1; + wholeAlter1 = wholeAlter2; + wholeAlter2 = swap; + } + + // TODO: strength of tie, even if not adjacent + tie(wholeAlter1, wholeAlter2, + ego == null ? null : ego.getFirst().getId(), + adjacent,false); + } + } + } + } catch (MissingPairException ex) { + logger.error("Couldn't create adjacency matrix for question " + q, ex); + } + } + } + } + + logger.info("# Alters: " + wholeNetworkAlters.size() + ", # Ties: " + wholeNetworkTies.size()); + } + + private Pair findAlter(Interview interview, Integer alterNumber) { + + for(WholeNetworkAlter alter : wholeNetworkAlters.values()) { + for(NameMapping mapping : alter.getOccurences()) { + if(mapping.getInterview().equals(interview) && mapping.getAlterNumber().equals(alterNumber)) + return new Pair(alter,mapping); + } + } + return null; + //throw new IllegalArgumentException("Alter did not exist -- it must have been derived from somewhere, so we *must* find it"); + } + + public Map getWholeNetworkAlters() { + return wholeNetworkAlters; + } + + public Set getWholeNetworkTies() { + Set ties = Sets.newHashSet(); + for(WholeNetworkTie tie : wholeNetworkTies.values()) { + if(tie.isTied(settings.discrepancyStrategy,settings.egoAlwaysTiedToOwnAlters)) { + ties.add(tie); + } + } + return ties; + } + + public WholeNetworkTie getTie(WholeNetworkAlter alter1, WholeNetworkAlter alter2) { + WholeNetworkTie tie1 = + wholeNetworkTies.get(new Pair(alter1,alter2)); + if(tie1 != null) { + return tie1; + } + WholeNetworkTie tie2 = + wholeNetworkTies.get(new Pair(alter2,alter1)); + if(tie2 != null) { + return tie2; + } + return null; + } + + private void tie(Pair wholeAlter1, Pair wholeAlter2, + Integer reporterMappingId, boolean isTied, boolean egoReportingOnSelf) + { + + Pair tieKey = new Pair(wholeAlter1.getFirst(), wholeAlter2.getFirst()); + + if(!wholeNetworkTies.containsKey(tieKey)) { + wholeNetworkTies.put(tieKey, new WholeNetworkTie(tieKey)); + logger.info("Saw new tie for first time: " + tieKey); + } + + WholeNetworkTie tieEntry = wholeNetworkTies.get(tieKey); + if(isTied && egoReportingOnSelf) { + tieEntry.addEvidenceEgoSaysTied(reporterMappingId); + } else { + tieEntry.addEvidence(reporterMappingId, isTied); + } + } + + public Pair getAdjacencyMatrix() { + + List alterList = + new ArrayList(wholeNetworkAlters.values()); + + + int size = alterList.size(); + + String [] names = new String[size]; + for(int i = 0; i < names.length; i++) { + names[i] = alterList.get(i).getId()+""; + } + + int [][] adj = new int[size][size]; + for(int x = 0; x < size; x++) { + for(int y = 0; y < size; y++) { + WholeNetworkAlter wholeAlter1 = alterList.get(x); + WholeNetworkAlter wholeAlter2 = alterList.get(y); + + if(wholeAlter1.compareTo(wholeAlter2) > 0) { + WholeNetworkAlter swap = wholeAlter1; + wholeAlter1 = wholeAlter2; + wholeAlter2 = swap; + } + + Pair tieKey = new Pair(wholeAlter1, wholeAlter2); + if(wholeNetworkTies.containsKey(tieKey)) { + WholeNetworkTie tie = wholeNetworkTies.get(tieKey); + adj[x][y] = + tie.isTied( + settings.discrepancyStrategy, + settings.egoAlwaysTiedToOwnAlters) + ? 1 : 0; + } + else { + adj[x][y] = 0; + } + } + } + + return new Pair(names,adj); + } +} diff --git a/src/org/egonet/wholenet/graph/WholeNetworkAlter.java b/src/main/java/org/egonet/wholenet/graph/WholeNetworkAlter.java similarity index 96% rename from src/org/egonet/wholenet/graph/WholeNetworkAlter.java rename to src/main/java/org/egonet/wholenet/graph/WholeNetworkAlter.java index 5e3aa22..17cafff 100644 --- a/src/org/egonet/wholenet/graph/WholeNetworkAlter.java +++ b/src/main/java/org/egonet/wholenet/graph/WholeNetworkAlter.java @@ -1,99 +1,99 @@ -package org.egonet.wholenet.graph; - -import java.util.*; - -import org.egonet.wholenet.gui.NameMapperFrame.NameMapping; - -import com.google.common.collect.HashMultiset; -import com.google.common.collect.Maps; - -public class WholeNetworkAlter implements Comparable { - - private final Integer id; - private final List occurences; - public WholeNetworkAlter(Integer id) { - super(); - this.id = id; - this.occurences = new ArrayList(); - } - - public void addOccurence(NameMapping mapping) { - occurences.add(mapping); - } - - public Integer getId() { - return id; - } - - public List getOccurences() { - return occurences; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((id == null) ? 0 : id.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (!(obj instanceof WholeNetworkAlter)) - return false; - WholeNetworkAlter other = (WholeNetworkAlter) obj; - if (id == null) { - if (other.id != null) - return false; - } else if (!id.equals(other.id)) - return false; - return true; - } - - public int compareTo(WholeNetworkAlter o) { - return id.compareTo(o.id); - } - - public String toString() { - if(occurences.size() <= 0) - return id.toString(); - return occurences.get(0).toString() + " (" + id + ")"; - } - - private Map> rawAttributes = Maps.newTreeMap(); - - public void addAttributes(Map attributes) { - for(String key : attributes.keySet()) { - HashMultiset attribute = rawAttributes.get(key); - if(attribute == null) { - attribute = HashMultiset.create(); - rawAttributes.put(key, attribute); - } - attribute.add(attributes.get(key)); - } - } - - public Map getAttributes() { - Map results = Maps.newTreeMap(); - for(String key : rawAttributes.keySet()) { - String bestValue = ""; - Integer bestCount = 0; - HashMultiset valueCounts = rawAttributes.get(key); - for(String value : valueCounts.elementSet()) { - Integer count = valueCounts.count(value); - if(count > bestCount || - (count.equals(bestCount) && value.length() > bestValue.length())) - { - bestValue = value; - bestCount = count; - } - } - results.put(key, bestValue); - } - return results; - } -} +package org.egonet.wholenet.graph; + +import java.util.*; + +import org.egonet.wholenet.gui.NameMapperFrame.NameMapping; + +import com.google.common.collect.HashMultiset; +import com.google.common.collect.Maps; + +public class WholeNetworkAlter implements Comparable { + + private final Integer id; + private final List occurences; + public WholeNetworkAlter(Integer id) { + super(); + this.id = id; + this.occurences = new ArrayList(); + } + + public void addOccurence(NameMapping mapping) { + occurences.add(mapping); + } + + public Integer getId() { + return id; + } + + public List getOccurences() { + return occurences; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((id == null) ? 0 : id.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (!(obj instanceof WholeNetworkAlter)) + return false; + WholeNetworkAlter other = (WholeNetworkAlter) obj; + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) + return false; + return true; + } + + public int compareTo(WholeNetworkAlter o) { + return id.compareTo(o.id); + } + + public String toString() { + if(occurences.size() <= 0) + return id.toString(); + return occurences.get(0).toString() + " (" + id + ")"; + } + + private Map> rawAttributes = Maps.newTreeMap(); + + public void addAttributes(Map attributes) { + for(String key : attributes.keySet()) { + HashMultiset attribute = rawAttributes.get(key); + if(attribute == null) { + attribute = HashMultiset.create(); + rawAttributes.put(key, attribute); + } + attribute.add(attributes.get(key)); + } + } + + public Map getAttributes() { + Map results = Maps.newTreeMap(); + for(String key : rawAttributes.keySet()) { + String bestValue = ""; + Integer bestCount = 0; + HashMultiset valueCounts = rawAttributes.get(key); + for(String value : valueCounts.elementSet()) { + Integer count = valueCounts.count(value); + if(count > bestCount || + (count.equals(bestCount) && value.length() > bestValue.length())) + { + bestValue = value; + bestCount = count; + } + } + results.put(key, bestValue); + } + return results; + } +} diff --git a/src/org/egonet/wholenet/graph/WholeNetworkTie.java b/src/main/java/org/egonet/wholenet/graph/WholeNetworkTie.java similarity index 96% rename from src/org/egonet/wholenet/graph/WholeNetworkTie.java rename to src/main/java/org/egonet/wholenet/graph/WholeNetworkTie.java index 74620a9..2499813 100644 --- a/src/org/egonet/wholenet/graph/WholeNetworkTie.java +++ b/src/main/java/org/egonet/wholenet/graph/WholeNetworkTie.java @@ -1,128 +1,128 @@ -package org.egonet.wholenet.graph; - -import java.util.HashSet; - -import com.google.common.collect.Sets; - -import net.sf.functionalj.tuple.Pair; - -public class WholeNetworkTie { - - private final WholeNetworkAlter a; - private final WholeNetworkAlter b; - - public WholeNetworkTie(Pair tie) { - this(tie.getFirst(), tie.getSecond()); - } - - public WholeNetworkTie(WholeNetworkAlter a, WholeNetworkAlter b) { - super(); - this.a = a.compareTo(b) < 0 ? a : b; - this.b = a.compareTo(b) < 0 ? b : a; - //SetView view = Sets.intersection(new HashSet(), new HashSet()); - } - - private int tiedYes = 0; - private int tiedNo = 0; - - private HashSet tiedYesSet = Sets.newHashSet(); - private HashSet tiedNoSet = Sets.newHashSet(); - - public HashSet tiedYes() { - return tiedYesSet; - } - public HashSet tiedNo() { - return tiedNoSet; - } - - public void addEvidence(Integer reporterMappingId, boolean isTied) { - if(isTied) { - tiedYes++; - if(reporterMappingId != null) { - tiedYesSet.add(reporterMappingId); - } - } else { - tiedNo++; - if(reporterMappingId != null) { - tiedNoSet.add(reporterMappingId); - } - } - } - - private boolean egoSaysTied = false; - - public void addEvidenceEgoSaysTied(Integer reporterMappingId) { - egoSaysTied = true; - addEvidence(reporterMappingId,true); - } - - public boolean isTied(DiscrepancyStrategy strategy, boolean egoAlwaysTiedToOwn) { - if(egoAlwaysTiedToOwn && egoSaysTied) { - return true; - } else if(strategy.equals(DiscrepancyStrategy.Maximum)) { - return tiedYes > 0; - } else if(strategy.equals(DiscrepancyStrategy.Majority)) { - return tiedYes > tiedNo; - } else if(strategy.equals(DiscrepancyStrategy.Minimum)) { - return tiedYes > 0 && tiedNo < 1; - } else if(strategy.equals(DiscrepancyStrategy.EgoAlterTiesOnly)) { - return egoSaysTied; - } else { - throw new RuntimeException("Unrecognized DiscrepancyStrategy: "+strategy); - } - } - - public static enum DiscrepancyStrategy { - Maximum("tie if any interviews say to tie"), - Majority("tie if more interviews say to tie than not to tie, ego vote overrides"), - Minimum("tie only when an interview says to tie and no interviews say not to tie"), - EgoAlterTiesOnly("ignore alter pair tie question"); - - private final String description; - DiscrepancyStrategy(String description) { - this.description = description; - } - public String getDescription() { - return description; - } - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((a == null) ? 0 : a.hashCode()); - result = prime * result + ((b == null) ? 0 : b.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (!(obj instanceof WholeNetworkTie)) - return false; - WholeNetworkTie other = (WholeNetworkTie) obj; - if (a == null) { - if (other.a != null) - return false; - } else if (!a.equals(other.a)) - return false; - if (b == null) { - if (other.b != null) - return false; - } else if (!b.equals(other.b)) - return false; - return true; - } - - public WholeNetworkAlter getA() { - return a; - } - - public WholeNetworkAlter getB() { - return b; - } -} +package org.egonet.wholenet.graph; + +import java.util.HashSet; + +import com.google.common.collect.Sets; + +import net.sf.functionalj.tuple.Pair; + +public class WholeNetworkTie { + + private final WholeNetworkAlter a; + private final WholeNetworkAlter b; + + public WholeNetworkTie(Pair tie) { + this(tie.getFirst(), tie.getSecond()); + } + + public WholeNetworkTie(WholeNetworkAlter a, WholeNetworkAlter b) { + super(); + this.a = a.compareTo(b) < 0 ? a : b; + this.b = a.compareTo(b) < 0 ? b : a; + //SetView view = Sets.intersection(new HashSet(), new HashSet()); + } + + private int tiedYes = 0; + private int tiedNo = 0; + + private HashSet tiedYesSet = Sets.newHashSet(); + private HashSet tiedNoSet = Sets.newHashSet(); + + public HashSet tiedYes() { + return tiedYesSet; + } + public HashSet tiedNo() { + return tiedNoSet; + } + + public void addEvidence(Integer reporterMappingId, boolean isTied) { + if(isTied) { + tiedYes++; + if(reporterMappingId != null) { + tiedYesSet.add(reporterMappingId); + } + } else { + tiedNo++; + if(reporterMappingId != null) { + tiedNoSet.add(reporterMappingId); + } + } + } + + private boolean egoSaysTied = false; + + public void addEvidenceEgoSaysTied(Integer reporterMappingId) { + egoSaysTied = true; + addEvidence(reporterMappingId,true); + } + + public boolean isTied(DiscrepancyStrategy strategy, boolean egoAlwaysTiedToOwn) { + if(egoAlwaysTiedToOwn && egoSaysTied) { + return true; + } else if(strategy.equals(DiscrepancyStrategy.Maximum)) { + return tiedYes > 0; + } else if(strategy.equals(DiscrepancyStrategy.Majority)) { + return tiedYes > tiedNo; + } else if(strategy.equals(DiscrepancyStrategy.Minimum)) { + return tiedYes > 0 && tiedNo < 1; + } else if(strategy.equals(DiscrepancyStrategy.EgoAlterTiesOnly)) { + return egoSaysTied; + } else { + throw new RuntimeException("Unrecognized DiscrepancyStrategy: "+strategy); + } + } + + public static enum DiscrepancyStrategy { + Maximum("tie if any interviews say to tie"), + Majority("tie if more interviews say to tie than not to tie, ego vote overrides"), + Minimum("tie only when an interview says to tie and no interviews say not to tie"), + EgoAlterTiesOnly("ignore alter pair tie question"); + + private final String description; + DiscrepancyStrategy(String description) { + this.description = description; + } + public String getDescription() { + return description; + } + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((a == null) ? 0 : a.hashCode()); + result = prime * result + ((b == null) ? 0 : b.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (!(obj instanceof WholeNetworkTie)) + return false; + WholeNetworkTie other = (WholeNetworkTie) obj; + if (a == null) { + if (other.a != null) + return false; + } else if (!a.equals(other.a)) + return false; + if (b == null) { + if (other.b != null) + return false; + } else if (!b.equals(other.b)) + return false; + return true; + } + + public WholeNetworkAlter getA() { + return a; + } + + public WholeNetworkAlter getB() { + return b; + } +} diff --git a/src/org/egonet/wholenet/gui/InterviewFileSelectionFrame.java b/src/main/java/org/egonet/wholenet/gui/InterviewFileSelectionFrame.java similarity index 96% rename from src/org/egonet/wholenet/gui/InterviewFileSelectionFrame.java rename to src/main/java/org/egonet/wholenet/gui/InterviewFileSelectionFrame.java index 60eea01..c3970f2 100644 --- a/src/org/egonet/wholenet/gui/InterviewFileSelectionFrame.java +++ b/src/main/java/org/egonet/wholenet/gui/InterviewFileSelectionFrame.java @@ -1,310 +1,310 @@ -package org.egonet.wholenet.gui; - -import java.awt.BorderLayout; -import java.awt.Component; -import java.awt.HeadlessException; -import java.awt.event.ActionEvent; - - -import javax.swing.*; -import java.io.*; -import java.util.*; - -import net.miginfocom.swing.MigLayout; - -import org.egonet.io.InterviewFileFilter; -import org.egonet.io.InterviewReader; -import org.egonet.util.CatchingAction; -import org.egonet.util.SwingWorker; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.endlessloopsoftware.egonet.Interview; -import com.endlessloopsoftware.egonet.Study; - -public class InterviewFileSelectionFrame extends JFrame { - - final private static Logger logger = LoggerFactory.getLogger(InterviewFileSelectionFrame.class); - - private final Study study; - private final File studyFile; - - private JList interviewList; - - final InterviewFileFilter filter; - - public InterviewFileSelectionFrame(final File studyFile, final Study study) throws HeadlessException { - this(studyFile, study, "Select interviews to include in whole network analysis"); - } - - public InterviewFileSelectionFrame(final File studyFile, final Study study, String title) throws HeadlessException { - super(title); - this.studyFile = studyFile; - this.study = study; - - this.filter = new InterviewFileFilter(study, "Interview Files", "int"); - - logger.info("Building interview file selection frame"); - build(); - } - - - private void build() { - BorderLayout layout = new BorderLayout(); - setLayout(layout); - - interviewList = new JList(); - DefaultListCellRenderer cellRenderer = new DefaultListCellRenderer() { - @Override - public Component getListCellRendererComponent(JList list, - Object value, int index, boolean isSelected, - boolean cellHasFocus) { - - if(value instanceof File) { - File fValue = (File)value; - value = fValue.toString().replace(studyFile.getParent().toString(), ""); - } - - return super.getListCellRendererComponent(list, value, index, isSelected, - cellHasFocus); - } - }; - interviewList.setCellRenderer(cellRenderer); - - JScrollPane interviewScroller = new JScrollPane(interviewList); - add(interviewScroller, BorderLayout.CENTER); - - JPanel fileButtonPanel = new JPanel(); - MigLayout vertical = new MigLayout("flowy,fill"); - fileButtonPanel.setLayout(vertical); - - Action addFileAction = new CatchingAction("Add interview file") { - @Override - public void safeActionPerformed(ActionEvent e) throws Exception { - addFileAction(); - } - }; - fileButtonPanel.add(new JButton(addFileAction), "growx, sg 1"); - - Action addDirectoryAction = new CatchingAction("Add directory") { - @Override - public void safeActionPerformed(ActionEvent e) throws Exception { - addDirectoryAction(); - } - }; - fileButtonPanel.add(new JButton(addDirectoryAction), "growx, sg 1"); - - Action removeFileAction = new CatchingAction("Remove selected") { - @Override - public void safeActionPerformed(ActionEvent e) throws Exception { - removeFileAction(); - } - }; - fileButtonPanel.add(new JButton(removeFileAction), "growx, sg 1"); - - add(fileButtonPanel, BorderLayout.WEST); - - List files = getInitialFiles(studyFile.getParentFile()); - interviewList.setModel(new InterviewFileListModel(files)); - - JPanel cancelNextButtonPanel = new JPanel(); - MigLayout horiz = new MigLayout("flowx,fill","center"); - cancelNextButtonPanel.setLayout(horiz); - - Action cancelAction = new CatchingAction("Cancel") { - @Override - public void safeActionPerformed(ActionEvent e) throws Exception { - dispose(); - } - }; - cancelNextButtonPanel.add(new JButton(cancelAction), "growx, sg 2"); - - Action nextAction = new CatchingAction("Continue") { - @Override - public void safeActionPerformed(ActionEvent e) throws Exception { - final InterviewFileListModel model = (InterviewFileListModel)interviewList.getModel(); - - - SwingWorker sw = new SwingWorker() { - - NameMapperFrame frame; - - @Override - public Object construct() { - List mappableFiles = new ArrayList(); - for(Object f : model.toArray()) - mappableFiles.add((File)f); - - frame = new NameMapperFrame(study, studyFile, mappableFiles); - return frame; - } - - @Override - public void finished() { - frame.setVisible(true); - } - - }; - - sw.start(); - dispose(); - } - }; - cancelNextButtonPanel.add(new JButton(nextAction), "growx, sg 2"); - - add(cancelNextButtonPanel, BorderLayout.SOUTH); - - pack(); - } - - protected void removeFileAction() { - int[] selected = interviewList.getSelectedIndices(); - - if(selected.length > 0) { - InterviewFileListModel newModel = new InterviewFileListModel(); - - ListModel model = interviewList.getModel(); - for(int i = 0; i < model.getSize(); i++) { - File item = model.getElementAt(i); - - boolean remove = false; - for(int j = 0; j < selected.length; j++) { - if(selected[j] == i) - remove = true; - } - - if(!remove) - newModel.addElement(item); - } - - interviewList.setModel(newModel); - } - } - - protected void addDirectoryAction() { - JFileChooser jfc = new JFileChooser(); - jfc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); - jfc.setMultiSelectionEnabled(false); - - int c = jfc.showOpenDialog(this); - if(c == JFileChooser.CANCEL_OPTION) - return; - - - InterviewFileListModel model = (InterviewFileListModel)interviewList.getModel(); - - File selected = jfc.getSelectedFile(); - if(selected != null && selected.isDirectory()) { - List results = getInitialFiles(selected); - for(File result : results) { - logger.info("Possible new file " + result.getName()); - - if(!model.contains(result)) - model.addElement(result); - } - } - } - - protected void addFileAction() { - JFileChooser jfc = new JFileChooser(); - jfc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); - jfc.setFileFilter(filter); - jfc.setMultiSelectionEnabled(true); - - int c = jfc.showOpenDialog(this); - if(c == JFileChooser.CANCEL_OPTION) - return; - - - InterviewFileListModel model = (InterviewFileListModel)interviewList.getModel(); - - File [] selected = jfc.getSelectedFiles(); - for(File result : selected) { - if(!model.contains(result)) - model.addElement(result); - } - } - - private boolean validFile(File candidate) { - boolean shouldRead = candidate.isFile() && candidate.canRead() && filter.accept(candidate); - if(!shouldRead) { - // it didn't match for some reason - //logger.info("Couldn't read or wasn't accepted by filter: " + candidate.getName()); - return false; - } - - try { - InterviewReader reader = new InterviewReader(study, candidate); - Interview interview = reader.getInterview(); - - if(!interview.isComplete()) { - //logger.info("Interview wasn't completed: " + candidate.getName()); - return false; - } - - } catch (Exception ex) { - //logger.info("Exception reading: " + candidate.getName()); - return false; - } - - return true; - } - - private List getInitialFiles(File directory) { - - List output = new ArrayList(); - if(!directory.isDirectory()) { - logger.info("Asked to scan a directory for whole network files, but the argument wasn't a directory: " + directory); - return output; - } - - - List files = new ArrayList(); - files.add(directory); - - while(files.size() > 0) { - File candidate = files.remove(0); - if(candidate.isDirectory()) { - for(File subfile : candidate.listFiles()) { - files.add(subfile); - } - - continue; - } - - if(validFile(candidate)) { - output.add(candidate); - logger.info("I'd try to use candidate file " + candidate.getName()); - } - else { - logger.info("I'd skip file " + candidate.getName()); - } - } - - if(output.size() <= 0) - logger.info("No files found for whole network analysis; you may have to add your own"); - - return output; - - } - - public Study getStudy() { - return study; - } - - public File getStudyFile() { - return studyFile; - } - - public class InterviewFileListModel extends DefaultListModel { - public InterviewFileListModel() { - super(); - } - - public InterviewFileListModel(List files) { - super(); - for(File f : files) - addElement(f); - } - } -} +package org.egonet.wholenet.gui; + +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.HeadlessException; +import java.awt.event.ActionEvent; + + +import javax.swing.*; +import java.io.*; +import java.util.*; + +import net.miginfocom.swing.MigLayout; + +import org.egonet.io.InterviewFileFilter; +import org.egonet.io.InterviewReader; +import org.egonet.util.CatchingAction; +import org.egonet.util.SwingWorker; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.endlessloopsoftware.egonet.Interview; +import com.endlessloopsoftware.egonet.Study; + +public class InterviewFileSelectionFrame extends JFrame { + + final private static Logger logger = LoggerFactory.getLogger(InterviewFileSelectionFrame.class); + + private final Study study; + private final File studyFile; + + private JList interviewList; + + final InterviewFileFilter filter; + + public InterviewFileSelectionFrame(final File studyFile, final Study study) throws HeadlessException { + this(studyFile, study, "Select interviews to include in whole network analysis"); + } + + public InterviewFileSelectionFrame(final File studyFile, final Study study, String title) throws HeadlessException { + super(title); + this.studyFile = studyFile; + this.study = study; + + this.filter = new InterviewFileFilter(study, "Interview Files", "int"); + + logger.info("Building interview file selection frame"); + build(); + } + + + private void build() { + BorderLayout layout = new BorderLayout(); + setLayout(layout); + + interviewList = new JList(); + DefaultListCellRenderer cellRenderer = new DefaultListCellRenderer() { + @Override + public Component getListCellRendererComponent(JList list, + Object value, int index, boolean isSelected, + boolean cellHasFocus) { + + if(value instanceof File) { + File fValue = (File)value; + value = fValue.toString().replace(studyFile.getParent().toString(), ""); + } + + return super.getListCellRendererComponent(list, value, index, isSelected, + cellHasFocus); + } + }; + interviewList.setCellRenderer(cellRenderer); + + JScrollPane interviewScroller = new JScrollPane(interviewList); + add(interviewScroller, BorderLayout.CENTER); + + JPanel fileButtonPanel = new JPanel(); + MigLayout vertical = new MigLayout("flowy,fill"); + fileButtonPanel.setLayout(vertical); + + Action addFileAction = new CatchingAction("Add interview file") { + @Override + public void safeActionPerformed(ActionEvent e) throws Exception { + addFileAction(); + } + }; + fileButtonPanel.add(new JButton(addFileAction), "growx, sg 1"); + + Action addDirectoryAction = new CatchingAction("Add directory") { + @Override + public void safeActionPerformed(ActionEvent e) throws Exception { + addDirectoryAction(); + } + }; + fileButtonPanel.add(new JButton(addDirectoryAction), "growx, sg 1"); + + Action removeFileAction = new CatchingAction("Remove selected") { + @Override + public void safeActionPerformed(ActionEvent e) throws Exception { + removeFileAction(); + } + }; + fileButtonPanel.add(new JButton(removeFileAction), "growx, sg 1"); + + add(fileButtonPanel, BorderLayout.WEST); + + List files = getInitialFiles(studyFile.getParentFile()); + interviewList.setModel(new InterviewFileListModel(files)); + + JPanel cancelNextButtonPanel = new JPanel(); + MigLayout horiz = new MigLayout("flowx,fill","center"); + cancelNextButtonPanel.setLayout(horiz); + + Action cancelAction = new CatchingAction("Cancel") { + @Override + public void safeActionPerformed(ActionEvent e) throws Exception { + dispose(); + } + }; + cancelNextButtonPanel.add(new JButton(cancelAction), "growx, sg 2"); + + Action nextAction = new CatchingAction("Continue") { + @Override + public void safeActionPerformed(ActionEvent e) throws Exception { + final InterviewFileListModel model = (InterviewFileListModel)interviewList.getModel(); + + + SwingWorker sw = new SwingWorker() { + + NameMapperFrame frame; + + @Override + public Object construct() { + List mappableFiles = new ArrayList(); + for(Object f : model.toArray()) + mappableFiles.add((File)f); + + frame = new NameMapperFrame(study, studyFile, mappableFiles); + return frame; + } + + @Override + public void finished() { + frame.setVisible(true); + } + + }; + + sw.start(); + dispose(); + } + }; + cancelNextButtonPanel.add(new JButton(nextAction), "growx, sg 2"); + + add(cancelNextButtonPanel, BorderLayout.SOUTH); + + pack(); + } + + protected void removeFileAction() { + int[] selected = interviewList.getSelectedIndices(); + + if(selected.length > 0) { + InterviewFileListModel newModel = new InterviewFileListModel(); + + ListModel model = interviewList.getModel(); + for(int i = 0; i < model.getSize(); i++) { + File item = model.getElementAt(i); + + boolean remove = false; + for(int j = 0; j < selected.length; j++) { + if(selected[j] == i) + remove = true; + } + + if(!remove) + newModel.addElement(item); + } + + interviewList.setModel(newModel); + } + } + + protected void addDirectoryAction() { + JFileChooser jfc = new JFileChooser(); + jfc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + jfc.setMultiSelectionEnabled(false); + + int c = jfc.showOpenDialog(this); + if(c == JFileChooser.CANCEL_OPTION) + return; + + + InterviewFileListModel model = (InterviewFileListModel)interviewList.getModel(); + + File selected = jfc.getSelectedFile(); + if(selected != null && selected.isDirectory()) { + List results = getInitialFiles(selected); + for(File result : results) { + logger.info("Possible new file " + result.getName()); + + if(!model.contains(result)) + model.addElement(result); + } + } + } + + protected void addFileAction() { + JFileChooser jfc = new JFileChooser(); + jfc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); + jfc.setFileFilter(filter); + jfc.setMultiSelectionEnabled(true); + + int c = jfc.showOpenDialog(this); + if(c == JFileChooser.CANCEL_OPTION) + return; + + + InterviewFileListModel model = (InterviewFileListModel)interviewList.getModel(); + + File [] selected = jfc.getSelectedFiles(); + for(File result : selected) { + if(!model.contains(result)) + model.addElement(result); + } + } + + private boolean validFile(File candidate) { + boolean shouldRead = candidate.isFile() && candidate.canRead() && filter.accept(candidate); + if(!shouldRead) { + // it didn't match for some reason + //logger.info("Couldn't read or wasn't accepted by filter: " + candidate.getName()); + return false; + } + + try { + InterviewReader reader = new InterviewReader(study, candidate); + Interview interview = reader.getInterview(); + + if(!interview.isComplete()) { + //logger.info("Interview wasn't completed: " + candidate.getName()); + return false; + } + + } catch (Exception ex) { + //logger.info("Exception reading: " + candidate.getName()); + return false; + } + + return true; + } + + private List getInitialFiles(File directory) { + + List output = new ArrayList(); + if(!directory.isDirectory()) { + logger.info("Asked to scan a directory for whole network files, but the argument wasn't a directory: " + directory); + return output; + } + + + List files = new ArrayList(); + files.add(directory); + + while(files.size() > 0) { + File candidate = files.remove(0); + if(candidate.isDirectory()) { + for(File subfile : candidate.listFiles()) { + files.add(subfile); + } + + continue; + } + + if(validFile(candidate)) { + output.add(candidate); + logger.info("I'd try to use candidate file " + candidate.getName()); + } + else { + logger.info("I'd skip file " + candidate.getName()); + } + } + + if(output.size() <= 0) + logger.info("No files found for whole network analysis; you may have to add your own"); + + return output; + + } + + public Study getStudy() { + return study; + } + + public File getStudyFile() { + return studyFile; + } + + public class InterviewFileListModel extends DefaultListModel { + public InterviewFileListModel() { + super(); + } + + public InterviewFileListModel(List files) { + super(); + for(File f : files) + addElement(f); + } + } +} diff --git a/src/org/egonet/wholenet/gui/NameMapperFrame.java b/src/main/java/org/egonet/wholenet/gui/NameMapperFrame.java similarity index 96% rename from src/org/egonet/wholenet/gui/NameMapperFrame.java rename to src/main/java/org/egonet/wholenet/gui/NameMapperFrame.java index 6192e17..bd1345a 100644 --- a/src/org/egonet/wholenet/gui/NameMapperFrame.java +++ b/src/main/java/org/egonet/wholenet/gui/NameMapperFrame.java @@ -1,633 +1,633 @@ -package org.egonet.wholenet.gui; - -import java.awt.Component; -import java.awt.Cursor; -import java.awt.event.ActionEvent; -import java.io.File; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeMap; -import java.util.TreeSet; - -import javax.swing.*; -import javax.swing.table.AbstractTableModel; -import javax.swing.table.DefaultTableCellRenderer; -import javax.swing.table.TableCellRenderer; - -import org.egonet.io.InterviewReader; -import org.egonet.model.question.AlterQuestion; -import org.egonet.model.question.Question; -import org.egonet.util.CatchingAction; -import org.egonet.util.ExtensionFileFilter; -import org.egonet.util.Name; -import org.egonet.util.SwingWorker; -import org.egonet.wholenet.graph.WholeNetwork; -import org.egonet.wholenet.graph.WholeNetwork.Settings; -import org.egonet.wholenet.graph.WholeNetworkTie.DiscrepancyStrategy; -import org.egonet.wholenet.io.NameMappingReader; -import org.egonet.wholenet.io.NameMappingWriter; -import org.jdesktop.swingx.JXTable; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import uk.ac.shef.wit.simmetrics.similaritymetrics.AbstractStringMetric; -import uk.ac.shef.wit.simmetrics.similaritymetrics.Levenshtein; -import net.miginfocom.swing.MigLayout; -import net.sf.functionalj.Function2; -import net.sf.functionalj.Function2Impl; -import net.sf.functionalj.Functions; -import net.sf.functionalj.tuple.Pair; -import net.sf.functionalj.tuple.Triple; - -import com.endlessloopsoftware.egonet.Answer; -import com.endlessloopsoftware.egonet.Interview; -import com.endlessloopsoftware.egonet.Study; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; - -public class NameMapperFrame extends JFrame { - - final private static Logger logger = LoggerFactory.getLogger(NameMapperFrame.class); - - private final Study study; - private final File studyFile; - - private final List> interviewMap; - - private MapperTableModel tableModel; - - public NameMapperFrame(Study study, File studyFile, List mappableFiles) { - super("Whole Network - Alter Name Mapping Editor"); - this.study = study; - this.studyFile = studyFile; - this.interviewMap = new ArrayList>(mappableFiles.size()); - this.study.toString(); - - for(File intFile : mappableFiles) { - try { - InterviewReader ir = new InterviewReader(study, intFile); - Interview intV = ir.getInterview(); - Pair p = new Pair(intFile, intV); - interviewMap.add(p); - } - catch (Exception ex ) { - logger.info("Couldn't map " + intFile.getName()); - logger.error(ex.toString()); - } - } - - build(); - } - - /** - * This class is a data member which will keep track of exactly what should - * mapping happen for every alter in every interview. It may point to - * another alter that should be treated as the same thing, or it may be set - * to never map to anything. - */ - public class NameMapping implements Comparable { - final Study study; - final Interview interview; - final Integer alterNumber; - final String alterName; - - private Integer group; - - public NameMapping(Study study, Interview interview, Integer alterNumber, Integer group) { - super(); - this.interview = interview; - this.study = study; - this.alterNumber = alterNumber; - this.alterName = interview.getAlterList()[alterNumber]; - this.group = group; - } - - // ego constructor - public NameMapping(Study study, Interview interview, String iName, Integer group) { - super(); - this.interview = interview; - this.study = study; - this.alterNumber = -1; - this.alterName = new Name(iName).toString(); - this.group = group; - } - - public Integer getGroup() { - return group; - } - - public void setGroup(Integer group) { - this.group = group; - } - - public Study getStudy() { - return study; - } - - public Interview getInterview() { - return interview; - } - - public Integer getAlterNumber() { - return alterNumber; - } - - public String toString() { - return alterName; - } - - public int compareTo(NameMapping o) { - return alterNumber.compareTo(o.alterNumber); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + getOuterType().hashCode(); - result = prime * result - + ((alterNumber == null) ? 0 : alterNumber.hashCode()); - result = prime * result - + ((interview == null) ? 0 : interview.hashCode()); - result = prime * result + ((study == null) ? 0 : study.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (!(obj instanceof NameMapping)) - return false; - NameMapping other = (NameMapping) obj; - if (!getOuterType().equals(other.getOuterType())) - return false; - if (alterNumber == null) { - if (other.alterNumber != null) - return false; - } else if (!alterNumber.equals(other.alterNumber)) - return false; - if (interview == null) { - if (other.interview != null) - return false; - } else if (!interview.equals(other.interview)) - return false; - if (study == null) { - if (other.study != null) - return false; - } else if (!study.equals(other.study)) - return false; - return true; - } - - private NameMapperFrame getOuterType() { - return NameMapperFrame.this; - } - } - - public class MapperTableModel extends AbstractTableModel { - - public final String [] columns = {"Alter", "Ego", "Mapping Group"}; - private final List mappings; - - private final List alterQuestions; - private final Set alterQuestionIds; - private final Map,Answer> questionInterviewAlterToAnswer; - - public Map - attributesForInterviewAndAlterId(Interview interview,Integer alterId) { - Map attributes = Maps.newTreeMap(); - String interviewName = interview.toString(); - for(Question question : alterQuestions) { - Answer answer = - questionInterviewAlterToAnswer.get( - new Triple( - question.UniqueId,interviewName,alterId)); - attributes.put(question.title, showAnswer(answer)); - } - return attributes; - } - - public MapperTableModel() { - mappings = new ArrayList(); - alterQuestions = new ArrayList(); - alterQuestionIds = new TreeSet(); - questionInterviewAlterToAnswer = new TreeMap,Answer>(); - - for(Question question : study.getQuestions().values()) { - if(question instanceof AlterQuestion) { - alterQuestions.add(question); - alterQuestionIds.add(question.UniqueId); - } - } - - int group = 1; - - for(Pair entry : interviewMap) { - Interview interview = entry.getSecond(); - - NameMapping egoMapping = new NameMapping(study, interview, entry.getFirst().getName(), group++); - mappings.add(egoMapping); - - String [] alterList = interview.getAlterList(); - for(int i = 0; i < alterList.length; i++) { - NameMapping mapping = new NameMapping(study, interview, i, group++); - mappings.add(mapping); - - } - for(Answer answer : interview.get_answers()) { - if(alterQuestionIds.contains(answer.questionId)) { - questionInterviewAlterToAnswer.put( - new Triple( - answer.questionId, - interview.toString(), - answer.firstAlter()), - answer); - } - } - } - } - - public int getColumnCount() { - return columns.length + alterQuestions.size(); - } - - public String getColumnName(int column) { - return column < columns.length ? columns[column] : - questionForColumn(column).title; - } - - private Question questionForColumn(int column) { - return alterQuestions.get(column - columns.length); - } - - public int getRowCount() { - return mappings.size(); - } - - public Object getValueAt(int rowIndex, int columnIndex) { - NameMapping row = mappings.get(rowIndex); - if(columnIndex == 0) { - return row.alterName; - } else if(columnIndex == 1) { - String egoName = row.getInterview().getIntName(); - return new Name(egoName).toString(); - } else if(columnIndex == 2) { - return row.group; - } - else { // Answer to alter question - Question question = questionForColumn(columnIndex); - Triple key = - new Triple( - question.UniqueId, - row.getInterview().toString(), - row.alterNumber); - return showAnswer(questionInterviewAlterToAnswer.get(key)); - } - } - - private String showAnswer(Answer answer) { - String result = answer+""; - return result.equals("-1") || result.equals("null") ? "" : result; - } - - @Override - public boolean isCellEditable(int rowIndex, int columnIndex) { - if(columnIndex == 2) - return true; - return false; - } - - @Override - public void setValueAt(Object aValue, int rowIndex, int columnIndex) { - if(columnIndex == 2 && aValue instanceof String) { - - Integer i = null; - try { - i = Integer.parseInt(aValue.toString()); - } - catch(NumberFormatException ex) { - return; - } - - NameMapping row = mappings.get(rowIndex); - row.setGroup(i); - } - } - - public List getMappings() { - return mappings; - } - - } - - class MappingRenderer implements ListCellRenderer, TableCellRenderer, Serializable { - - private final DefaultTableCellRenderer tableDelegate = new DefaultTableCellRenderer(); - private final DefaultListCellRenderer listDelegate = new DefaultListCellRenderer(); - - public Component getTableCellRendererComponent(JTable table, Object value, - boolean isSelected, boolean hasFocus, int row, int column) { - - if(value instanceof NameMapping) { - value = convert((NameMapping)value); - } - - return tableDelegate.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); - } - - public Component getListCellRendererComponent(JList list, Object value, - int index, boolean isSelected, boolean cellHasFocus) { - - if(value instanceof NameMapping) { - value = convert((NameMapping)value); - } - - return listDelegate.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); - } - - private String convert(NameMapping mapping) { - Interview intv = mapping.interview; - String ego = new Name(intv.getIntName()).toString(); - String alter = mapping.alterName; - - return alter + " (" + ego + ")"; - } - } - - private Settings settings = new Settings(); - - private void editSettings(final Settings settings) { - JPanel panel = new JPanel(new MigLayout()); - - panel.add(new JLabel("In how many interviews must an alter be mentioned"),"span,grow"); - panel.add(new JLabel("in order to be included in the whole network?"),"span,grow"); - final JTextField inclusionField = new JTextField(5); - inclusionField.setText(settings.inclusionThreshold+""); - panel.add(inclusionField,"wrap"); - - panel.add(new JSeparator(),"span,grow"); - - final JCheckBox egoAlwaysIncludedField = - new JCheckBox( - "Always include ego (otherwise ego not mentioned often " + - "enough is filtered as above)", - settings.alwaysIncludeEgo); - panel.add(egoAlwaysIncludedField,"span,grow"); - - panel.add(new JSeparator(),"span,grow"); - - panel.add(new JLabel("Alter tie discrepancies"),"wrap"); - final ButtonGroup group = new ButtonGroup(); - for(DiscrepancyStrategy strategy : DiscrepancyStrategy.values()) { - JRadioButton button = new JRadioButton(strategy.name()+" - "+strategy.getDescription()); - button.setActionCommand(strategy.name()); - group.add(button); - panel.add(button,"span,grow"); - if(settings.discrepancyStrategy.equals(strategy)) { - button.setSelected(true); - } - } - final JCheckBox egoOverrideField = - new JCheckBox( - "Ego always connected to own alters " + - "(even if all other respondents disagree)", - settings.egoAlwaysTiedToOwnAlters); - panel.add(egoOverrideField,"span,grow"); - - panel.add(new JSeparator(),"span,grow"); - - final JFrame frame = new JFrame("Whole Network Analysis"); - - panel.add(new JButton(new CatchingAction("Save") { - public void safeActionPerformed(ActionEvent e) throws Exception { - try { - settings.inclusionThreshold = Integer.parseInt(inclusionField.getText()); - } catch(Exception ex) { - - } - settings.alwaysIncludeEgo = egoAlwaysIncludedField.isSelected(); - settings.discrepancyStrategy = - DiscrepancyStrategy.valueOf(group.getSelection().getActionCommand()); - settings.egoAlwaysTiedToOwnAlters = egoOverrideField.isSelected(); - frame.dispose(); - } - })); - - frame.setContentPane(panel); - frame.pack(); - frame.setVisible(true); - } - - private void build() { - tableModel = new MapperTableModel(); - final JXTable table = new JXTable(tableModel); - table.setSortable(true); - table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); - - // column 0 - source ego/alter - table.getColumnModel().getColumn(0).setCellRenderer(new MappingRenderer()); - - // column 1 - mapping group - ; // no changes - - MigLayout layout = new MigLayout("fill", "[grow]"); - setLayout(layout); - - JScrollPane scrollPane = - new JScrollPane(table, - ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, - ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS); - add(new JLabel("Please perform alter/ego name mappings"), "growx, wrap"); - add(scrollPane, "grow, span, wrap"); - - Action cancelAction = new CatchingAction("Cancel") { - @Override - public void safeActionPerformed(ActionEvent e) throws Exception { - dispose(); - } - }; - JButton cancelButton = new JButton(cancelAction); - add(cancelButton, "split, growx"); - - Action automatchAction = new CatchingAction("Automatch") { - @Override - public void safeActionPerformed(ActionEvent e) throws Exception { - setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); // Hourglass cursor - try { - doDefaultSimilarity(tableModel, 0.8f); - table.repaint(); - } finally { - setCursor(Cursor.getDefaultCursor()); // Finished - back to normal cursor - } - } - }; - JButton automatchButton = new JButton(automatchAction); - add(automatchButton, "split, growx"); - - add( - new JButton(new CatchingAction("Save") { - public void safeActionPerformed(ActionEvent e) - throws Exception { - File studyFile = NameMapperFrame.this.studyFile; - File suggestedOutputFile = - new File( - studyFile.getParent(), - NameMapperFrame.this.study.getStudyName()+".mapping"); - JFileChooser fc = new JFileChooser(suggestedOutputFile); - fc.setSelectedFile(suggestedOutputFile); - fc.addChoosableFileFilter(new ExtensionFileFilter("Name Mapping Files","mapping")); - fc.setDialogTitle("Save name mappings"); - if(fc.showSaveDialog(NameMapperFrame.this) == - JFileChooser.APPROVE_OPTION) - { - new NameMappingWriter(tableModel.getMappings()) - .writeToFile(fc.getSelectedFile()); - } - } - }), - "split, growx"); - add( - new JButton(new CatchingAction("Load") { - public void safeActionPerformed(ActionEvent e) - throws Exception { - File studyFile = NameMapperFrame.this.studyFile; - File suggestedOutputFile = - new File(studyFile.getParent()); - JFileChooser fc = new JFileChooser(suggestedOutputFile); - fc.setSelectedFile(suggestedOutputFile); - fc.addChoosableFileFilter(new ExtensionFileFilter("Name Mapping Files","mapping")); - fc.setDialogTitle("Load name mappings from file"); - if(fc.showOpenDialog(NameMapperFrame.this) == - JFileChooser.APPROVE_OPTION) - { - new NameMappingReader(fc.getSelectedFile()) - .applyTo(tableModel.getMappings()); - } - } - }), - "split, growx"); - add(new JButton( - new CatchingAction("Settings") { - @Override - public void safeActionPerformed(ActionEvent e) throws Exception { - editSettings(settings); - } - }), - "split, growx"); - - Action continueAction = new CatchingAction("Continue") { - @Override - public void safeActionPerformed(ActionEvent e) throws Exception { - - SwingWorker sw = new SwingWorker() { - - WholeNetworkViewer viewer; - - @Override - public Object construct() { - - List mappings = tableModel.getMappings(); - - List interviews = Lists.newArrayList( - Functions.map(new Pair().second, interviewMap)); - - Function2,Interview,Integer> getAlterAttributes = new Function2Impl,Interview,Integer>(){ - public Map call( - Interview interview, Integer alterId) { - return tableModel.attributesForInterviewAndAlterId(interview, alterId); - } - }; - - // do the whole network combination, and export/show it! - WholeNetwork net = - new WholeNetwork(study, interviews, mappings, settings, getAlterAttributes); - - viewer = new WholeNetworkViewer(study, studyFile, net); - return viewer; - } - - public void finished() { - viewer.setVisible(true); - } - - }; - - sw.start(); - dispose(); - - } - }; - JButton continueButton = new JButton(continueAction); - add(continueButton, "growx"); - - - - pack(); - } - - private void doDefaultSimilarity(MapperTableModel model, float cutoff) { - AbstractStringMetric metric = new Levenshtein(); - - Map> groupings = new HashMap>(); - int groupCounter = 1; - - ArrayList names = new ArrayList(model.getMappings()); - while(names.size() > 0) { - NameMapping current = names.remove(0); - - if(current == null || current.alterName == null) - continue; - - float highest = 0.0f; Integer highestGroup = null; - for(Map.Entry> entry : groupings.entrySet()) { - float averageScore = 0; int elementCount = 0; - for(NameMapping entryMapping : entry.getValue()) { - - if(entryMapping.alterName == null) - continue; - - // when figuring a true score, make everything lowercase and trimmed - float thisScore = metric.getSimilarity(current.alterName.toLowerCase().trim(), entryMapping.alterName.toLowerCase().trim()); - if(thisScore >= cutoff) - logger.info(current.alterName + " + " + entryMapping.alterName + " = " + thisScore); - - averageScore += thisScore; - elementCount++; - } - averageScore /= elementCount; - if(averageScore >= cutoff && averageScore > highest) { - highest = averageScore; - highestGroup = entry.getKey(); - } - } - - // pick an existing group - if(highestGroup != null) { - List destGroup = groupings.get(highestGroup); - destGroup.add(current); - } - // create a new group - else { - List destGroup = new ArrayList(); - destGroup.add(current); - groupings.put(groupCounter++, destGroup); - } - } - - for(NameMapping map : model.getMappings()) { - for(Integer group : groupings.keySet()) { - if(groupings.get(group).contains(map)) { - map.setGroup(group); - break; - } - } - } - } -} +package org.egonet.wholenet.gui; + +import java.awt.Component; +import java.awt.Cursor; +import java.awt.event.ActionEvent; +import java.io.File; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import java.util.TreeSet; + +import javax.swing.*; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.DefaultTableCellRenderer; +import javax.swing.table.TableCellRenderer; + +import org.egonet.io.InterviewReader; +import org.egonet.model.question.AlterQuestion; +import org.egonet.model.question.Question; +import org.egonet.util.CatchingAction; +import org.egonet.util.ExtensionFileFilter; +import org.egonet.util.Name; +import org.egonet.util.SwingWorker; +import org.egonet.wholenet.graph.WholeNetwork; +import org.egonet.wholenet.graph.WholeNetwork.Settings; +import org.egonet.wholenet.graph.WholeNetworkTie.DiscrepancyStrategy; +import org.egonet.wholenet.io.NameMappingReader; +import org.egonet.wholenet.io.NameMappingWriter; +import org.jdesktop.swingx.JXTable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import uk.ac.shef.wit.simmetrics.similaritymetrics.AbstractStringMetric; +import uk.ac.shef.wit.simmetrics.similaritymetrics.Levenshtein; +import net.miginfocom.swing.MigLayout; +import net.sf.functionalj.Function2; +import net.sf.functionalj.Function2Impl; +import net.sf.functionalj.Functions; +import net.sf.functionalj.tuple.Pair; +import net.sf.functionalj.tuple.Triple; + +import com.endlessloopsoftware.egonet.Answer; +import com.endlessloopsoftware.egonet.Interview; +import com.endlessloopsoftware.egonet.Study; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; + +public class NameMapperFrame extends JFrame { + + final private static Logger logger = LoggerFactory.getLogger(NameMapperFrame.class); + + private final Study study; + private final File studyFile; + + private final List> interviewMap; + + private MapperTableModel tableModel; + + public NameMapperFrame(Study study, File studyFile, List mappableFiles) { + super("Whole Network - Alter Name Mapping Editor"); + this.study = study; + this.studyFile = studyFile; + this.interviewMap = new ArrayList>(mappableFiles.size()); + this.study.toString(); + + for(File intFile : mappableFiles) { + try { + InterviewReader ir = new InterviewReader(study, intFile); + Interview intV = ir.getInterview(); + Pair p = new Pair(intFile, intV); + interviewMap.add(p); + } + catch (Exception ex ) { + logger.info("Couldn't map " + intFile.getName()); + logger.error(ex.toString()); + } + } + + build(); + } + + /** + * This class is a data member which will keep track of exactly what should + * mapping happen for every alter in every interview. It may point to + * another alter that should be treated as the same thing, or it may be set + * to never map to anything. + */ + public class NameMapping implements Comparable { + final Study study; + final Interview interview; + final Integer alterNumber; + final String alterName; + + private Integer group; + + public NameMapping(Study study, Interview interview, Integer alterNumber, Integer group) { + super(); + this.interview = interview; + this.study = study; + this.alterNumber = alterNumber; + this.alterName = interview.getAlterList()[alterNumber]; + this.group = group; + } + + // ego constructor + public NameMapping(Study study, Interview interview, String iName, Integer group) { + super(); + this.interview = interview; + this.study = study; + this.alterNumber = -1; + this.alterName = new Name(iName).toString(); + this.group = group; + } + + public Integer getGroup() { + return group; + } + + public void setGroup(Integer group) { + this.group = group; + } + + public Study getStudy() { + return study; + } + + public Interview getInterview() { + return interview; + } + + public Integer getAlterNumber() { + return alterNumber; + } + + public String toString() { + return alterName; + } + + public int compareTo(NameMapping o) { + return alterNumber.compareTo(o.alterNumber); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + getOuterType().hashCode(); + result = prime * result + + ((alterNumber == null) ? 0 : alterNumber.hashCode()); + result = prime * result + + ((interview == null) ? 0 : interview.hashCode()); + result = prime * result + ((study == null) ? 0 : study.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (!(obj instanceof NameMapping)) + return false; + NameMapping other = (NameMapping) obj; + if (!getOuterType().equals(other.getOuterType())) + return false; + if (alterNumber == null) { + if (other.alterNumber != null) + return false; + } else if (!alterNumber.equals(other.alterNumber)) + return false; + if (interview == null) { + if (other.interview != null) + return false; + } else if (!interview.equals(other.interview)) + return false; + if (study == null) { + if (other.study != null) + return false; + } else if (!study.equals(other.study)) + return false; + return true; + } + + private NameMapperFrame getOuterType() { + return NameMapperFrame.this; + } + } + + public class MapperTableModel extends AbstractTableModel { + + public final String [] columns = {"Alter", "Ego", "Mapping Group"}; + private final List mappings; + + private final List alterQuestions; + private final Set alterQuestionIds; + private final Map,Answer> questionInterviewAlterToAnswer; + + public Map + attributesForInterviewAndAlterId(Interview interview,Integer alterId) { + Map attributes = Maps.newTreeMap(); + String interviewName = interview.toString(); + for(Question question : alterQuestions) { + Answer answer = + questionInterviewAlterToAnswer.get( + new Triple( + question.UniqueId,interviewName,alterId)); + attributes.put(question.title, showAnswer(answer)); + } + return attributes; + } + + public MapperTableModel() { + mappings = new ArrayList(); + alterQuestions = new ArrayList(); + alterQuestionIds = new TreeSet(); + questionInterviewAlterToAnswer = new TreeMap,Answer>(); + + for(Question question : study.getQuestions().values()) { + if(question instanceof AlterQuestion) { + alterQuestions.add(question); + alterQuestionIds.add(question.UniqueId); + } + } + + int group = 1; + + for(Pair entry : interviewMap) { + Interview interview = entry.getSecond(); + + NameMapping egoMapping = new NameMapping(study, interview, entry.getFirst().getName(), group++); + mappings.add(egoMapping); + + String [] alterList = interview.getAlterList(); + for(int i = 0; i < alterList.length; i++) { + NameMapping mapping = new NameMapping(study, interview, i, group++); + mappings.add(mapping); + + } + for(Answer answer : interview.get_answers()) { + if(alterQuestionIds.contains(answer.questionId)) { + questionInterviewAlterToAnswer.put( + new Triple( + answer.questionId, + interview.toString(), + answer.firstAlter()), + answer); + } + } + } + } + + public int getColumnCount() { + return columns.length + alterQuestions.size(); + } + + public String getColumnName(int column) { + return column < columns.length ? columns[column] : + questionForColumn(column).title; + } + + private Question questionForColumn(int column) { + return alterQuestions.get(column - columns.length); + } + + public int getRowCount() { + return mappings.size(); + } + + public Object getValueAt(int rowIndex, int columnIndex) { + NameMapping row = mappings.get(rowIndex); + if(columnIndex == 0) { + return row.alterName; + } else if(columnIndex == 1) { + String egoName = row.getInterview().getIntName(); + return new Name(egoName).toString(); + } else if(columnIndex == 2) { + return row.group; + } + else { // Answer to alter question + Question question = questionForColumn(columnIndex); + Triple key = + new Triple( + question.UniqueId, + row.getInterview().toString(), + row.alterNumber); + return showAnswer(questionInterviewAlterToAnswer.get(key)); + } + } + + private String showAnswer(Answer answer) { + String result = answer+""; + return result.equals("-1") || result.equals("null") ? "" : result; + } + + @Override + public boolean isCellEditable(int rowIndex, int columnIndex) { + if(columnIndex == 2) + return true; + return false; + } + + @Override + public void setValueAt(Object aValue, int rowIndex, int columnIndex) { + if(columnIndex == 2 && aValue instanceof String) { + + Integer i = null; + try { + i = Integer.parseInt(aValue.toString()); + } + catch(NumberFormatException ex) { + return; + } + + NameMapping row = mappings.get(rowIndex); + row.setGroup(i); + } + } + + public List getMappings() { + return mappings; + } + + } + + class MappingRenderer implements ListCellRenderer, TableCellRenderer, Serializable { + + private final DefaultTableCellRenderer tableDelegate = new DefaultTableCellRenderer(); + private final DefaultListCellRenderer listDelegate = new DefaultListCellRenderer(); + + public Component getTableCellRendererComponent(JTable table, Object value, + boolean isSelected, boolean hasFocus, int row, int column) { + + if(value instanceof NameMapping) { + value = convert((NameMapping)value); + } + + return tableDelegate.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + } + + public Component getListCellRendererComponent(JList list, Object value, + int index, boolean isSelected, boolean cellHasFocus) { + + if(value instanceof NameMapping) { + value = convert((NameMapping)value); + } + + return listDelegate.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + } + + private String convert(NameMapping mapping) { + Interview intv = mapping.interview; + String ego = new Name(intv.getIntName()).toString(); + String alter = mapping.alterName; + + return alter + " (" + ego + ")"; + } + } + + private Settings settings = new Settings(); + + private void editSettings(final Settings settings) { + JPanel panel = new JPanel(new MigLayout()); + + panel.add(new JLabel("In how many interviews must an alter be mentioned"),"span,grow"); + panel.add(new JLabel("in order to be included in the whole network?"),"span,grow"); + final JTextField inclusionField = new JTextField(5); + inclusionField.setText(settings.inclusionThreshold+""); + panel.add(inclusionField,"wrap"); + + panel.add(new JSeparator(),"span,grow"); + + final JCheckBox egoAlwaysIncludedField = + new JCheckBox( + "Always include ego (otherwise ego not mentioned often " + + "enough is filtered as above)", + settings.alwaysIncludeEgo); + panel.add(egoAlwaysIncludedField,"span,grow"); + + panel.add(new JSeparator(),"span,grow"); + + panel.add(new JLabel("Alter tie discrepancies"),"wrap"); + final ButtonGroup group = new ButtonGroup(); + for(DiscrepancyStrategy strategy : DiscrepancyStrategy.values()) { + JRadioButton button = new JRadioButton(strategy.name()+" - "+strategy.getDescription()); + button.setActionCommand(strategy.name()); + group.add(button); + panel.add(button,"span,grow"); + if(settings.discrepancyStrategy.equals(strategy)) { + button.setSelected(true); + } + } + final JCheckBox egoOverrideField = + new JCheckBox( + "Ego always connected to own alters " + + "(even if all other respondents disagree)", + settings.egoAlwaysTiedToOwnAlters); + panel.add(egoOverrideField,"span,grow"); + + panel.add(new JSeparator(),"span,grow"); + + final JFrame frame = new JFrame("Whole Network Analysis"); + + panel.add(new JButton(new CatchingAction("Save") { + public void safeActionPerformed(ActionEvent e) throws Exception { + try { + settings.inclusionThreshold = Integer.parseInt(inclusionField.getText()); + } catch(Exception ex) { + + } + settings.alwaysIncludeEgo = egoAlwaysIncludedField.isSelected(); + settings.discrepancyStrategy = + DiscrepancyStrategy.valueOf(group.getSelection().getActionCommand()); + settings.egoAlwaysTiedToOwnAlters = egoOverrideField.isSelected(); + frame.dispose(); + } + })); + + frame.setContentPane(panel); + frame.pack(); + frame.setVisible(true); + } + + private void build() { + tableModel = new MapperTableModel(); + final JXTable table = new JXTable(tableModel); + table.setSortable(true); + table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); + + // column 0 - source ego/alter + table.getColumnModel().getColumn(0).setCellRenderer(new MappingRenderer()); + + // column 1 - mapping group + ; // no changes + + MigLayout layout = new MigLayout("fill", "[grow]"); + setLayout(layout); + + JScrollPane scrollPane = + new JScrollPane(table, + ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS); + add(new JLabel("Please perform alter/ego name mappings"), "growx, wrap"); + add(scrollPane, "grow, span, wrap"); + + Action cancelAction = new CatchingAction("Cancel") { + @Override + public void safeActionPerformed(ActionEvent e) throws Exception { + dispose(); + } + }; + JButton cancelButton = new JButton(cancelAction); + add(cancelButton, "split, growx"); + + Action automatchAction = new CatchingAction("Automatch") { + @Override + public void safeActionPerformed(ActionEvent e) throws Exception { + setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); // Hourglass cursor + try { + doDefaultSimilarity(tableModel, 0.8f); + table.repaint(); + } finally { + setCursor(Cursor.getDefaultCursor()); // Finished - back to normal cursor + } + } + }; + JButton automatchButton = new JButton(automatchAction); + add(automatchButton, "split, growx"); + + add( + new JButton(new CatchingAction("Save") { + public void safeActionPerformed(ActionEvent e) + throws Exception { + File studyFile = NameMapperFrame.this.studyFile; + File suggestedOutputFile = + new File( + studyFile.getParent(), + NameMapperFrame.this.study.getStudyName()+".mapping"); + JFileChooser fc = new JFileChooser(suggestedOutputFile); + fc.setSelectedFile(suggestedOutputFile); + fc.addChoosableFileFilter(new ExtensionFileFilter("Name Mapping Files","mapping")); + fc.setDialogTitle("Save name mappings"); + if(fc.showSaveDialog(NameMapperFrame.this) == + JFileChooser.APPROVE_OPTION) + { + new NameMappingWriter(tableModel.getMappings()) + .writeToFile(fc.getSelectedFile()); + } + } + }), + "split, growx"); + add( + new JButton(new CatchingAction("Load") { + public void safeActionPerformed(ActionEvent e) + throws Exception { + File studyFile = NameMapperFrame.this.studyFile; + File suggestedOutputFile = + new File(studyFile.getParent()); + JFileChooser fc = new JFileChooser(suggestedOutputFile); + fc.setSelectedFile(suggestedOutputFile); + fc.addChoosableFileFilter(new ExtensionFileFilter("Name Mapping Files","mapping")); + fc.setDialogTitle("Load name mappings from file"); + if(fc.showOpenDialog(NameMapperFrame.this) == + JFileChooser.APPROVE_OPTION) + { + new NameMappingReader(fc.getSelectedFile()) + .applyTo(tableModel.getMappings()); + } + } + }), + "split, growx"); + add(new JButton( + new CatchingAction("Settings") { + @Override + public void safeActionPerformed(ActionEvent e) throws Exception { + editSettings(settings); + } + }), + "split, growx"); + + Action continueAction = new CatchingAction("Continue") { + @Override + public void safeActionPerformed(ActionEvent e) throws Exception { + + SwingWorker sw = new SwingWorker() { + + WholeNetworkViewer viewer; + + @Override + public Object construct() { + + List mappings = tableModel.getMappings(); + + List interviews = Lists.newArrayList( + Functions.map(new Pair().second, interviewMap)); + + Function2,Interview,Integer> getAlterAttributes = new Function2Impl,Interview,Integer>(){ + public Map call( + Interview interview, Integer alterId) { + return tableModel.attributesForInterviewAndAlterId(interview, alterId); + } + }; + + // do the whole network combination, and export/show it! + WholeNetwork net = + new WholeNetwork(study, interviews, mappings, settings, getAlterAttributes); + + viewer = new WholeNetworkViewer(study, studyFile, net); + return viewer; + } + + public void finished() { + viewer.setVisible(true); + } + + }; + + sw.start(); + dispose(); + + } + }; + JButton continueButton = new JButton(continueAction); + add(continueButton, "growx"); + + + + pack(); + } + + private void doDefaultSimilarity(MapperTableModel model, float cutoff) { + AbstractStringMetric metric = new Levenshtein(); + + Map> groupings = new HashMap>(); + int groupCounter = 1; + + ArrayList names = new ArrayList(model.getMappings()); + while(names.size() > 0) { + NameMapping current = names.remove(0); + + if(current == null || current.alterName == null) + continue; + + float highest = 0.0f; Integer highestGroup = null; + for(Map.Entry> entry : groupings.entrySet()) { + float averageScore = 0; int elementCount = 0; + for(NameMapping entryMapping : entry.getValue()) { + + if(entryMapping.alterName == null) + continue; + + // when figuring a true score, make everything lowercase and trimmed + float thisScore = metric.getSimilarity(current.alterName.toLowerCase().trim(), entryMapping.alterName.toLowerCase().trim()); + if(thisScore >= cutoff) + logger.info(current.alterName + " + " + entryMapping.alterName + " = " + thisScore); + + averageScore += thisScore; + elementCount++; + } + averageScore /= elementCount; + if(averageScore >= cutoff && averageScore > highest) { + highest = averageScore; + highestGroup = entry.getKey(); + } + } + + // pick an existing group + if(highestGroup != null) { + List destGroup = groupings.get(highestGroup); + destGroup.add(current); + } + // create a new group + else { + List destGroup = new ArrayList(); + destGroup.add(current); + groupings.put(groupCounter++, destGroup); + } + } + + for(NameMapping map : model.getMappings()) { + for(Integer group : groupings.keySet()) { + if(groupings.get(group).contains(map)) { + map.setGroup(group); + break; + } + } + } + } +} diff --git a/src/org/egonet/wholenet/gui/WholeNetworkViewer.java b/src/main/java/org/egonet/wholenet/gui/WholeNetworkViewer.java similarity index 97% rename from src/org/egonet/wholenet/gui/WholeNetworkViewer.java rename to src/main/java/org/egonet/wholenet/gui/WholeNetworkViewer.java index b6a8c2c..c129081 100644 --- a/src/org/egonet/wholenet/gui/WholeNetworkViewer.java +++ b/src/main/java/org/egonet/wholenet/gui/WholeNetworkViewer.java @@ -1,318 +1,318 @@ -package org.egonet.wholenet.gui; - -import java.awt.BorderLayout; -import java.awt.HeadlessException; -import java.awt.event.ActionEvent; -import java.io.File; -import java.io.FileWriter; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import javax.swing.JFileChooser; -import javax.swing.JFrame; -import javax.swing.JMenu; -import javax.swing.JMenuBar; -import javax.swing.JMenuItem; -import javax.swing.JOptionPane; -import javax.swing.JPanel; -import javax.swing.filechooser.FileNameExtensionFilter; - -import net.sf.functionalj.tuple.Pair; - -import org.egonet.io.AdjacencyWriter; -import org.egonet.io.EdgeListWriter; -import org.egonet.util.CatchingAction; -import org.egonet.wholenet.graph.WholeNetwork; -import org.egonet.wholenet.graph.WholeNetworkAlter; -import org.egonet.wholenet.graph.WholeNetworkTie; -import org.egonet.wholenet.io.ConsensusDataWriter; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import au.com.bytecode.opencsv.CSVWriter; - -import com.endlessloopsoftware.ego.client.graph.ELSFRLayout2; -import com.endlessloopsoftware.egonet.Study; -import com.google.common.collect.Lists; -import com.google.common.collect.Sets; - -import edu.uci.ics.jung.algorithms.layout.Layout; -import edu.uci.ics.jung.graph.SparseGraph; -import edu.uci.ics.jung.visualization.VisualizationViewer; -import edu.uci.ics.jung.visualization.control.DefaultModalGraphMouse; -import edu.uci.ics.jung.visualization.decorators.EdgeShape; -import edu.uci.ics.jung.visualization.decorators.ToStringLabeller; -import edu.uci.ics.jung.visualization.picking.ShapePickSupport; - -public class WholeNetworkViewer extends JFrame { - - final private static Logger logger = LoggerFactory.getLogger(WholeNetworkViewer.class); - - final private WholeNetwork net; - - final private File studyFile; - final private Study study; - - final private WholeNetworkViewer self; - - public WholeNetworkViewer(Study study, File studyFile, WholeNetwork net) throws HeadlessException { - super("Whole Network Output"); - this.study = study; - this.studyFile = studyFile; - this.net = net; - this.self = this; - build(); - } - - public void build() { - JMenu fileMenu = new JMenu("File"); - fileMenu.setMnemonic('F'); - - saveEdgelistAction.setParent(this); - JMenuItem saveEdgelist = new JMenuItem(saveEdgelistAction); - fileMenu.add(saveEdgelist); - - saveAdjAction.setParent(this); - fileMenu.add(new JMenuItem(saveAdjAction)); - - saveAlterAttributesCSVAction.setParent(this); - fileMenu.add(new JMenuItem(saveAlterAttributesCSVAction)); - - saveConsensusAction.setParent(this); - fileMenu.add(new JMenuItem(saveConsensusAction)); - - JMenuBar mb = new JMenuBar(); - mb.add(fileMenu); - setJMenuBar(mb); - - SparseGraph graph = new SparseGraph(); - - for(WholeNetworkAlter alter : net.getWholeNetworkAlters().values()) { - graph.addVertex(alter); - logger.info("Adding vertex " + alter); - } - - for(WholeNetworkTie tie : net.getWholeNetworkTies()) { - graph.addEdge(tie, tie.getA(), tie.getB()); - logger.info("Adding edge " + tie); - } - - Layout layout = new ELSFRLayout2(graph); - VisualizationViewer vv = new VisualizationViewer(layout); - vv.setGraphMouse(new DefaultModalGraphMouse()); - vv.setPickSupport(new ShapePickSupport(vv)); - vv.getRenderContext().setVertexLabelTransformer(new ToStringLabeller()); - vv.getRenderContext().setEdgeShapeTransformer(new EdgeShape.Line()); - - JFrame frame = new JFrame(); - frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - - JPanel panel = new JPanel(new BorderLayout()); - panel.add(vv, BorderLayout.CENTER); - - setContentPane(panel); - pack(); - } - - final CatchingAction saveEdgelistAction = new CatchingAction("Save Edgelist") { - @Override - public void safeActionPerformed(ActionEvent e) throws Exception { - - String fileName; - fileName = study.getStudyName() + "_wholenetwork_edgelist"; - File currentDirectory = new File(studyFile.getParent() - + "/Graphs"); - currentDirectory.mkdir(); - - JFileChooser fileChooser = new JFileChooser(); - fileChooser.setFileFilter(new FileNameExtensionFilter("Comma-Separated Values","csv")); - fileChooser.setCurrentDirectory(currentDirectory); - fileChooser.setSelectedFile(new File(fileName + ".csv")); - fileChooser.setDialogTitle("Save Whole Network EdgeList (CSV)"); - fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); - - int returnValue = JFileChooser.APPROVE_OPTION; - while (returnValue == JFileChooser.APPROVE_OPTION) { - returnValue = fileChooser.showSaveDialog(parent); - File dataFile = fileChooser.getSelectedFile(); - try { - if(dataFile != null && ! dataFile.isDirectory()) { - String path = dataFile.getAbsolutePath(); - if(! path.endsWith(".csv")) { - path += ".csv"; - dataFile = new File(path); - } - EdgeListWriter fw = new EdgeListWriter(dataFile); - Pair p = net.getAdjacencyMatrix(); - fw.writeEdgelist(p.getFirst(), p.getSecond()); - fw.close(); - } - } catch (Exception e1) { - throw new RuntimeException(e1); - } - break; - } - } - }; - - final CatchingAction saveAdjAction = new CatchingAction("Save Adjacency Matrix") { - @Override - public void safeActionPerformed(ActionEvent e) throws Exception { - - String fileName; - fileName = study.getStudyName() + "_wholenetwork_edgelist"; - File currentDirectory = new File(studyFile.getParent() - + "/Graphs"); - currentDirectory.mkdir(); - - JFileChooser fileChooser = new JFileChooser(); - fileChooser.setFileFilter(new FileNameExtensionFilter("Comma-Separated Values","csv")); - fileChooser.setCurrentDirectory(currentDirectory); - fileChooser.setSelectedFile(new File(fileName + ".csv")); - fileChooser.setDialogTitle("Save Whole Network Adjacency Matrix (CSV)"); - fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); - - int returnValue = JFileChooser.APPROVE_OPTION; - while (returnValue == JFileChooser.APPROVE_OPTION) { - returnValue = fileChooser.showSaveDialog(parent); - File dataFile = fileChooser.getSelectedFile(); - try { - if(dataFile != null && ! dataFile.isDirectory()) { - String path = dataFile.getAbsolutePath(); - if(! path.endsWith(".csv")) { - path += ".csv"; - dataFile = new File(path); - } - AdjacencyWriter fw = new AdjacencyWriter(dataFile); - Pair p = net.getAdjacencyMatrix(); - fw.writeAdjacency(p.getFirst(),p.getSecond()); - fw.close(); - } - } catch (Exception e1) { - throw new RuntimeException(e1); - } - break; - } - } - }; - - final CatchingAction saveConsensusAction = new CatchingAction("Save Consensus Matrix") { - @Override - public void safeActionPerformed(ActionEvent e) throws Exception { - - String fileName; - fileName = study.getStudyName() + "_consensus_matrix"; - File currentDirectory = new File(studyFile.getParent()); - currentDirectory.mkdir(); - - JFileChooser fileChooser = new JFileChooser(); - fileChooser.setFileFilter(new FileNameExtensionFilter("Comma-Separated Values","csv")); - fileChooser.setCurrentDirectory(currentDirectory); - fileChooser.setSelectedFile(new File(fileName + ".csv")); - fileChooser.setDialogTitle("Save Consensus Matrix (CSV)"); - fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); - - int returnValue = JFileChooser.APPROVE_OPTION; - while (returnValue == JFileChooser.APPROVE_OPTION) { - returnValue = fileChooser.showSaveDialog(parent); - File dataFile = fileChooser.getSelectedFile(); - try { - if(dataFile != null && ! dataFile.isDirectory()) { - String path = dataFile.getAbsolutePath(); - if(! path.endsWith(".csv")) { - path += ".csv"; - dataFile = new File(path); - } - Integer missingAllowed = 2; - String missingString = (String) - JOptionPane.showInputDialog(self, - "How many alters can a reporter not report on?" + - "\n (Enter a number)", - "Allowed missing values - filled in randomly", - JOptionPane.PLAIN_MESSAGE, - null,null,missingAllowed+""); - try { - missingAllowed = Integer.parseInt(missingString); - } catch(Exception ex) { - JOptionPane.showMessageDialog(self, "Didn't understand how many alters a reporter is allowed to not report on."+ - "\nFalling back on default value of "+missingAllowed+"."); - } - String msg = new ConsensusDataWriter(net,missingAllowed).writeToFile(dataFile); - JOptionPane.showMessageDialog(self, msg); - } - } catch (Exception e1) { - throw new RuntimeException(e1); - } - break; - } - } - }; - - final CatchingAction saveAlterAttributesCSVAction = new CatchingAction("Save Alter Attributes") { - @Override - public void safeActionPerformed(ActionEvent e) throws Exception { - - String fileName; - fileName = study.getStudyName() + "_wholenetwork_nodes"; - File currentDirectory = new File(studyFile.getParent() - + "/Graphs"); - currentDirectory.mkdir(); - - JFileChooser fileChooser = new JFileChooser(); - fileChooser.setFileFilter(new FileNameExtensionFilter("Comma-Separated Values","csv")); - fileChooser.setCurrentDirectory(currentDirectory); - fileChooser.setSelectedFile(new File(fileName + ".csv")); - fileChooser.setDialogTitle("Save Alter Attributes (CSV)"); - fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); - - int returnValue = JFileChooser.APPROVE_OPTION; - while (returnValue == JFileChooser.APPROVE_OPTION) { - returnValue = fileChooser.showSaveDialog(parent); - File dataFile = fileChooser.getSelectedFile(); - try { - if(dataFile != null && ! dataFile.isDirectory()) { - String path = dataFile.getAbsolutePath(); - if(! path.endsWith(".csv")) { - path += ".csv"; - dataFile = new File(path); - } - - FileWriter fw = new FileWriter(dataFile); - CSVWriter csv = new CSVWriter(fw); - - Set questionSet = Sets.newHashSet(); - for(WholeNetworkAlter alter : net.getWholeNetworkAlters().values()) { - questionSet.addAll(alter.getAttributes().keySet()); - } - List questionList = new ArrayList(questionSet); - - List heading = Lists.newArrayList("MappingId","Name"); - heading.addAll(questionList); - csv.writeNext(heading.toArray(new String[]{})); - - for(WholeNetworkAlter alter : net.getWholeNetworkAlters().values()) { - ArrayList row = - Lists.newArrayList( - alter.getId()+"", - alter.getOccurences().get(0).toString().replaceAll("[^a-zA-Z_\\-0-9]+", "_")); - Map answers = alter.getAttributes(); - for(String question : questionList) { - String value = answers.get(question); - row.add(value == null ? "" : value); - } - csv.writeNext(row.toArray(new String[]{})); - } - - csv.flush(); - fw.close(); - } - } catch (Exception e1) { - throw new RuntimeException(e1); - } - break; - } - } - }; -} +package org.egonet.wholenet.gui; + +import java.awt.BorderLayout; +import java.awt.HeadlessException; +import java.awt.event.ActionEvent; +import java.io.File; +import java.io.FileWriter; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.swing.JFileChooser; +import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.filechooser.FileNameExtensionFilter; + +import net.sf.functionalj.tuple.Pair; + +import org.egonet.io.AdjacencyWriter; +import org.egonet.io.EdgeListWriter; +import org.egonet.util.CatchingAction; +import org.egonet.wholenet.graph.WholeNetwork; +import org.egonet.wholenet.graph.WholeNetworkAlter; +import org.egonet.wholenet.graph.WholeNetworkTie; +import org.egonet.wholenet.io.ConsensusDataWriter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import au.com.bytecode.opencsv.CSVWriter; + +import com.endlessloopsoftware.ego.client.graph.ELSFRLayout2; +import com.endlessloopsoftware.egonet.Study; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; + +import edu.uci.ics.jung.algorithms.layout.Layout; +import edu.uci.ics.jung.graph.SparseGraph; +import edu.uci.ics.jung.visualization.VisualizationViewer; +import edu.uci.ics.jung.visualization.control.DefaultModalGraphMouse; +import edu.uci.ics.jung.visualization.decorators.EdgeShape; +import edu.uci.ics.jung.visualization.decorators.ToStringLabeller; +import edu.uci.ics.jung.visualization.picking.ShapePickSupport; + +public class WholeNetworkViewer extends JFrame { + + final private static Logger logger = LoggerFactory.getLogger(WholeNetworkViewer.class); + + final private WholeNetwork net; + + final private File studyFile; + final private Study study; + + final private WholeNetworkViewer self; + + public WholeNetworkViewer(Study study, File studyFile, WholeNetwork net) throws HeadlessException { + super("Whole Network Output"); + this.study = study; + this.studyFile = studyFile; + this.net = net; + this.self = this; + build(); + } + + public void build() { + JMenu fileMenu = new JMenu("File"); + fileMenu.setMnemonic('F'); + + saveEdgelistAction.setParent(this); + JMenuItem saveEdgelist = new JMenuItem(saveEdgelistAction); + fileMenu.add(saveEdgelist); + + saveAdjAction.setParent(this); + fileMenu.add(new JMenuItem(saveAdjAction)); + + saveAlterAttributesCSVAction.setParent(this); + fileMenu.add(new JMenuItem(saveAlterAttributesCSVAction)); + + saveConsensusAction.setParent(this); + fileMenu.add(new JMenuItem(saveConsensusAction)); + + JMenuBar mb = new JMenuBar(); + mb.add(fileMenu); + setJMenuBar(mb); + + SparseGraph graph = new SparseGraph(); + + for(WholeNetworkAlter alter : net.getWholeNetworkAlters().values()) { + graph.addVertex(alter); + logger.info("Adding vertex " + alter); + } + + for(WholeNetworkTie tie : net.getWholeNetworkTies()) { + graph.addEdge(tie, tie.getA(), tie.getB()); + logger.info("Adding edge " + tie); + } + + Layout layout = new ELSFRLayout2(graph); + VisualizationViewer vv = new VisualizationViewer(layout); + vv.setGraphMouse(new DefaultModalGraphMouse()); + vv.setPickSupport(new ShapePickSupport(vv)); + vv.getRenderContext().setVertexLabelTransformer(new ToStringLabeller()); + vv.getRenderContext().setEdgeShapeTransformer(new EdgeShape.Line()); + + JFrame frame = new JFrame(); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + JPanel panel = new JPanel(new BorderLayout()); + panel.add(vv, BorderLayout.CENTER); + + setContentPane(panel); + pack(); + } + + final CatchingAction saveEdgelistAction = new CatchingAction("Save Edgelist") { + @Override + public void safeActionPerformed(ActionEvent e) throws Exception { + + String fileName; + fileName = study.getStudyName() + "_wholenetwork_edgelist"; + File currentDirectory = new File(studyFile.getParent() + + "/Graphs"); + currentDirectory.mkdir(); + + JFileChooser fileChooser = new JFileChooser(); + fileChooser.setFileFilter(new FileNameExtensionFilter("Comma-Separated Values","csv")); + fileChooser.setCurrentDirectory(currentDirectory); + fileChooser.setSelectedFile(new File(fileName + ".csv")); + fileChooser.setDialogTitle("Save Whole Network EdgeList (CSV)"); + fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); + + int returnValue = JFileChooser.APPROVE_OPTION; + while (returnValue == JFileChooser.APPROVE_OPTION) { + returnValue = fileChooser.showSaveDialog(parent); + File dataFile = fileChooser.getSelectedFile(); + try { + if(dataFile != null && ! dataFile.isDirectory()) { + String path = dataFile.getAbsolutePath(); + if(! path.endsWith(".csv")) { + path += ".csv"; + dataFile = new File(path); + } + EdgeListWriter fw = new EdgeListWriter(dataFile); + Pair p = net.getAdjacencyMatrix(); + fw.writeEdgelist(p.getFirst(), p.getSecond()); + fw.close(); + } + } catch (Exception e1) { + throw new RuntimeException(e1); + } + break; + } + } + }; + + final CatchingAction saveAdjAction = new CatchingAction("Save Adjacency Matrix") { + @Override + public void safeActionPerformed(ActionEvent e) throws Exception { + + String fileName; + fileName = study.getStudyName() + "_wholenetwork_edgelist"; + File currentDirectory = new File(studyFile.getParent() + + "/Graphs"); + currentDirectory.mkdir(); + + JFileChooser fileChooser = new JFileChooser(); + fileChooser.setFileFilter(new FileNameExtensionFilter("Comma-Separated Values","csv")); + fileChooser.setCurrentDirectory(currentDirectory); + fileChooser.setSelectedFile(new File(fileName + ".csv")); + fileChooser.setDialogTitle("Save Whole Network Adjacency Matrix (CSV)"); + fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); + + int returnValue = JFileChooser.APPROVE_OPTION; + while (returnValue == JFileChooser.APPROVE_OPTION) { + returnValue = fileChooser.showSaveDialog(parent); + File dataFile = fileChooser.getSelectedFile(); + try { + if(dataFile != null && ! dataFile.isDirectory()) { + String path = dataFile.getAbsolutePath(); + if(! path.endsWith(".csv")) { + path += ".csv"; + dataFile = new File(path); + } + AdjacencyWriter fw = new AdjacencyWriter(dataFile); + Pair p = net.getAdjacencyMatrix(); + fw.writeAdjacency(p.getFirst(),p.getSecond()); + fw.close(); + } + } catch (Exception e1) { + throw new RuntimeException(e1); + } + break; + } + } + }; + + final CatchingAction saveConsensusAction = new CatchingAction("Save Consensus Matrix") { + @Override + public void safeActionPerformed(ActionEvent e) throws Exception { + + String fileName; + fileName = study.getStudyName() + "_consensus_matrix"; + File currentDirectory = new File(studyFile.getParent()); + currentDirectory.mkdir(); + + JFileChooser fileChooser = new JFileChooser(); + fileChooser.setFileFilter(new FileNameExtensionFilter("Comma-Separated Values","csv")); + fileChooser.setCurrentDirectory(currentDirectory); + fileChooser.setSelectedFile(new File(fileName + ".csv")); + fileChooser.setDialogTitle("Save Consensus Matrix (CSV)"); + fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); + + int returnValue = JFileChooser.APPROVE_OPTION; + while (returnValue == JFileChooser.APPROVE_OPTION) { + returnValue = fileChooser.showSaveDialog(parent); + File dataFile = fileChooser.getSelectedFile(); + try { + if(dataFile != null && ! dataFile.isDirectory()) { + String path = dataFile.getAbsolutePath(); + if(! path.endsWith(".csv")) { + path += ".csv"; + dataFile = new File(path); + } + Integer missingAllowed = 2; + String missingString = (String) + JOptionPane.showInputDialog(self, + "How many alters can a reporter not report on?" + + "\n (Enter a number)", + "Allowed missing values - filled in randomly", + JOptionPane.PLAIN_MESSAGE, + null,null,missingAllowed+""); + try { + missingAllowed = Integer.parseInt(missingString); + } catch(Exception ex) { + JOptionPane.showMessageDialog(self, "Didn't understand how many alters a reporter is allowed to not report on."+ + "\nFalling back on default value of "+missingAllowed+"."); + } + String msg = new ConsensusDataWriter(net,missingAllowed).writeToFile(dataFile); + JOptionPane.showMessageDialog(self, msg); + } + } catch (Exception e1) { + throw new RuntimeException(e1); + } + break; + } + } + }; + + final CatchingAction saveAlterAttributesCSVAction = new CatchingAction("Save Alter Attributes") { + @Override + public void safeActionPerformed(ActionEvent e) throws Exception { + + String fileName; + fileName = study.getStudyName() + "_wholenetwork_nodes"; + File currentDirectory = new File(studyFile.getParent() + + "/Graphs"); + currentDirectory.mkdir(); + + JFileChooser fileChooser = new JFileChooser(); + fileChooser.setFileFilter(new FileNameExtensionFilter("Comma-Separated Values","csv")); + fileChooser.setCurrentDirectory(currentDirectory); + fileChooser.setSelectedFile(new File(fileName + ".csv")); + fileChooser.setDialogTitle("Save Alter Attributes (CSV)"); + fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); + + int returnValue = JFileChooser.APPROVE_OPTION; + while (returnValue == JFileChooser.APPROVE_OPTION) { + returnValue = fileChooser.showSaveDialog(parent); + File dataFile = fileChooser.getSelectedFile(); + try { + if(dataFile != null && ! dataFile.isDirectory()) { + String path = dataFile.getAbsolutePath(); + if(! path.endsWith(".csv")) { + path += ".csv"; + dataFile = new File(path); + } + + FileWriter fw = new FileWriter(dataFile); + CSVWriter csv = new CSVWriter(fw); + + Set questionSet = Sets.newHashSet(); + for(WholeNetworkAlter alter : net.getWholeNetworkAlters().values()) { + questionSet.addAll(alter.getAttributes().keySet()); + } + List questionList = new ArrayList(questionSet); + + List heading = Lists.newArrayList("MappingId","Name"); + heading.addAll(questionList); + csv.writeNext(heading.toArray(new String[]{})); + + for(WholeNetworkAlter alter : net.getWholeNetworkAlters().values()) { + ArrayList row = + Lists.newArrayList( + alter.getId()+"", + alter.getOccurences().get(0).toString().replaceAll("[^a-zA-Z_\\-0-9]+", "_")); + Map answers = alter.getAttributes(); + for(String question : questionList) { + String value = answers.get(question); + row.add(value == null ? "" : value); + } + csv.writeNext(row.toArray(new String[]{})); + } + + csv.flush(); + fw.close(); + } + } catch (Exception e1) { + throw new RuntimeException(e1); + } + break; + } + } + }; +} diff --git a/src/org/egonet/wholenet/io/ConsensusDataWriter.java b/src/main/java/org/egonet/wholenet/io/ConsensusDataWriter.java similarity index 97% rename from src/org/egonet/wholenet/io/ConsensusDataWriter.java rename to src/main/java/org/egonet/wholenet/io/ConsensusDataWriter.java index 377017a..a10573b 100644 --- a/src/org/egonet/wholenet/io/ConsensusDataWriter.java +++ b/src/main/java/org/egonet/wholenet/io/ConsensusDataWriter.java @@ -1,193 +1,193 @@ -package org.egonet.wholenet.io; - -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.util.List; -import java.util.Map; -import java.util.Random; -import java.util.Set; - -import org.egonet.graph.KPlexesTwoMode; -import org.egonet.wholenet.graph.WholeNetwork; -import org.egonet.wholenet.graph.WholeNetworkAlter; -import org.egonet.wholenet.graph.WholeNetworkTie; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import au.com.bytecode.opencsv.CSVWriter; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; - -public class ConsensusDataWriter { - - final private static Logger logger = LoggerFactory.getLogger(ConsensusDataWriter.class); - - WholeNetwork net; - Integer allowedMissingEdgesPerNode; - public ConsensusDataWriter(WholeNetwork net, Integer allowedMissingEdgesPerNode) { - this.net = net; - this.allowedMissingEdgesPerNode = allowedMissingEdgesPerNode; - } - @SuppressWarnings("unchecked") - public String writeToFile(File file) throws IOException { - Set allAlters = - Sets.newHashSet(net.getWholeNetworkAlters().values()); - - Integer numTies = 0; - Integer numMixedTies = 0; - Integer numYesOnlyTies = 0; - Integer numNoOnlyTies = 0; - Integer numUntied = 0; - Integer numTiedWithoutVotes = 0; - - Map> - reportersByAlter = Maps.newHashMap(); - Set allReporters = Sets.newHashSet(); - for(WholeNetworkAlter alter1 : allAlters) { - Set alter1reporters = Sets.newHashSet(); - for(WholeNetworkAlter alter2 : allAlters) { - if(! alter1.equals(alter2)) { - WholeNetworkTie tie = net.getTie(alter1, alter2); - if(tie == null) { - numUntied++; - } else { - numTies++; - Set tieReporters = Sets.union(tie.tiedNo(), tie.tiedYes()); - alter1reporters.addAll(tieReporters); - if(tieReporters.isEmpty()) { - numTiedWithoutVotes++; - } else if(tie.tiedNo().isEmpty()) { - numYesOnlyTies++; - } else if(tie.tiedYes().isEmpty()) { - numNoOnlyTies++; - } else { - numMixedTies++; - } - } - } - } - reportersByAlter.put(alter1, alter1reporters); - allReporters.addAll(alter1reporters); - } - logger.info("NumTies: "+numTies+", NumMixed: "+numMixedTies+ - ", NumYesOnly: "+numYesOnlyTies+", NumNoOnly: "+numNoOnlyTies+ - ", NumUntied: "+numUntied+", NumTiedWithoutVotes: "+numTiedWithoutVotes); - - Map> - altersByReporter = Maps.newHashMap(); - for(Integer reporter : allReporters) { - Set reporterAlters = Sets.newHashSet(); - for(WholeNetworkAlter alter : allAlters) { - if(reportersByAlter.get(alter).contains(reporter)) { - reporterAlters.add(alter); - } - } - altersByReporter.put(reporter, reporterAlters); - } - - // Construct two mode network of alters and reporters and look for cliques, - // which are subnetworks in which all reporters can report on all alters. - // Add connections for 100% density within modes so that I can use a - // one mode clique finding algorithm. - Map alterAndReporterTwoMode = Maps.newHashMap(); - for(Integer reporter : allReporters) { - Set reporterConnections = Sets.newHashSet(); - reporterConnections.addAll(altersByReporter.get(reporter)); - alterAndReporterTwoMode.put(reporter, reporterConnections); - } - for(WholeNetworkAlter alter : allAlters) { - Set alterConnections = Sets.newHashSet(); - alterConnections.addAll(reportersByAlter.get(alter)); - alterAndReporterTwoMode.put(alter, alterConnections); - } - Set kplex = new KPlexesTwoMode().findLargeKPlex(alterAndReporterTwoMode, allReporters, allowedMissingEdgesPerNode); - Set kplexReporters = Sets.intersection(allReporters, kplex); - Set kplexAlters = Sets.intersection(allAlters, kplex); - - List alterList = Lists.newArrayList(kplexAlters); - List reporterList = Lists.newArrayList(kplexReporters); - - FileWriter fw = new FileWriter(file); - CSVWriter csv = new CSVWriter(fw); - - List header = Lists.newArrayList(""); - for(int i = 0; i < alterList.size(); i++) { - WholeNetworkAlter alter1 = alterList.get(i); - for(int j = i+1; j < alterList.size(); j++) { - WholeNetworkAlter alter2 = alterList.get(j); - if(! alter1.equals(alter2)) { - header.add(alter1+" - "+alter2); - } - } - } - csv.writeNext(header.toArray(new String[]{})); - - Integer dataYes = 0, dataNo = 0, guessYes = 0, guessNo = 0; - Integer guessWithKnownAlters = 0; - Integer guessWithUnknownAlters = 0; - Random rand = new Random(); - - for(Integer reporter : reporterList) { - List line = Lists.newArrayList(reporter+""); - for(int i = 0; i < alterList.size(); i++) { - WholeNetworkAlter alter1 = alterList.get(i); - for(int j = i+1; j < alterList.size(); j++) { - WholeNetworkAlter alter2 = alterList.get(j); - WholeNetworkTie tie = net.getTie(alter1, alter2); - if(alterAndReporterTwoMode.get(reporter).contains(alter1) && - alterAndReporterTwoMode.get(reporter).contains(alter2)) - { - if(alter1.getId().equals(reporter) || - alter2.getId().equals(reporter)) - { // Tie between ego and alter - line.add("1"); - dataYes++; - } else if(tie != null && tie.tiedYes().contains(reporter)) { - line.add("1"); - dataYes++; - } else if(tie != null && tie.tiedNo().contains(reporter)) { - line.add("0"); - dataNo++; - } else { - guessWithKnownAlters++; - System.out.println(reporter+" knows "+alter1+" and "+alter2+ - " but didn't say whether they are linked."); - } - } else { - if(rand.nextInt(2) > 0) { - line.add("1"); - guessYes++; - } else { - line.add("0"); - guessNo++; - } - guessWithUnknownAlters++; - } - } - } - csv.writeNext(line.toArray(new String[]{})); - } - Integer reportedAnswers = dataYes+dataNo; - Integer imputedAnswers = guessYes+guessNo; - Double portionImputed = imputedAnswers*1.0/(reportedAnswers+imputedAnswers); - String msg = - "Allowed max missing per node: "+allowedMissingEdgesPerNode+ - "\nActual max missing per node: "+ - new KPlexesTwoMode().maxMissingEdgesPerNodeInSubgroup(alterAndReporterTwoMode, allReporters, kplex)+ - "\nReporters: "+reporterList.size()+ - "\nAlters: "+alterList.size()+ - "\nReported answers: "+reportedAnswers+ - "\nImputed answers: "+imputedAnswers+ - "\nPercent imputed: "+((int) (portionImputed*100))+"%"+ - "\nReporter didn't know one or both alters: "+guessWithUnknownAlters+ - "\nReporter knew alters, but I couldn't find answer: "+guessWithKnownAlters; - System.out.println(msg); - - csv.flush(); - fw.close(); - return msg; - } -} +package org.egonet.wholenet.io; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.Set; + +import org.egonet.graph.KPlexesTwoMode; +import org.egonet.wholenet.graph.WholeNetwork; +import org.egonet.wholenet.graph.WholeNetworkAlter; +import org.egonet.wholenet.graph.WholeNetworkTie; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import au.com.bytecode.opencsv.CSVWriter; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; + +public class ConsensusDataWriter { + + final private static Logger logger = LoggerFactory.getLogger(ConsensusDataWriter.class); + + WholeNetwork net; + Integer allowedMissingEdgesPerNode; + public ConsensusDataWriter(WholeNetwork net, Integer allowedMissingEdgesPerNode) { + this.net = net; + this.allowedMissingEdgesPerNode = allowedMissingEdgesPerNode; + } + @SuppressWarnings("unchecked") + public String writeToFile(File file) throws IOException { + Set allAlters = + Sets.newHashSet(net.getWholeNetworkAlters().values()); + + Integer numTies = 0; + Integer numMixedTies = 0; + Integer numYesOnlyTies = 0; + Integer numNoOnlyTies = 0; + Integer numUntied = 0; + Integer numTiedWithoutVotes = 0; + + Map> + reportersByAlter = Maps.newHashMap(); + Set allReporters = Sets.newHashSet(); + for(WholeNetworkAlter alter1 : allAlters) { + Set alter1reporters = Sets.newHashSet(); + for(WholeNetworkAlter alter2 : allAlters) { + if(! alter1.equals(alter2)) { + WholeNetworkTie tie = net.getTie(alter1, alter2); + if(tie == null) { + numUntied++; + } else { + numTies++; + Set tieReporters = Sets.union(tie.tiedNo(), tie.tiedYes()); + alter1reporters.addAll(tieReporters); + if(tieReporters.isEmpty()) { + numTiedWithoutVotes++; + } else if(tie.tiedNo().isEmpty()) { + numYesOnlyTies++; + } else if(tie.tiedYes().isEmpty()) { + numNoOnlyTies++; + } else { + numMixedTies++; + } + } + } + } + reportersByAlter.put(alter1, alter1reporters); + allReporters.addAll(alter1reporters); + } + logger.info("NumTies: "+numTies+", NumMixed: "+numMixedTies+ + ", NumYesOnly: "+numYesOnlyTies+", NumNoOnly: "+numNoOnlyTies+ + ", NumUntied: "+numUntied+", NumTiedWithoutVotes: "+numTiedWithoutVotes); + + Map> + altersByReporter = Maps.newHashMap(); + for(Integer reporter : allReporters) { + Set reporterAlters = Sets.newHashSet(); + for(WholeNetworkAlter alter : allAlters) { + if(reportersByAlter.get(alter).contains(reporter)) { + reporterAlters.add(alter); + } + } + altersByReporter.put(reporter, reporterAlters); + } + + // Construct two mode network of alters and reporters and look for cliques, + // which are subnetworks in which all reporters can report on all alters. + // Add connections for 100% density within modes so that I can use a + // one mode clique finding algorithm. + Map alterAndReporterTwoMode = Maps.newHashMap(); + for(Integer reporter : allReporters) { + Set reporterConnections = Sets.newHashSet(); + reporterConnections.addAll(altersByReporter.get(reporter)); + alterAndReporterTwoMode.put(reporter, reporterConnections); + } + for(WholeNetworkAlter alter : allAlters) { + Set alterConnections = Sets.newHashSet(); + alterConnections.addAll(reportersByAlter.get(alter)); + alterAndReporterTwoMode.put(alter, alterConnections); + } + Set kplex = new KPlexesTwoMode().findLargeKPlex(alterAndReporterTwoMode, allReporters, allowedMissingEdgesPerNode); + Set kplexReporters = Sets.intersection(allReporters, kplex); + Set kplexAlters = Sets.intersection(allAlters, kplex); + + List alterList = Lists.newArrayList(kplexAlters); + List reporterList = Lists.newArrayList(kplexReporters); + + FileWriter fw = new FileWriter(file); + CSVWriter csv = new CSVWriter(fw); + + List header = Lists.newArrayList(""); + for(int i = 0; i < alterList.size(); i++) { + WholeNetworkAlter alter1 = alterList.get(i); + for(int j = i+1; j < alterList.size(); j++) { + WholeNetworkAlter alter2 = alterList.get(j); + if(! alter1.equals(alter2)) { + header.add(alter1+" - "+alter2); + } + } + } + csv.writeNext(header.toArray(new String[]{})); + + Integer dataYes = 0, dataNo = 0, guessYes = 0, guessNo = 0; + Integer guessWithKnownAlters = 0; + Integer guessWithUnknownAlters = 0; + Random rand = new Random(); + + for(Integer reporter : reporterList) { + List line = Lists.newArrayList(reporter+""); + for(int i = 0; i < alterList.size(); i++) { + WholeNetworkAlter alter1 = alterList.get(i); + for(int j = i+1; j < alterList.size(); j++) { + WholeNetworkAlter alter2 = alterList.get(j); + WholeNetworkTie tie = net.getTie(alter1, alter2); + if(alterAndReporterTwoMode.get(reporter).contains(alter1) && + alterAndReporterTwoMode.get(reporter).contains(alter2)) + { + if(alter1.getId().equals(reporter) || + alter2.getId().equals(reporter)) + { // Tie between ego and alter + line.add("1"); + dataYes++; + } else if(tie != null && tie.tiedYes().contains(reporter)) { + line.add("1"); + dataYes++; + } else if(tie != null && tie.tiedNo().contains(reporter)) { + line.add("0"); + dataNo++; + } else { + guessWithKnownAlters++; + System.out.println(reporter+" knows "+alter1+" and "+alter2+ + " but didn't say whether they are linked."); + } + } else { + if(rand.nextInt(2) > 0) { + line.add("1"); + guessYes++; + } else { + line.add("0"); + guessNo++; + } + guessWithUnknownAlters++; + } + } + } + csv.writeNext(line.toArray(new String[]{})); + } + Integer reportedAnswers = dataYes+dataNo; + Integer imputedAnswers = guessYes+guessNo; + Double portionImputed = imputedAnswers*1.0/(reportedAnswers+imputedAnswers); + String msg = + "Allowed max missing per node: "+allowedMissingEdgesPerNode+ + "\nActual max missing per node: "+ + new KPlexesTwoMode().maxMissingEdgesPerNodeInSubgroup(alterAndReporterTwoMode, allReporters, kplex)+ + "\nReporters: "+reporterList.size()+ + "\nAlters: "+alterList.size()+ + "\nReported answers: "+reportedAnswers+ + "\nImputed answers: "+imputedAnswers+ + "\nPercent imputed: "+((int) (portionImputed*100))+"%"+ + "\nReporter didn't know one or both alters: "+guessWithUnknownAlters+ + "\nReporter knew alters, but I couldn't find answer: "+guessWithKnownAlters; + System.out.println(msg); + + csv.flush(); + fw.close(); + return msg; + } +} diff --git a/src/org/egonet/wholenet/io/NameMappingReader.java b/src/main/java/org/egonet/wholenet/io/NameMappingReader.java similarity index 96% rename from src/org/egonet/wholenet/io/NameMappingReader.java rename to src/main/java/org/egonet/wholenet/io/NameMappingReader.java index 4859dea..bc9c066 100644 --- a/src/org/egonet/wholenet/io/NameMappingReader.java +++ b/src/main/java/org/egonet/wholenet/io/NameMappingReader.java @@ -1,202 +1,202 @@ -package org.egonet.wholenet.io; - -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.egonet.wholenet.gui.NameMapperFrame.NameMapping; - -import net.sf.functionalj.tuple.Pair; - -import com.google.common.collect.ArrayListMultimap; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Multimap; -import com.google.common.collect.Sets; - -import au.com.bytecode.opencsv.CSVReader; - -public class NameMappingReader { - - public static class Mapping { - - // "ego_first","ego_last","alter_number","alter_name","group" - - public String egoName,alterName; - public Integer alterNumber, group; - - public Mapping(String[] csvColumns) { - this(csvColumns[0],csvColumns[1],csvColumns[2],csvColumns[3]); - } - - public Mapping(String egoName, String alterNumber, String alterName, String group) - { - this.egoName = egoName; - this.alterNumber = Integer.parseInt(alterNumber); - this.alterName = alterName; - this.group = Integer.parseInt(group); - } - - public Mapping(NameMapping mapping) { - String name = mapping.getInterview().getIntName(); - this.egoName = name; - - this.alterNumber = mapping.getAlterNumber(); - this.alterName = mapping.toString(); - this.group = mapping.getGroup(); - } - - public Key key() { - return new Key(egoName,alterNumber); - } - } - - public static class Key extends Pair { - public Key(String name, Integer alterNumber) { - super(name,alterNumber); - } - public String toString() { - return getFirst()+" "+getSecond(); - } - } - - public static class Mappings { - private List mappings; - private Map keyToMapping; - private Multimap groupToMappings; - - public Mappings() { - mappings = Lists.newArrayList(); - keyToMapping = Maps.newHashMap(); - groupToMappings = ArrayListMultimap.create(); - } - - public void add(Mapping mapping) { - mappings.add(mapping); - keyToMapping.put(mapping.key(), mapping); - groupToMappings.put(mapping.group, mapping); - } - - private void reIndex() { - keyToMapping = Maps.newHashMap(); - groupToMappings = ArrayListMultimap.create(); - for(Mapping mapping : mappings) { - keyToMapping.put(mapping.key(), mapping); - groupToMappings.put(mapping.group, mapping); - } - } - - public Set groups() { - return groupToMappings.keySet(); - } - - public Collection group(Integer groupIndex) { - return groupToMappings.get(groupIndex); - } - - public void breakGroup(Integer groupIndex) { - Collection group = group(groupIndex); - - List unusedIndices = Lists.newArrayList(); - for(Integer i = 1; unusedIndices.size() < group.size(); i++) { - if(i.equals(groupIndex) || ! groups().contains(i)) { - unusedIndices.add(i); - } - } - - for(Mapping mapping : group) { - mapping.group = unusedIndices.remove(0); - } - - reIndex(); - } - - public void combineGroups(Integer... groupIndexes) { - if(groupIndexes.length > 1) { - for(Integer groupIndex : groupIndexes) { - for(Mapping mapping : group(groupIndex)) { - mapping.group = groupIndexes[0]; - } - } - reIndex(); - } - } - - public Set keys() { - return keyToMapping.keySet(); - } - - public Mapping get(Key key) { - return keyToMapping.get(key); - } - } - - private Mappings mappings; - - public NameMappingReader(File mappingFile) throws IOException { - FileReader fileReader = new FileReader(mappingFile); - CSVReader csv = new CSVReader(fileReader); - - csv.readNext(); // skip header - - mappings = new Mappings(); - - String[] nextLine; - while((nextLine = csv.readNext()) != null) { - mappings.add(new Mapping(nextLine)); - } - - fileReader.close(); - } - - public void applyTo(List nameMappings) { - Mappings oldMappings = new Mappings(); - for(NameMapping nameMapping : nameMappings) { - oldMappings.add(new Mapping(nameMapping)); - } - - // Remove incorrect links - for(Integer oldGroup : new ArrayList(oldMappings.groups())) { - Boolean groupShownToBeInvalid = false; - for(Mapping oldMapping1 : oldMappings.group(oldGroup)) { - Mapping mapping1 = mappings.get(oldMapping1.key()); - for(Mapping oldMapping2 : oldMappings.group(oldGroup)) { - Mapping mapping2 = mappings.get(oldMapping2.key()); - if(mapping1 != null && mapping2 != null && - ! mapping1.group.equals(mapping2.group)) - { - groupShownToBeInvalid = true; - } - } - } - if(groupShownToBeInvalid) { - oldMappings.breakGroup(oldGroup); - } - } - - // Add new links - for(Integer group : mappings.groups()) { - Set matchingOldGroups = Sets.newTreeSet(); - for(Mapping mapping : mappings.group(group)) { - Mapping oldMapping = oldMappings.get(mapping.key()); - if(oldMapping != null) { - matchingOldGroups.add(oldMapping.group); - } - } - oldMappings.combineGroups(matchingOldGroups.toArray(new Integer[]{})); - } - - // Apply calculated groupings to original name mappings. - for(NameMapping nameMapping : nameMappings) { - nameMapping.setGroup( - oldMappings.get( - new Mapping(nameMapping).key()) - .group); - } - } -} +package org.egonet.wholenet.io; + +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.egonet.wholenet.gui.NameMapperFrame.NameMapping; + +import net.sf.functionalj.tuple.Pair; + +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Multimap; +import com.google.common.collect.Sets; + +import au.com.bytecode.opencsv.CSVReader; + +public class NameMappingReader { + + public static class Mapping { + + // "ego_first","ego_last","alter_number","alter_name","group" + + public String egoName,alterName; + public Integer alterNumber, group; + + public Mapping(String[] csvColumns) { + this(csvColumns[0],csvColumns[1],csvColumns[2],csvColumns[3]); + } + + public Mapping(String egoName, String alterNumber, String alterName, String group) + { + this.egoName = egoName; + this.alterNumber = Integer.parseInt(alterNumber); + this.alterName = alterName; + this.group = Integer.parseInt(group); + } + + public Mapping(NameMapping mapping) { + String name = mapping.getInterview().getIntName(); + this.egoName = name; + + this.alterNumber = mapping.getAlterNumber(); + this.alterName = mapping.toString(); + this.group = mapping.getGroup(); + } + + public Key key() { + return new Key(egoName,alterNumber); + } + } + + public static class Key extends Pair { + public Key(String name, Integer alterNumber) { + super(name,alterNumber); + } + public String toString() { + return getFirst()+" "+getSecond(); + } + } + + public static class Mappings { + private List mappings; + private Map keyToMapping; + private Multimap groupToMappings; + + public Mappings() { + mappings = Lists.newArrayList(); + keyToMapping = Maps.newHashMap(); + groupToMappings = ArrayListMultimap.create(); + } + + public void add(Mapping mapping) { + mappings.add(mapping); + keyToMapping.put(mapping.key(), mapping); + groupToMappings.put(mapping.group, mapping); + } + + private void reIndex() { + keyToMapping = Maps.newHashMap(); + groupToMappings = ArrayListMultimap.create(); + for(Mapping mapping : mappings) { + keyToMapping.put(mapping.key(), mapping); + groupToMappings.put(mapping.group, mapping); + } + } + + public Set groups() { + return groupToMappings.keySet(); + } + + public Collection group(Integer groupIndex) { + return groupToMappings.get(groupIndex); + } + + public void breakGroup(Integer groupIndex) { + Collection group = group(groupIndex); + + List unusedIndices = Lists.newArrayList(); + for(Integer i = 1; unusedIndices.size() < group.size(); i++) { + if(i.equals(groupIndex) || ! groups().contains(i)) { + unusedIndices.add(i); + } + } + + for(Mapping mapping : group) { + mapping.group = unusedIndices.remove(0); + } + + reIndex(); + } + + public void combineGroups(Integer... groupIndexes) { + if(groupIndexes.length > 1) { + for(Integer groupIndex : groupIndexes) { + for(Mapping mapping : group(groupIndex)) { + mapping.group = groupIndexes[0]; + } + } + reIndex(); + } + } + + public Set keys() { + return keyToMapping.keySet(); + } + + public Mapping get(Key key) { + return keyToMapping.get(key); + } + } + + private Mappings mappings; + + public NameMappingReader(File mappingFile) throws IOException { + FileReader fileReader = new FileReader(mappingFile); + CSVReader csv = new CSVReader(fileReader); + + csv.readNext(); // skip header + + mappings = new Mappings(); + + String[] nextLine; + while((nextLine = csv.readNext()) != null) { + mappings.add(new Mapping(nextLine)); + } + + fileReader.close(); + } + + public void applyTo(List nameMappings) { + Mappings oldMappings = new Mappings(); + for(NameMapping nameMapping : nameMappings) { + oldMappings.add(new Mapping(nameMapping)); + } + + // Remove incorrect links + for(Integer oldGroup : new ArrayList(oldMappings.groups())) { + Boolean groupShownToBeInvalid = false; + for(Mapping oldMapping1 : oldMappings.group(oldGroup)) { + Mapping mapping1 = mappings.get(oldMapping1.key()); + for(Mapping oldMapping2 : oldMappings.group(oldGroup)) { + Mapping mapping2 = mappings.get(oldMapping2.key()); + if(mapping1 != null && mapping2 != null && + ! mapping1.group.equals(mapping2.group)) + { + groupShownToBeInvalid = true; + } + } + } + if(groupShownToBeInvalid) { + oldMappings.breakGroup(oldGroup); + } + } + + // Add new links + for(Integer group : mappings.groups()) { + Set matchingOldGroups = Sets.newTreeSet(); + for(Mapping mapping : mappings.group(group)) { + Mapping oldMapping = oldMappings.get(mapping.key()); + if(oldMapping != null) { + matchingOldGroups.add(oldMapping.group); + } + } + oldMappings.combineGroups(matchingOldGroups.toArray(new Integer[]{})); + } + + // Apply calculated groupings to original name mappings. + for(NameMapping nameMapping : nameMappings) { + nameMapping.setGroup( + oldMappings.get( + new Mapping(nameMapping).key()) + .group); + } + } +} diff --git a/src/org/egonet/wholenet/io/NameMappingWriter.java b/src/main/java/org/egonet/wholenet/io/NameMappingWriter.java similarity index 96% rename from src/org/egonet/wholenet/io/NameMappingWriter.java rename to src/main/java/org/egonet/wholenet/io/NameMappingWriter.java index 4a216b0..6bb552b 100644 --- a/src/org/egonet/wholenet/io/NameMappingWriter.java +++ b/src/main/java/org/egonet/wholenet/io/NameMappingWriter.java @@ -1,40 +1,40 @@ -package org.egonet.wholenet.io; - -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; - -import org.egonet.wholenet.gui.NameMapperFrame; - -import au.com.bytecode.opencsv.CSVWriter; - -public class NameMappingWriter { - - private final Iterable nameMappings; - - public NameMappingWriter(Iterable nameMappings) { - this.nameMappings = nameMappings; - } - - public void writeToFile(File file) throws IOException { - FileWriter fw = new FileWriter(file); - CSVWriter csv = new CSVWriter(fw); - - csv.writeNext(new String[]{ - "ego_name","unused","alter_number","alter_name","group"}); - - for(NameMapperFrame.NameMapping mapping : nameMappings) { - String name = mapping.getInterview().getIntName(); - csv.writeNext(new String[]{ - name, - "", - mapping.getAlterNumber()+"", - mapping.toString(), // alter name - mapping.getGroup()+"" - }); - } - - csv.flush(); - fw.close(); - } -} +package org.egonet.wholenet.io; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; + +import org.egonet.wholenet.gui.NameMapperFrame; + +import au.com.bytecode.opencsv.CSVWriter; + +public class NameMappingWriter { + + private final Iterable nameMappings; + + public NameMappingWriter(Iterable nameMappings) { + this.nameMappings = nameMappings; + } + + public void writeToFile(File file) throws IOException { + FileWriter fw = new FileWriter(file); + CSVWriter csv = new CSVWriter(fw); + + csv.writeNext(new String[]{ + "ego_name","unused","alter_number","alter_name","group"}); + + for(NameMapperFrame.NameMapping mapping : nameMappings) { + String name = mapping.getInterview().getIntName(); + csv.writeNext(new String[]{ + name, + "", + mapping.getAlterNumber()+"", + mapping.toString(), // alter name + mapping.getGroup()+"" + }); + } + + csv.flush(); + fw.close(); + } +} diff --git a/test/org/egonet/test/graph/GraphTest.java b/src/test/java/org/egonet/test/graph/GraphTest.java similarity index 96% rename from test/org/egonet/test/graph/GraphTest.java rename to src/test/java/org/egonet/test/graph/GraphTest.java index ea7a7d4..5463aef 100644 --- a/test/org/egonet/test/graph/GraphTest.java +++ b/src/test/java/org/egonet/test/graph/GraphTest.java @@ -1,34 +1,34 @@ -package org.egonet.test.graph; - -import static org.junit.Assert.*; - -import java.util.Random; - -import org.egonet.graph.Graph; -import org.junit.*; -import junit.framework.JUnit4TestAdapter; - -public class GraphTest { - - private Random rand = new Random(); - - @Test - public void testRandom() { - for(Integer i = 0; i < 60; i++) { - Double expectedDensity = rand.nextDouble(); - Graph graph = Graph.random(i, expectedDensity); - - assertEquals("Random graph of "+i+" nodes actually has "+i+" nodes.", - i.intValue(),graph.nodes().size()); - Double calculatedDensity = graph.density(); - if(i > 50) { - assertEquals("Random graph with "+i+" nodes has requested density.", - expectedDensity,calculatedDensity,0.1); - } - } - } - - public static junit.framework.Test suite() { - return new JUnit4TestAdapter(GraphTest.class); - } -} +package org.egonet.test.graph; + +import static org.junit.Assert.*; + +import java.util.Random; + +import org.egonet.graph.Graph; +import org.junit.*; +import junit.framework.JUnit4TestAdapter; + +public class GraphTest { + + private Random rand = new Random(); + + @Test + public void testRandom() { + for(Integer i = 0; i < 60; i++) { + Double expectedDensity = rand.nextDouble(); + Graph graph = Graph.random(i, expectedDensity); + + assertEquals("Random graph of "+i+" nodes actually has "+i+" nodes.", + i.intValue(),graph.nodes().size()); + Double calculatedDensity = graph.density(); + if(i > 50) { + assertEquals("Random graph with "+i+" nodes has requested density.", + expectedDensity,calculatedDensity,0.1); + } + } + } + + public static junit.framework.Test suite() { + return new JUnit4TestAdapter(GraphTest.class); + } +} diff --git a/test/org/egonet/test/graph/IndexedSetOfSetsTest.java b/src/test/java/org/egonet/test/graph/IndexedSetOfSetsTest.java similarity index 96% rename from test/org/egonet/test/graph/IndexedSetOfSetsTest.java rename to src/test/java/org/egonet/test/graph/IndexedSetOfSetsTest.java index fc41504..dceb78b 100644 --- a/test/org/egonet/test/graph/IndexedSetOfSetsTest.java +++ b/src/test/java/org/egonet/test/graph/IndexedSetOfSetsTest.java @@ -1,142 +1,142 @@ -package org.egonet.test.graph; - -import static org.junit.Assert.*; - -import java.util.Set; - -import org.junit.*; -import junit.framework.JUnit4TestAdapter; - -import org.egonet.graph.IndexedSetOfSets; - -import com.google.common.collect.Sets; - -public class IndexedSetOfSetsTest { - - private Set item1() { - Set item = Sets.newHashSet(); - item.add("a1"); - item.add("b1"); - item.add("c1"); - return item; - } - - private Set item2() { - Set item = Sets.newHashSet(); - item.add("a2"); - item.add("b2"); - item.add("c2"); - return item; - } - - private Set item3() { - Set item = Sets.newHashSet(); - item.add("a1"); - item.add("b1"); - item.add("c2"); - return item; - } - - private IndexedSetOfSets emptySet() { - IndexedSetOfSets set = new IndexedSetOfSets(); - return set; - } - - private IndexedSetOfSets set1() { - IndexedSetOfSets set = new IndexedSetOfSets(); - set.add(item1()); - return set; - } - - private IndexedSetOfSets set2() { - IndexedSetOfSets set = new IndexedSetOfSets(); - set.add(item2()); - return set; - } - - private IndexedSetOfSets set12() { - IndexedSetOfSets set = new IndexedSetOfSets(); - set.add(item1()); - set.add(item2()); - return set; - } - - private IndexedSetOfSets set21() { - IndexedSetOfSets set = new IndexedSetOfSets(); - set.add(item2()); - set.add(item1()); - return set; - } - - private IndexedSetOfSets set13() { - IndexedSetOfSets set = new IndexedSetOfSets(); - set.add(item1()); - set.add(item3()); - return set; - } - - private IndexedSetOfSets set123() { - IndexedSetOfSets set = new IndexedSetOfSets(); - set.add(item1()); - set.add(item2()); - set.add(item3()); - return set; - } - - @Test - public void testAdd() { - assertFalse("Adding an item to a set changes the set.", - emptySet().equals(set1())); - assertFalse("Adding another item to a set changes the set.", - set1().equals(set12())); - assertEquals("Order of adding does not matter.", - set12(), set21()); - } - - @Test - public void testContains() { - assertTrue("A set contains the item placed in it.", - set1().contains(item1())); - assertTrue("A larger set contains the first item placed in it.", - set12().contains(item1())); - assertTrue("A larger set contains the second item placed in it.", - set12().contains(item2())); - assertFalse("A set does not contain an item that was not placed in it.", - set1().contains(item2())); - } - - @Test - public void testRemove() { - IndexedSetOfSets set12minus2 = set12(); - set12minus2.remove(item2()); - assertEquals("Remove is the inverse of add.", - set12minus2,set1()); - - IndexedSetOfSets set12minus1 = set12(); - set12minus1.remove(item1()); - assertEquals("Remove is the inverse of add.", - set12minus1,set2()); - - IndexedSetOfSets set12minus1and2 = set12(); - set12minus1and2.remove(item1()); - set12minus1and2.remove(item2()); - assertEquals("Remove is the inverse of add.", - set12minus1and2,emptySet()); - } - - @Test - public void testFindByIndex() { - assertEquals("findByIndex returns empty set when used on empty set.", - emptySet(),emptySet().findByIndex("a1")); - assertEquals("findByIndex returns empty set when no relevant sets available.", - emptySet(),set13().findByIndex("a2")); - assertEquals("findByIndex finds the matching set.", - set1(),set12().findByIndex("a1")); - assertEquals("findByIndex can find more than one result.", - set13(),set123().findByIndex("b1")); - } - - public static junit.framework.Test suite() { - return new JUnit4TestAdapter(IndexedSetOfSetsTest.class); - } -} +package org.egonet.test.graph; + +import static org.junit.Assert.*; + +import java.util.Set; + +import org.junit.*; +import junit.framework.JUnit4TestAdapter; + +import org.egonet.graph.IndexedSetOfSets; + +import com.google.common.collect.Sets; + +public class IndexedSetOfSetsTest { + + private Set item1() { + Set item = Sets.newHashSet(); + item.add("a1"); + item.add("b1"); + item.add("c1"); + return item; + } + + private Set item2() { + Set item = Sets.newHashSet(); + item.add("a2"); + item.add("b2"); + item.add("c2"); + return item; + } + + private Set item3() { + Set item = Sets.newHashSet(); + item.add("a1"); + item.add("b1"); + item.add("c2"); + return item; + } + + private IndexedSetOfSets emptySet() { + IndexedSetOfSets set = new IndexedSetOfSets(); + return set; + } + + private IndexedSetOfSets set1() { + IndexedSetOfSets set = new IndexedSetOfSets(); + set.add(item1()); + return set; + } + + private IndexedSetOfSets set2() { + IndexedSetOfSets set = new IndexedSetOfSets(); + set.add(item2()); + return set; + } + + private IndexedSetOfSets set12() { + IndexedSetOfSets set = new IndexedSetOfSets(); + set.add(item1()); + set.add(item2()); + return set; + } + + private IndexedSetOfSets set21() { + IndexedSetOfSets set = new IndexedSetOfSets(); + set.add(item2()); + set.add(item1()); + return set; + } + + private IndexedSetOfSets set13() { + IndexedSetOfSets set = new IndexedSetOfSets(); + set.add(item1()); + set.add(item3()); + return set; + } + + private IndexedSetOfSets set123() { + IndexedSetOfSets set = new IndexedSetOfSets(); + set.add(item1()); + set.add(item2()); + set.add(item3()); + return set; + } + + @Test + public void testAdd() { + assertFalse("Adding an item to a set changes the set.", + emptySet().equals(set1())); + assertFalse("Adding another item to a set changes the set.", + set1().equals(set12())); + assertEquals("Order of adding does not matter.", + set12(), set21()); + } + + @Test + public void testContains() { + assertTrue("A set contains the item placed in it.", + set1().contains(item1())); + assertTrue("A larger set contains the first item placed in it.", + set12().contains(item1())); + assertTrue("A larger set contains the second item placed in it.", + set12().contains(item2())); + assertFalse("A set does not contain an item that was not placed in it.", + set1().contains(item2())); + } + + @Test + public void testRemove() { + IndexedSetOfSets set12minus2 = set12(); + set12minus2.remove(item2()); + assertEquals("Remove is the inverse of add.", + set12minus2,set1()); + + IndexedSetOfSets set12minus1 = set12(); + set12minus1.remove(item1()); + assertEquals("Remove is the inverse of add.", + set12minus1,set2()); + + IndexedSetOfSets set12minus1and2 = set12(); + set12minus1and2.remove(item1()); + set12minus1and2.remove(item2()); + assertEquals("Remove is the inverse of add.", + set12minus1and2,emptySet()); + } + + @Test + public void testFindByIndex() { + assertEquals("findByIndex returns empty set when used on empty set.", + emptySet(),emptySet().findByIndex("a1")); + assertEquals("findByIndex returns empty set when no relevant sets available.", + emptySet(),set13().findByIndex("a2")); + assertEquals("findByIndex finds the matching set.", + set1(),set12().findByIndex("a1")); + assertEquals("findByIndex can find more than one result.", + set13(),set123().findByIndex("b1")); + } + + public static junit.framework.Test suite() { + return new JUnit4TestAdapter(IndexedSetOfSetsTest.class); + } +} diff --git a/test/org/egonet/test/graph/KPlexesTest.java b/src/test/java/org/egonet/test/graph/KPlexesTest.java similarity index 96% rename from test/org/egonet/test/graph/KPlexesTest.java rename to src/test/java/org/egonet/test/graph/KPlexesTest.java index 1a54711..3d4a000 100644 --- a/test/org/egonet/test/graph/KPlexesTest.java +++ b/src/test/java/org/egonet/test/graph/KPlexesTest.java @@ -1,134 +1,134 @@ -package org.egonet.test.graph; - -import static org.junit.Assert.*; - -import java.util.Map; -import java.util.Random; -import java.util.Set; - -import org.egonet.graph.KPlexes; -import org.junit.*; - -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; - -import junit.framework.JUnit4TestAdapter; - -public class KPlexesTest { - - protected Random rand = new Random(); - private KPlexes kp = new KPlexes(); - - private Map> graphWithThreeCliques() { - Map> res = Maps.newHashMap(); - Set one = Sets.newHashSet(2,3,8); - Set two = Sets.newHashSet(1,3,4); - Set three = Sets.newHashSet(1,2,4,5); - Set four = Sets.newHashSet(2,3); - Set five = Sets.newHashSet(3,6,7); - Set six = Sets.newHashSet(5,7); - Set seven = Sets.newHashSet(5,6); - Set eight = Sets.newHashSet(1,9); - Set nine = Sets.newHashSet(8); - res.put(1,one); - res.put(2,two); - res.put(3,three); - res.put(4,four); - res.put(5,five); - res.put(6,six); - res.put(7,seven); - res.put(8,eight); - res.put(9,nine); - return res; - } - - private Set intSet(Integer... members) { - return Sets.newHashSet(members); - } - - @Test - public void testConnectionsByNode() { - Map calculations = - kp.connectionsByNode(graphWithThreeCliques()); - Integer[] answers = new Integer[]{3,3,4,2,3,2,2,2,1}; - for(Integer i = 0; i < answers.length; i++) { - Integer node = i+1; - Integer answer = answers[i]; - Integer calculated = calculations.get(node); - assertEquals(node+" has "+answer+" connections", - answer,calculated); - } - } - - @Test - public void testConnectednessByNode() { - Map calculations = - kp.connectednessByNode(graphWithThreeCliques()); - Integer[] answers = new Integer[]{2,2,3,2,2,2,2,1,1}; - for(Integer i = 0; i < answers.length; i++) { - Integer node = i+1; - Integer answer = answers[i]; - Integer calculated = calculations.get(node); - assertEquals(node+" has connectedness of "+answer, - answer,calculated); - } - } - - @Test - public void testConnectionsWithinSubgroup() { - Map cons = - kp.connectionsWithinSubgroup(graphWithThreeCliques(), intSet(1,2,3,4)); - Integer[] answers = new Integer[]{2,3,3,2,1,0,0,1,0}; - for(Integer i = 0; i < answers.length; i++) { - Integer node = i+1; - Integer answer = answers[i]; - Integer calculated = cons.get(node); - assertEquals(node+" is connected to "+answer+" members of {1,2,3,4}", - answer,calculated); - } - } - - @Test - public void testCriticalNodes() { - assertEquals("All nodes are critical in a 1-plex.", - intSet(7), - kp.criticalNodesInKPlex( - graphWithThreeCliques(), - intSet(7), - 1)); - } - - @Test - public void testSubgraphBoundingFinalKPlex() { - Set finalKPlex = intSet(5,6,7); - Map> subgraph = - kp.subgraphBoundingFinalKPlex(graphWithThreeCliques(), intSet(7), 1, 3); - Set boundsKPlex = subgraph.keySet(); - assertTrue(boundsKPlex+" should bound "+finalKPlex+" (full graph is "+subgraph+")", - boundsKPlex.containsAll(finalKPlex)); - } - - @Test - public void testGrowClique() { - Set clique = kp.growKPlex(graphWithThreeCliques(), intSet(7), 1, 3); - assertEquals("Expect {7} to grow into 1-plex of {5,6,7}.", - intSet(5,6,7),clique); - } - - @Test - public void testCliqueSearch() { - Set clique = kp.findLargeKPlex(graphWithThreeCliques(), 1); - assertEquals("Find a clique of size three, because all three cliques have size three.", - 3,clique.size()); - } - - @Test - public void testKPlexSearch() { - assertEquals("Find a 2-plex of size 4.", - intSet(1,2,3,4),kp.findLargeKPlex(graphWithThreeCliques(), 2)); - } - - public static junit.framework.Test suite() { - return new JUnit4TestAdapter(KPlexesTest.class); - } -} +package org.egonet.test.graph; + +import static org.junit.Assert.*; + +import java.util.Map; +import java.util.Random; +import java.util.Set; + +import org.egonet.graph.KPlexes; +import org.junit.*; + +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; + +import junit.framework.JUnit4TestAdapter; + +public class KPlexesTest { + + protected Random rand = new Random(); + private KPlexes kp = new KPlexes(); + + private Map> graphWithThreeCliques() { + Map> res = Maps.newHashMap(); + Set one = Sets.newHashSet(2,3,8); + Set two = Sets.newHashSet(1,3,4); + Set three = Sets.newHashSet(1,2,4,5); + Set four = Sets.newHashSet(2,3); + Set five = Sets.newHashSet(3,6,7); + Set six = Sets.newHashSet(5,7); + Set seven = Sets.newHashSet(5,6); + Set eight = Sets.newHashSet(1,9); + Set nine = Sets.newHashSet(8); + res.put(1,one); + res.put(2,two); + res.put(3,three); + res.put(4,four); + res.put(5,five); + res.put(6,six); + res.put(7,seven); + res.put(8,eight); + res.put(9,nine); + return res; + } + + private Set intSet(Integer... members) { + return Sets.newHashSet(members); + } + + @Test + public void testConnectionsByNode() { + Map calculations = + kp.connectionsByNode(graphWithThreeCliques()); + Integer[] answers = new Integer[]{3,3,4,2,3,2,2,2,1}; + for(Integer i = 0; i < answers.length; i++) { + Integer node = i+1; + Integer answer = answers[i]; + Integer calculated = calculations.get(node); + assertEquals(node+" has "+answer+" connections", + answer,calculated); + } + } + + @Test + public void testConnectednessByNode() { + Map calculations = + kp.connectednessByNode(graphWithThreeCliques()); + Integer[] answers = new Integer[]{2,2,3,2,2,2,2,1,1}; + for(Integer i = 0; i < answers.length; i++) { + Integer node = i+1; + Integer answer = answers[i]; + Integer calculated = calculations.get(node); + assertEquals(node+" has connectedness of "+answer, + answer,calculated); + } + } + + @Test + public void testConnectionsWithinSubgroup() { + Map cons = + kp.connectionsWithinSubgroup(graphWithThreeCliques(), intSet(1,2,3,4)); + Integer[] answers = new Integer[]{2,3,3,2,1,0,0,1,0}; + for(Integer i = 0; i < answers.length; i++) { + Integer node = i+1; + Integer answer = answers[i]; + Integer calculated = cons.get(node); + assertEquals(node+" is connected to "+answer+" members of {1,2,3,4}", + answer,calculated); + } + } + + @Test + public void testCriticalNodes() { + assertEquals("All nodes are critical in a 1-plex.", + intSet(7), + kp.criticalNodesInKPlex( + graphWithThreeCliques(), + intSet(7), + 1)); + } + + @Test + public void testSubgraphBoundingFinalKPlex() { + Set finalKPlex = intSet(5,6,7); + Map> subgraph = + kp.subgraphBoundingFinalKPlex(graphWithThreeCliques(), intSet(7), 1, 3); + Set boundsKPlex = subgraph.keySet(); + assertTrue(boundsKPlex+" should bound "+finalKPlex+" (full graph is "+subgraph+")", + boundsKPlex.containsAll(finalKPlex)); + } + + @Test + public void testGrowClique() { + Set clique = kp.growKPlex(graphWithThreeCliques(), intSet(7), 1, 3); + assertEquals("Expect {7} to grow into 1-plex of {5,6,7}.", + intSet(5,6,7),clique); + } + + @Test + public void testCliqueSearch() { + Set clique = kp.findLargeKPlex(graphWithThreeCliques(), 1); + assertEquals("Find a clique of size three, because all three cliques have size three.", + 3,clique.size()); + } + + @Test + public void testKPlexSearch() { + assertEquals("Find a 2-plex of size 4.", + intSet(1,2,3,4),kp.findLargeKPlex(graphWithThreeCliques(), 2)); + } + + public static junit.framework.Test suite() { + return new JUnit4TestAdapter(KPlexesTest.class); + } +} diff --git a/test/org/egonet/test/graph/KPlexesTwoModeTest.java b/src/test/java/org/egonet/test/graph/KPlexesTwoModeTest.java similarity index 96% rename from test/org/egonet/test/graph/KPlexesTwoModeTest.java rename to src/test/java/org/egonet/test/graph/KPlexesTwoModeTest.java index 2f8f544..31ff0a3 100644 --- a/test/org/egonet/test/graph/KPlexesTwoModeTest.java +++ b/src/test/java/org/egonet/test/graph/KPlexesTwoModeTest.java @@ -1,243 +1,243 @@ -package org.egonet.test.graph; - -import static org.junit.Assert.*; - -import java.util.List; -import java.util.Map; -import java.util.Random; -import java.util.Set; - -import net.sf.functionalj.tuple.Pair; - -import org.egonet.graph.KPlexesTwoMode; -import org.junit.*; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; - -import junit.framework.JUnit4TestAdapter; - -public class KPlexesTwoModeTest { - - protected Random rand = new Random(); - private KPlexesTwoMode kp = new KPlexesTwoMode(); - - private Set intSet(Integer... members) { - return Sets.newHashSet(members); - } - - private Pair> intGraphItem(Integer member, Integer... connections) { - return new Pair>(member,intSet(connections)); - } - - private Map> intGraph(Pair>... members) { - Map> result = Maps.newHashMap(); - for(Pair> member : members) { - result.put(member.getFirst(), member.getSecond()); - } - return result; - } - - @SuppressWarnings("unchecked") - private Map> exampleGraph() { - return intGraph( - intGraphItem(1, 7,8,9,10), - intGraphItem(2, 10), - intGraphItem(3, 7,9,10), - intGraphItem(4, 6,7,10), - intGraphItem(5, 6), - intGraphItem(6, 4,5), - intGraphItem(7, 1,3,4), - intGraphItem(8, 1), - intGraphItem(9, 1,3), - intGraphItem(10, 1,2,3,4)); - } - private Set exampleMode1() { - return intSet(1,2,3,4,5); - } - private List> exampleLargestCliques() { - List> results = Lists.newArrayList(); - results.add(intSet(1,3,4,7,10)); - results.add(intSet(1,3,7,9,10)); - return results; - } - - @SuppressWarnings("unchecked") - private Map> example2Graph() { - return intGraph( - intGraphItem(1, 6,7,8,9,10), - intGraphItem(2, 6,7,8, 10), - intGraphItem(3, 6,7,8, 10), - intGraphItem(4, 6,7,8,9,10), - intGraphItem(5, 6,7, 9,10), - intGraphItem(6, 1,2,3,4,5), - intGraphItem(7, 1,2,3,4,5), - intGraphItem(8, 1,2,3,4 ), - intGraphItem(9, 1, 4,5), - intGraphItem(10, 1,2,3,4,5)); - } - private Set example2Mode1() { - return intSet(1,2,3,4,5); - } - private Set example2OnePlex() { - return intSet(1,2,3,4,5,6,7,8,10); - } - public Integer example2outlier() { - return 9; - } - - @Test - public void testConnectionsByNode() { - Map calculations = - kp.connectionsByNode(exampleGraph()); - Integer[] answers = new Integer[]{4,1,3,3,1,2,3,1,2,4}; - for(Integer i = 0; i < answers.length; i++) { - Integer node = i+1; - Integer answer = answers[i]; - Integer calculated = calculations.get(node); - assertEquals(node+" has "+answer+" connections", - answer,calculated); - } - } - - @Test - public void testConnectednessByNode() { - Map calculations = - kp.connectednessByNode(exampleGraph()); - Integer[] answers = new Integer[]{2,1,2,2,1,1,3,1,2,3}; - for(Integer i = 0; i < answers.length; i++) { - Integer node = i+1; - Integer answer = answers[i]; - Integer calculated = calculations.get(node); - assertEquals(node+" has connectedness of "+answer, - answer,calculated); - } - } - - @Test - public void testConnectionsWithinSubgroup() { - Map cons = - kp.connectionsWithinSubgroup(exampleGraph(), intSet(1,4,7,10)); - Integer[] answers = new Integer[]{2,1,2,2,0,1,2,1,1,2}; - for(Integer i = 0; i < answers.length; i++) { - Integer node = i+1; - Integer answer = answers[i]; - Integer calculated = cons.get(node); - assertEquals(node+" is connected to "+answer+" members of {1,4,7,10}", - answer,calculated); - } - } - - @Test - public void testMeetConnectednessThreshold() { - Set kPlex = intSet(1,3,4,7,9,10); - Set notConnectedEnough = - Sets.difference(kPlex, kp.meetConnectednessThreshold(exampleGraph(), 1, 3)); - assertTrue("Members of 1-plex are sufficiently connected to be in 1-plex. " + - "So why did these fail: "+notConnectedEnough, - notConnectedEnough.isEmpty()); - } - - @Test - public void testCriticalNodes() { - assertEquals("All nodes are critical in a 1-plex.", - intSet(7), - kp.criticalNodesInKPlex( - exampleGraph(), - exampleMode1(), - intSet(7), - 0)); - Set clique = intSet(1,3,7,9,10); - assertEquals("All nodes are critical in a 1-plex.", - clique, - kp.criticalNodesInKPlex( - exampleGraph(), - exampleMode1(), - clique, - 0)); - } - - @Test - public void testNodesThatCanBeAddedToKPlex() { - assertEquals("No more nodes can be added to a clique.", - intSet(), - kp.nodesThatCanBeAddedToKPlex( - exampleGraph(), - exampleMode1(), - intSet(1,3,7,9,10), - 0)); - Set kPlex = intSet(1,3,4,7,9,10); - - for(Integer i : kPlex) { - Set canBeAdded = - kp.nodesThatCanBeAddedToKPlex(exampleGraph(), exampleMode1(), intSet(i), 1); - Set nonAddableMembers = Sets.difference(kPlex, Sets.union(canBeAdded,intSet(i))); - assertTrue(nonAddableMembers+" can't be added to "+i+" but are part of same 1-plex "+kPlex, - nonAddableMembers.isEmpty()); - } - assertEquals("Can't add one more element to 1-plex "+example2OnePlex()+" in graph "+example2Graph(), - intSet(),kp.nodesThatCanBeAddedToKPlex(example2Graph(), example2Mode1(), example2OnePlex(), 1)); - } - - @Test - public void testSubgraphBoundingFinalClique() { - Set finalKPlex = intSet(1,4,7,10); - Map> subgraph = - kp.subgraphBoundingFinalKPlex(exampleGraph(), exampleMode1(), intSet(1), 0, 2); - Set boundsKPlex = subgraph.keySet(); - assertTrue(boundsKPlex+" should bound "+finalKPlex+" (full graph is "+subgraph+")", - boundsKPlex.containsAll(finalKPlex)); - } - @Test - public void testSubgraphBoundingFinalKPlex() { - Set finalKPlex = intSet(1,3,4,7,9,10); - for(Integer i : finalKPlex) { - Map> subgraph = - kp.subgraphBoundingFinalKPlex(exampleGraph(), exampleMode1(), intSet(i), 1, 3); - Set boundsKPlex = subgraph.keySet(); - assertTrue(boundsKPlex+" grown from "+i+" should bound "+finalKPlex, - boundsKPlex.containsAll(finalKPlex)); - } - } - - @Test - public void testGrowClique() { - Set clique = kp.growKPlex(exampleGraph(), exampleMode1(), intSet(4), 0, 2); - assertTrue( - "Expected {7} to grow into one of the two largest cliques, but got " - +clique+" instead.", - exampleLargestCliques().contains(clique)); - Set seed = intSet(3,4,7,10); - Set expected = intSet(1,3,4,7,9,10); - Set onePlex = kp.growKPlex(exampleGraph(), exampleMode1(), seed, 1, 3); - assertEquals("Expected "+seed+" to grow into large 1-plex "+expected+ - " but got "+onePlex+" instead.", - expected,onePlex); - } - - @Test - public void testCliqueSearch() { - Set clique = kp.findLargeKPlex(exampleGraph(), exampleMode1(), 0); - assertTrue("Expected this to be one of the largest cliques: "+clique, - exampleLargestCliques().contains(clique)); - } - - @Test - public void testKPlexSearch() { - assertEquals("Looks like the largest 1-plex is {1,3,4,7,9,10}.", - intSet(1,3,4,7,9,10),kp.findLargeKPlex(exampleGraph(), exampleMode1(), 1)); - } - - @Test - public void testMaxMissingEdgesPerNodeInSubgroup() { - assertEquals("Known 1-plex has at most one missing edge per node", - 1, - kp.maxMissingEdgesPerNodeInSubgroup(exampleGraph(),exampleMode1(), - intSet(1,3,4,7,9,10)).intValue()); - } - - public static junit.framework.Test suite() { - return new JUnit4TestAdapter(KPlexesTwoModeTest.class); - } -} +package org.egonet.test.graph; + +import static org.junit.Assert.*; + +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.Set; + +import net.sf.functionalj.tuple.Pair; + +import org.egonet.graph.KPlexesTwoMode; +import org.junit.*; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; + +import junit.framework.JUnit4TestAdapter; + +public class KPlexesTwoModeTest { + + protected Random rand = new Random(); + private KPlexesTwoMode kp = new KPlexesTwoMode(); + + private Set intSet(Integer... members) { + return Sets.newHashSet(members); + } + + private Pair> intGraphItem(Integer member, Integer... connections) { + return new Pair>(member,intSet(connections)); + } + + private Map> intGraph(Pair>... members) { + Map> result = Maps.newHashMap(); + for(Pair> member : members) { + result.put(member.getFirst(), member.getSecond()); + } + return result; + } + + @SuppressWarnings("unchecked") + private Map> exampleGraph() { + return intGraph( + intGraphItem(1, 7,8,9,10), + intGraphItem(2, 10), + intGraphItem(3, 7,9,10), + intGraphItem(4, 6,7,10), + intGraphItem(5, 6), + intGraphItem(6, 4,5), + intGraphItem(7, 1,3,4), + intGraphItem(8, 1), + intGraphItem(9, 1,3), + intGraphItem(10, 1,2,3,4)); + } + private Set exampleMode1() { + return intSet(1,2,3,4,5); + } + private List> exampleLargestCliques() { + List> results = Lists.newArrayList(); + results.add(intSet(1,3,4,7,10)); + results.add(intSet(1,3,7,9,10)); + return results; + } + + @SuppressWarnings("unchecked") + private Map> example2Graph() { + return intGraph( + intGraphItem(1, 6,7,8,9,10), + intGraphItem(2, 6,7,8, 10), + intGraphItem(3, 6,7,8, 10), + intGraphItem(4, 6,7,8,9,10), + intGraphItem(5, 6,7, 9,10), + intGraphItem(6, 1,2,3,4,5), + intGraphItem(7, 1,2,3,4,5), + intGraphItem(8, 1,2,3,4 ), + intGraphItem(9, 1, 4,5), + intGraphItem(10, 1,2,3,4,5)); + } + private Set example2Mode1() { + return intSet(1,2,3,4,5); + } + private Set example2OnePlex() { + return intSet(1,2,3,4,5,6,7,8,10); + } + public Integer example2outlier() { + return 9; + } + + @Test + public void testConnectionsByNode() { + Map calculations = + kp.connectionsByNode(exampleGraph()); + Integer[] answers = new Integer[]{4,1,3,3,1,2,3,1,2,4}; + for(Integer i = 0; i < answers.length; i++) { + Integer node = i+1; + Integer answer = answers[i]; + Integer calculated = calculations.get(node); + assertEquals(node+" has "+answer+" connections", + answer,calculated); + } + } + + @Test + public void testConnectednessByNode() { + Map calculations = + kp.connectednessByNode(exampleGraph()); + Integer[] answers = new Integer[]{2,1,2,2,1,1,3,1,2,3}; + for(Integer i = 0; i < answers.length; i++) { + Integer node = i+1; + Integer answer = answers[i]; + Integer calculated = calculations.get(node); + assertEquals(node+" has connectedness of "+answer, + answer,calculated); + } + } + + @Test + public void testConnectionsWithinSubgroup() { + Map cons = + kp.connectionsWithinSubgroup(exampleGraph(), intSet(1,4,7,10)); + Integer[] answers = new Integer[]{2,1,2,2,0,1,2,1,1,2}; + for(Integer i = 0; i < answers.length; i++) { + Integer node = i+1; + Integer answer = answers[i]; + Integer calculated = cons.get(node); + assertEquals(node+" is connected to "+answer+" members of {1,4,7,10}", + answer,calculated); + } + } + + @Test + public void testMeetConnectednessThreshold() { + Set kPlex = intSet(1,3,4,7,9,10); + Set notConnectedEnough = + Sets.difference(kPlex, kp.meetConnectednessThreshold(exampleGraph(), 1, 3)); + assertTrue("Members of 1-plex are sufficiently connected to be in 1-plex. " + + "So why did these fail: "+notConnectedEnough, + notConnectedEnough.isEmpty()); + } + + @Test + public void testCriticalNodes() { + assertEquals("All nodes are critical in a 1-plex.", + intSet(7), + kp.criticalNodesInKPlex( + exampleGraph(), + exampleMode1(), + intSet(7), + 0)); + Set clique = intSet(1,3,7,9,10); + assertEquals("All nodes are critical in a 1-plex.", + clique, + kp.criticalNodesInKPlex( + exampleGraph(), + exampleMode1(), + clique, + 0)); + } + + @Test + public void testNodesThatCanBeAddedToKPlex() { + assertEquals("No more nodes can be added to a clique.", + intSet(), + kp.nodesThatCanBeAddedToKPlex( + exampleGraph(), + exampleMode1(), + intSet(1,3,7,9,10), + 0)); + Set kPlex = intSet(1,3,4,7,9,10); + + for(Integer i : kPlex) { + Set canBeAdded = + kp.nodesThatCanBeAddedToKPlex(exampleGraph(), exampleMode1(), intSet(i), 1); + Set nonAddableMembers = Sets.difference(kPlex, Sets.union(canBeAdded,intSet(i))); + assertTrue(nonAddableMembers+" can't be added to "+i+" but are part of same 1-plex "+kPlex, + nonAddableMembers.isEmpty()); + } + assertEquals("Can't add one more element to 1-plex "+example2OnePlex()+" in graph "+example2Graph(), + intSet(),kp.nodesThatCanBeAddedToKPlex(example2Graph(), example2Mode1(), example2OnePlex(), 1)); + } + + @Test + public void testSubgraphBoundingFinalClique() { + Set finalKPlex = intSet(1,4,7,10); + Map> subgraph = + kp.subgraphBoundingFinalKPlex(exampleGraph(), exampleMode1(), intSet(1), 0, 2); + Set boundsKPlex = subgraph.keySet(); + assertTrue(boundsKPlex+" should bound "+finalKPlex+" (full graph is "+subgraph+")", + boundsKPlex.containsAll(finalKPlex)); + } + @Test + public void testSubgraphBoundingFinalKPlex() { + Set finalKPlex = intSet(1,3,4,7,9,10); + for(Integer i : finalKPlex) { + Map> subgraph = + kp.subgraphBoundingFinalKPlex(exampleGraph(), exampleMode1(), intSet(i), 1, 3); + Set boundsKPlex = subgraph.keySet(); + assertTrue(boundsKPlex+" grown from "+i+" should bound "+finalKPlex, + boundsKPlex.containsAll(finalKPlex)); + } + } + + @Test + public void testGrowClique() { + Set clique = kp.growKPlex(exampleGraph(), exampleMode1(), intSet(4), 0, 2); + assertTrue( + "Expected {7} to grow into one of the two largest cliques, but got " + +clique+" instead.", + exampleLargestCliques().contains(clique)); + Set seed = intSet(3,4,7,10); + Set expected = intSet(1,3,4,7,9,10); + Set onePlex = kp.growKPlex(exampleGraph(), exampleMode1(), seed, 1, 3); + assertEquals("Expected "+seed+" to grow into large 1-plex "+expected+ + " but got "+onePlex+" instead.", + expected,onePlex); + } + + @Test + public void testCliqueSearch() { + Set clique = kp.findLargeKPlex(exampleGraph(), exampleMode1(), 0); + assertTrue("Expected this to be one of the largest cliques: "+clique, + exampleLargestCliques().contains(clique)); + } + + @Test + public void testKPlexSearch() { + assertEquals("Looks like the largest 1-plex is {1,3,4,7,9,10}.", + intSet(1,3,4,7,9,10),kp.findLargeKPlex(exampleGraph(), exampleMode1(), 1)); + } + + @Test + public void testMaxMissingEdgesPerNodeInSubgroup() { + assertEquals("Known 1-plex has at most one missing edge per node", + 1, + kp.maxMissingEdgesPerNodeInSubgroup(exampleGraph(),exampleMode1(), + intSet(1,3,4,7,9,10)).intValue()); + } + + public static junit.framework.Test suite() { + return new JUnit4TestAdapter(KPlexesTwoModeTest.class); + } +} diff --git a/test/org/egonet/tests/functional/CombineInterviews.java b/src/test/java/org/egonet/tests/functional/CombineInterviews.java similarity index 100% rename from test/org/egonet/tests/functional/CombineInterviews.java rename to src/test/java/org/egonet/tests/functional/CombineInterviews.java diff --git a/test/org/egonet/tests/functional/CreatePdf.java b/src/test/java/org/egonet/tests/functional/CreatePdf.java similarity index 96% rename from test/org/egonet/tests/functional/CreatePdf.java rename to src/test/java/org/egonet/tests/functional/CreatePdf.java index 583a8c8..25b3e5b 100644 --- a/test/org/egonet/tests/functional/CreatePdf.java +++ b/src/test/java/org/egonet/tests/functional/CreatePdf.java @@ -1,37 +1,37 @@ -package org.egonet.tests.functional; - -import java.io.*; - -import org.egonet.io.InterviewReader; -import org.egonet.io.PDFWriter; -import org.egonet.io.StudyReader; - -import com.endlessloopsoftware.egonet.Interview; -import com.endlessloopsoftware.egonet.Study; - -public class CreatePdf { - - - /** - * @param args - */ - public static void main(String[] args) throws Exception { - StudyReader sr = new StudyReader(new File("C:/Documents and Settings/Martin/My Documents/EgoNet/EgoNet Study/Sample Study.ego")); - Study study = sr.getStudy(); - - File fInterview = new File("C:/Documents and Settings/Martin/My Documents/EgoNet/EgoNet Study/Interviews/martin_smith.int"); - InterviewReader ir = new InterviewReader(study, fInterview); - Interview interview = ir.getInterview(); - - String path = "C:/Documents and Settings/Martin/Desktop/"; - - File completeFile = new File(path+"complete.pdf"); - PDFWriter pdfWriter1 = new PDFWriter(study, interview); - pdfWriter1.write(completeFile); - - File incompleteFile = new File(path+"incomplete.pdf"); - PDFWriter pdfWriter2 = new PDFWriter(study, interview.getIntName()); - pdfWriter2.write(incompleteFile); - } - -} +package org.egonet.tests.functional; + +import java.io.*; + +import org.egonet.io.InterviewReader; +import org.egonet.io.PDFWriter; +import org.egonet.io.StudyReader; + +import com.endlessloopsoftware.egonet.Interview; +import com.endlessloopsoftware.egonet.Study; + +public class CreatePdf { + + + /** + * @param args + */ + public static void main(String[] args) throws Exception { + StudyReader sr = new StudyReader(new File("C:/Documents and Settings/Martin/My Documents/EgoNet/EgoNet Study/Sample Study.ego")); + Study study = sr.getStudy(); + + File fInterview = new File("C:/Documents and Settings/Martin/My Documents/EgoNet/EgoNet Study/Interviews/martin_smith.int"); + InterviewReader ir = new InterviewReader(study, fInterview); + Interview interview = ir.getInterview(); + + String path = "C:/Documents and Settings/Martin/Desktop/"; + + File completeFile = new File(path+"complete.pdf"); + PDFWriter pdfWriter1 = new PDFWriter(study, interview); + pdfWriter1.write(completeFile); + + File incompleteFile = new File(path+"incomplete.pdf"); + PDFWriter pdfWriter2 = new PDFWriter(study, interview.getIntName()); + pdfWriter2.write(incompleteFile); + } + +} diff --git a/test/org/egonet/tests/functional/DesignStudy.java b/src/test/java/org/egonet/tests/functional/DesignStudy.java similarity index 100% rename from test/org/egonet/tests/functional/DesignStudy.java rename to src/test/java/org/egonet/tests/functional/DesignStudy.java diff --git a/test/org/egonet/tests/functional/DoInterview.java b/src/test/java/org/egonet/tests/functional/DoInterview.java similarity index 100% rename from test/org/egonet/tests/functional/DoInterview.java rename to src/test/java/org/egonet/tests/functional/DoInterview.java diff --git a/winwrap.xml b/winwrap.xml index e6588cf..815e1d5 100644 --- a/winwrap.xml +++ b/winwrap.xml @@ -1,7 +1,7 @@ gui - dist/Egonet.exe - dist/Egonet.jar + target/scala-2.10/Egonet.exe + target/scala-2.10/egonet-assembly-0.1-SNAPSHOT.jar 1.6.0 256