/*** * Copyright (c) 2008, Endless Loop Software, Inc. * * This file is part of EgoNet. * * EgoNet is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * EgoNet is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.egonet.gui.author; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ItemEvent; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.util.ArrayList; 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.gui.interview.ClientQuestionPanel; import org.egonet.model.Shared; import org.egonet.model.answer.Answer; import org.egonet.model.answer.CategoricalAnswer; import org.egonet.model.answer.TextAnswer; import org.egonet.model.question.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Generic Panel creation and handling routines for question editing */ public class AuthoringQuestionPanel extends EgoQPanel { final private static Logger logger = LoggerFactory.getLogger(AuthoringQuestionPanel.class); private boolean inUpdate; private final JSplitPane question_split = new JSplitPane(); private final JList<Question> question_list = new JList<Question>(); 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_type_label = new JLabel("Question Type:"); private final JComboBox<Class<? extends Question>> question_type_menu = new JComboBox<Class<? extends Question>>(); private final JLabel question_answer_type_label = new JLabel("Answer Type:"); private final JButton question_answer_type_button = new JButton("Selections"); private final JLabel question_link_label = new JLabel("Question Link:"); private final JLabel question_link_field = new JLabel("None"); private final JLabel question_follows_label = new JLabel("Follows Question:"); private final JComboBox<Class<? extends Answer>> question_answer_type_menu = new JComboBox<Class<? extends Answer>>(Shared.answerClasses); private final JComboBox<Question> question_follows_menu = new JComboBox<Question>(); private final JLabel question_followup_only_label = new JLabel("Follow up protocols only:"); private final JCheckBox question_followup_only_combo = new JCheckBox(); 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 JButton question_duplicate_button = new JButton("Duplicate"); private final JButton question_link_button = new JButton("Set Link"); private final JButton question_delete_button = new JButton("Delete"); private final JLabel question_central_label = new JLabel(); private final CategoryInputPane selectionsDialog; private final QuestionLinkDialog questionLinkDialog; 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 AuthoringQuestionPanel(EgoNet egoNet, Class<? extends Question> type) throws Exception { super(type); this.egoNet = egoNet; DefaultComboBoxModel<Class<? extends Question>> model = new DefaultComboBoxModel<Class<? extends Question>>(); for(Class<? extends Question> qType : Shared.questionClasses) { if(qType.equals(StudyQuestion.class)) continue; model.addElement(qType); } question_type_menu.setModel(model); questionLinkDialog = new QuestionLinkDialog(egoNet); selectionsDialog = new CategoryInputPane(egoNet, question_list); question_title_field.setName("question_title_field"); question_question_field.setName("question_question_field"); question_citation_field.setName("question_citation_field"); question_answer_type_menu.setName("question_answer_type_menu"); 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(); } private Question getSelectedQuestion() { return (Question) question_list.getSelectedValue(); } /** * 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, 3, 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, 4, 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, 4, 2, 3, 0.0, 0.3, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(10, 10, 10, 10), 0, 0)); question_panel_right.add(question_type_label, new GridBagConstraints(0, 7, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(10, 10, 10, 10), 0, 0)); question_panel_right.add(question_type_menu, new GridBagConstraints(1, 7, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(10, 10, 10, 10), 0, 0)); question_panel_right.add(question_central_label, new GridBagConstraints(2, 7, 1, 1, 0.2, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(10, 10, 10, 10), 0, 0)); question_panel_right.add(question_answer_type_label, new GridBagConstraints(0, 8, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(10, 10, 10, 10), 0, 0)); question_panel_right.add(question_answer_type_menu, new GridBagConstraints(1, 8, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(10, 10, 10, 10), 0, 0)); question_panel_right.add(question_answer_type_button, new GridBagConstraints(2, 8, 1, 1, 0.2, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(10, 10, 10, 10), 0, 0)); question_panel_right.add(question_follows_label, new GridBagConstraints(0, 9, 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, 9, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(10, 10, 10, 10), 0, 0)); question_panel_right.add(question_followup_only_label, new GridBagConstraints(0, 13, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(10, 10, 10, 10), 0, 0)); question_panel_right.add(question_followup_only_combo, new GridBagConstraints(1, 13, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(10, 10, 10, 10), 0, 0)); question_panel_right.add(question_link_label, new GridBagConstraints(0, 10, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(10, 10, 10, 10), 0, 0)); question_panel_right.add(question_link_field, new GridBagConstraints(1, 10, 2, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(10, 10, 10, 10), 0, 0)); question_panel_right.add(question_new_button, new GridBagConstraints(0, 11, 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, 11, 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, 11, 1, 1, 0.33, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(10, 10, 10, 10), 0, 0)); question_panel_right.add(question_link_button, new GridBagConstraints(0, 12, 1, 1, 0.33, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(10, 10, 10, 10), 0, 0)); question_panel_right.add(question_duplicate_button, new GridBagConstraints(1, 12, 1, 1, 0.33, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(10, 10, 10, 10), 0, 0)); question_list.setModel(new DefaultListModel<Question>()); egoNet.getStudy().fillList(questionType, (DefaultListModel<Question>)question_list.getModel()); question_list.getSelectionModel().addListSelectionListener(new ListSelectionListener() { public void valueChanged(ListSelectionEvent e) { question_list_selectionChanged(e); } }); question_list.addKeyListener(new KeyAdapter() { public void keyPressed(KeyEvent ke){ // is anything selected if(question_list.getSelectedIndex() == -1) return; // did we see something that wasn't UP or DOWN if(ke.getKeyCode() != KeyEvent.VK_DOWN) return; // did it not have a "SHIFT" key int modifiersEx = ke.getModifiersEx(); String tmpString = KeyEvent.getModifiersExText(modifiersEx); if(!tmpString.contains("Shift")) return; // we got a shift-up or shift-down ke.consume(); Question q_old = (Question) question_list.getSelectedValue(); if (q_old == null) { JOptionPane.showMessageDialog(egoNet.getFrame(), "Select a question first!", "Dupe Question", JOptionPane.OK_OPTION); return; } Question q = (Question) question_list.getSelectedValue(); try { egoNet.getStudy().removeQuestion(q); egoNet.getStudy().addQuestion(q); egoNet.getStudy().setModified(true); } catch (Exception ex) { throw new RuntimeException(ex); } fillPanel(); } }); 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) { @SuppressWarnings("unchecked") Class<? extends Answer> answerType = (Class<? extends Answer>)question_answer_type_menu.getSelectedItem(); Question question = getSelectedQuestion(); ClientQuestionPanel.showPreview( question_title_field.getText(),question_question_field.getText(), questionType,answerType,question.getSelections()); } }); question_delete_button.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(ActionEvent e) { question_delete_button_actionPerformed(e); } }); question_duplicate_button.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(ActionEvent e) { question_duplicate_button_actionPerformed(e); } }); question_link_button.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(ActionEvent e) { question_link_button_actionPerformed(e); } }); question_follows_menu.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(ActionEvent e) { question_follows_menu_actionPerformed(e); } }); question_followup_only_combo.addItemListener(new java.awt.event.ItemListener() { @Override public void itemStateChanged(ItemEvent e) { question_followup_only_combo_actionPerformed(e); } }); question_type_menu.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(ActionEvent e) { question_type_menu_actionPerformed(e); } }); question_answer_type_menu.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(ActionEvent e) { question_answer_type_menu_actionPerformed(e); } }); question_answer_type_button.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(ActionEvent e) { set_selections_button_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(); } }); this.add(question_split, null); inUpdate = false; } /** * Updates right side question fields when the selection changes * * @param e event generated by selection change. */ private void question_list_selectionChanged(ListSelectionEvent e) { if (!e.getValueIsAdjusting()) { if (!inUpdate) { questionUpdate(); } } } /**** * fill List with appropriate questions Set other fields to selected * question */ public void fillPanel() { if (questionType == egoNet.getFrame().curTab) { storageUpdate(); questionUpdate(); } } /** * Called when file changes to load new questions into list */ private void storageUpdate() { inUpdate = true; if (questionType == egoNet.getFrame().curTab) { DefaultListModel<Question> listModel = ((DefaultListModel<Question>) question_list.getModel()); Object o = question_list.getSelectedValue(); int selectedIndex = question_list.getSelectedIndex(); listModel.removeAllElements(); egoNet.getStudy().fillList(questionType, (DefaultListModel<Question>) question_list.getModel()); /* Goal below is to stay near the previously selected element, somehow */ // if the previously selected element is still in the model if(listModel.contains(o)) { // select it question_list.setSelectedValue(o, true); } // if the index is still valid in the model else if(selectedIndex >= 0 && selectedIndex < listModel.getSize()){ // select it question_list.setSelectedIndex(selectedIndex); } // if the index-1 is still valid in the model else if(selectedIndex-1 >= 0 && selectedIndex-1 < listModel.getSize()){ question_list.setSelectedIndex(selectedIndex-1); } // if the index+1 is still valid in the model else if(selectedIndex+1 >= 0 && selectedIndex+1 < listModel.getSize()){ question_list.setSelectedIndex(selectedIndex+1); } logger.info("o is " + (o == null ? "": "NOT ") + "null, selectedIndex="+selectedIndex+", new selected index = "+question_list.getSelectedIndex()); } inUpdate = false; } private void questionUpdate() { Question q; int index; inUpdate = true; if (questionType == egoNet.getFrame().curTab) { /* If no element selected, assume first */ index = question_list.getSelectedIndex(); if ((index == -1) && (question_list.getModel().getSize() > 0)) { index = 0; } /* Load questions from list into follows menu */ 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); q = (Question) question_list.getSelectedValue(); if (q != null) { question_type_menu.setSelectedItem(questionType); question_answer_type_menu.setSelectedItem(q.answerType); question_question_field.setText(q.text); question_citation_field.setText(q.citation); question_title_field.setText(q.title); question_follows_menu.setSelectedIndex(index); question_followup_only_combo.setSelected(q.followupOnly); question_type_menu.setEnabled(true); question_answer_type_menu.setEnabled(!(q instanceof AlterPromptQuestion)); question_answer_type_button.setEnabled(q.answerType.equals(CategoricalAnswer.class)); question_question_field.setEditable(true); question_citation_field.setEditable(true); question_title_field.setEditable(true); question_delete_button.setEnabled(true); question_duplicate_button.setEnabled(true); question_link_button.setEnabled(true); /* Box only appears on alter pair page */ question_central_label.setVisible(false); if (q.answerType.equals(CategoricalAnswer.class)) { if (q.getSelections().size() == 0) { question_central_label.setText("No Selections"); question_central_label.setForeground(Color.red); question_central_label.setVisible(true); } else if (questionType == AlterPairQuestion.class) { question_central_label.setText("No Adjacency Selections"); question_central_label.setForeground(Color.red); for (int i = 0; i < q.getSelections().size(); i++) { if (q.getSelections().get(i).isAdjacent()) { question_central_label.setText("Adjacency Selections Set"); question_central_label.setForeground(Color.black); } } question_central_label.setVisible(true); } } /* Fill in link field */ if (q.link.isActive()) { Question linkQuestion = egoNet.getStudy().getQuestions().getQuestion(q.link.getAnswer().getQuestionId()); if (linkQuestion == null) { question_link_field.setText("< none >"); } else { if (linkQuestion.title.length() > 32) { question_link_field.setText(linkQuestion.title.substring(0, 32) + ": " + q.link.getAnswer().string); } else { question_link_field.setText(linkQuestion.title + ": " + q.link.getAnswer().string); } } } else { question_link_field.setText("< none >"); } } else { question_answer_type_menu.setSelectedIndex(0); question_question_field.setText(null); question_citation_field.setText(null); question_title_field.setText(null); question_central_label.setVisible(false); question_link_field.setText(""); question_type_menu.setEnabled(false); question_answer_type_menu.setEnabled(false); question_answer_type_button.setEnabled(false); question_question_field.setEditable(false); question_citation_field.setEditable(false); question_title_field.setEditable(false); question_delete_button.setEnabled(false); question_link_button.setEnabled(false); question_duplicate_button.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 */ 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 */ 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 */ 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); } } } /**** * Event handler for new question button * * @param e Action Event */ private void question_new_button_actionPerformed(ActionEvent e) { if (egoNet.getStudy().confirmIncompatibleChange(egoNet.getFrame())) { Question q = Question.newInstance(questionType); q.title = new String(Question.getNiceName(questionType) + ":Untitled Question"); if (q instanceof AlterPromptQuestion) { q.answerType = TextAnswer.class; } 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()); egoNet.getStudy().setModified(true); egoNet.getStudy().setCompatible(false); } } /**** * Event handler for delete question button * * @param e Action Event */ private 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().confirmIncompatibleChange(egoNet.getFrame())) { egoNet.getStudy().removeQuestion(q); egoNet.getStudy().setModified(true); egoNet.getStudy().setCompatible(false); fillPanel(); } } } /**** * Event handler for dupe question button * * @param e Action Event */ private void question_duplicate_button_actionPerformed(ActionEvent e) { Question q_old = (Question) question_list.getSelectedValue(); if (q_old == null) { JOptionPane.showMessageDialog(egoNet.getFrame(), "Select a question first!", "Dupe Question", JOptionPane.OK_OPTION); return; } if (egoNet.getStudy().confirmIncompatibleChange(egoNet.getFrame())) { Question q = Question.newInstance(q_old.getClass()); q.title = new String((Question.getNiceName(questionType)) + ": " + q_old.title + (q_old.title != null && q_old.title.endsWith("Duplicate Question") ? "" : " (Duplicate Question)")); q.answerType = q_old.answerType; q.citation = q_old.citation; q.setStatable(q_old.isStatable()); q.text = q_old.text; q.followupOnly = q_old.followupOnly; try { egoNet.getStudy().addQuestion(q); q.setSelections(new ArrayList<Selection>(q_old.getSelections())); } 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()); egoNet.getStudy().setModified(true); egoNet.getStudy().setCompatible(false); } } /** * Opens Set Link Dialog * * @param e UI event */ void question_link_button_actionPerformed(ActionEvent e) { Question q = (Question) question_list.getSelectedValue(); questionLinkDialog.pack(); questionLinkDialog.activate(q); } /** * Change question type in question record, move to new ordering list * * @param e UI event */ void question_type_menu_actionPerformed(ActionEvent e) { if (!inUpdate) { if (egoNet.getStudy().confirmIncompatibleChange(egoNet.getFrame())) { Question q = (Question) question_list.getSelectedValue(); @SuppressWarnings("unchecked") Class<? extends Question> type = (Class<? extends Question>)question_type_menu.getSelectedItem(); try { egoNet.getStudy().changeQuestionType(q, type); egoNet.getStudy().setCompatible(false); } catch (DuplicateQuestionException ex) { throw new RuntimeException(ex); } fillPanel(); } else { questionUpdate(); } } } /** * Change answer type in pop up menu, save in question record * * @param e UI event */ void question_answer_type_menu_actionPerformed(ActionEvent e) { if (!inUpdate) { if (egoNet.getStudy().confirmIncompatibleChange(egoNet.getFrame())) { @SuppressWarnings("unchecked") Class<? extends Answer> i = (Class<? extends Answer>)question_answer_type_menu.getSelectedItem(); Question q = (Question) question_list.getSelectedValue(); if (q != null) { if (q.answerType.equals(i)) { q.answerType = i; egoNet.getStudy().setModified(true); egoNet.getStudy().setCompatible(false); questionUpdate(); } } } else { // Change back questionUpdate(); } } } /** * Brings up category selection modal dialog box * * @param e UI event */ void set_selections_button_actionPerformed(ActionEvent e) { selectionsDialog.activate(); } /** * Changes order of questions * * @param e UI event */ void question_follows_menu_actionPerformed(ActionEvent e) { if (!inUpdate) { if (egoNet.getStudy().confirmIncompatibleChange(egoNet.getFrame())) { Question follows = (Question) question_follows_menu.getSelectedItem(); Question q = (Question) question_list.getSelectedValue(); egoNet.getStudy().moveQuestionAfter(q, follows); egoNet.getStudy().setCompatible(false); egoNet.getStudy().setModified(true); fillPanel(); } else { questionUpdate(); } } } void question_followup_only_combo_actionPerformed(ItemEvent e) { if (!inUpdate) { if (egoNet.getStudy().confirmIncompatibleChange(egoNet.getFrame())) { Question q = (Question) question_list.getSelectedValue(); q.setFollowupOnly(e.getStateChange() != ItemEvent.DESELECTED); egoNet.getStudy().setCompatible(false); egoNet.getStudy().setModified(true); fillPanel(); } else { questionUpdate(); } } } void question_central_checkBox_actionPerformed(ActionEvent e) { Question q = (Question) question_list.getSelectedValue(); egoNet.getStudy().setCentralQuestion(q); } public Class<? extends Question> getQuestionType() { return questionType; } } /** * Implements ListCellRenderer to differentiate between base and custom * questions */ class QuestionListCellRenderer<T> implements ListCellRenderer<T> { protected final DefaultListCellRenderer defaultRenderer = new DefaultListCellRenderer(); public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { JLabel renderer = (JLabel) defaultRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); return renderer; } }