001: package com.xoetrope.carousel.survey;
002:
003: import com.xoetrope.survey.Question;
004: import java.awt.event.ActionEvent;
005: import java.awt.event.ActionListener;
006: import java.util.Observable;
007: import java.util.Observer;
008: import java.util.Vector;
009: import java.awt.Component;
010: import java.awt.Point;
011: import java.awt.event.MouseEvent;
012: import java.awt.event.MouseListener;
013: import javax.swing.JComboBox;
014: import javax.swing.JLabel;
015: import javax.swing.JMenuItem;
016: import javax.swing.JPopupMenu;
017: import javax.swing.JTable;
018: import javax.swing.JTextField;
019: import javax.swing.event.ListSelectionEvent;
020: import javax.swing.table.AbstractTableModel;
021: import javax.swing.event.ListSelectionListener;
022: import net.xoetrope.xui.XProject;
023: import net.xoetrope.xui.XProjectManager;
024:
025: /**
026: * A model for questions table
027: *
028: * <p> Copyright (c) Xoetrope Ltd., 2001-2006, This software is licensed under
029: * the GNU Public License (GPL), please see license.txt for more details. If
030: * you make commercial use of this software you must purchase a commercial
031: * license from Xoetrope.</p>
032: * <p> $Revision: 1.5 $</p>
033: */
034: public class XQuestionsTableModel extends AbstractTableModel implements
035: MouseListener, ListSelectionListener, Observer {
036:
037: public static final int COL_GROUPID = 0;
038: public static final int COL_ID = 1;
039: public static final int COL_QUESTION = 2;
040: public static final int COL_TYPE = 3;
041:
042: protected XQuestionGroup currentGroup;
043: protected XSurvey survey;
044: protected XTable table;
045: protected Observable notifier;
046: protected JPopupMenu popupMenu;
047: protected NewQuestionDialog newQuestionDialog;
048:
049: //actions
050: protected ActionListener addQuestion, deleteQuestion,
051: moveQuestionUp, moveQuestionDown;
052:
053: protected XTableColumn[] columns = new XTableColumn[4];
054:
055: public XQuestionsTableModel(XTable t) {
056: table = t;
057: notifier = new QuestionChangedNotifier();
058:
059: XProject project = XProjectManager.getCurrentProject();
060: survey = (XSurvey) project.getObject("Survey");
061: currentGroup = survey.getGroup(0);
062:
063: columns[0] = new XTableColumn("group", 20, JLabel.LEFT,
064: new JComboBox(survey.getGroups()));
065: columns[1] = new XTableColumn("id", 20, JLabel.LEFT,
066: new JTextField());
067: columns[2] = new XTableColumn("question", 400, JLabel.LEFT,
068: new JTextField());
069:
070: columns[3] = new XTableColumn("type", 100, JLabel.LEFT,
071: new JComboBox(Question.QUESTION_TYPES));
072:
073: table.setModel(this , columns, this );
074: table.getSelectionModel().addListSelectionListener(this );
075:
076: moveQuestionUp = new moveQuestionUp();
077: moveQuestionDown = new moveQuestionDown();
078: addQuestion = new AddQuestion();
079: deleteQuestion = new DeleteQuestion();
080:
081: newQuestionDialog = new NewQuestionDialog();
082: createPopupMenu();
083: }
084:
085: public void refresh() {
086: table.clearSelection();
087: table.revalidate();
088: table.repaint();
089: notifier.notifyObservers(null);
090: }
091:
092: public JTable getTable() {
093: return table;
094: }
095:
096: public void setCurrentGroup(XQuestionGroup group) {
097: currentGroup = group;
098: }
099:
100: public ActionListener getMoveQuestionUp() {
101: return moveQuestionUp;
102: }
103:
104: public ActionListener getMoveQuestionDown() {
105: return moveQuestionDown;
106: }
107:
108: public ActionListener getAddQuestion() {
109: return addQuestion;
110: }
111:
112: public ActionListener getDeleteQuestion() {
113: return deleteQuestion;
114: }
115:
116: private void createPopupMenu() {
117: JMenuItem menuItem;
118: popupMenu = new JPopupMenu();
119: popupMenu.add(new JLabel("Question Option"));
120: popupMenu.addSeparator();
121: menuItem = new JMenuItem("Move up");
122: popupMenu.add(menuItem);
123: menuItem.addActionListener(moveQuestionUp);
124: menuItem = new JMenuItem("Move down");
125: popupMenu.add(menuItem);
126: menuItem.addActionListener(moveQuestionDown);
127: popupMenu.addSeparator();
128: menuItem = new JMenuItem("Add..");
129: popupMenu.add(menuItem);
130: menuItem.addActionListener(addQuestion);
131: menuItem = new JMenuItem("Delete..");
132: popupMenu.add(menuItem);
133: menuItem.addActionListener(deleteQuestion);
134: }
135:
136: public Observable getNotifier() {
137: return notifier;
138: }
139:
140: public XTableColumn[] getColumns() {
141: return columns;
142: }
143:
144: public int getRowCount() {
145: return (currentGroup != null ? currentGroup.getQuestions()
146: .size() : 0);
147: }
148:
149: public int getColumnCount() {
150: int cc = 0;
151: for (int i = 0; i < columns.length; i++)
152: if (columns[i].isActive())
153: cc++;
154: return cc;
155: }
156:
157: public void selectQuestion(Question question) {
158: int idx = currentGroup.getQuestionIdx(question);
159: int row = table.getSelectedRow();
160: if (idx != -1 && idx != row) {
161: table.getSelectionModel().setSelectionInterval(idx, idx);
162: table.repaint();
163: } else if (idx == -1) {
164: table.clearSelection();
165: table.repaint();
166: }
167: }
168:
169: public Object getValueAt(int rowIndex, int columnIndex) {
170: if (currentGroup == null || rowIndex < 0
171: || rowIndex >= getRowCount())
172: return "";
173:
174: for (int i = 0; i < columns.length; i++)
175: if (!columns[i].isActive())
176: columnIndex++;
177:
178: Question question = currentGroup.getQuestion(rowIndex);
179: switch (columnIndex) {
180: case COL_GROUPID:
181: return question.getGroup().toString();
182: case COL_ID:
183: return String.valueOf(question.getId());
184: case COL_QUESTION:
185: return question.getText();
186: case COL_TYPE:
187: return question.getQuestionTypeText();
188: }
189: return "";
190: }
191:
192: public void setValueAt(Object value, int rowIndex, int columnIndex) {
193: if ((value == null) || (currentGroup == null) || (rowIndex < 0)
194: || (rowIndex >= getRowCount()))
195: return;
196:
197: for (int i = 0; i < columns.length; i++) {
198: if (!columns[i].isActive())
199: columnIndex++;
200: }
201:
202: Question question = currentGroup.getQuestion(rowIndex);
203:
204: switch (columnIndex) {
205: case COL_GROUPID:
206: XQuestionGroup newGroup = (XQuestionGroup) value;
207: if (newGroup.getId() != question.getGroup().getId()) {
208: currentGroup.removeQuestion(question);
209: question.setGroup(newGroup);
210: newGroup.addQuestion(question);
211: table.revalidate();
212: table.repaint();
213: }
214: break;
215: case COL_ID:
216: int newId = new Integer(value.toString()).intValue();
217: if (newId != question.getId())
218: XSurvey.setProjectModified(true);
219: question.setId(newId);
220: break;
221:
222: case COL_QUESTION:
223: String newText = value.toString();
224: if (!newText.equals(question.getText()))
225: XSurvey.setProjectModified(true);
226: question.setText(newText);
227: break;
228:
229: case COL_TYPE:
230: String newType = value.toString();
231: boolean state = !newType.equals(question
232: .getQuestionTypeText());
233: if (state)
234: XSurvey.setProjectModified(true);
235: question.setType(newType);
236: break;
237: }
238: }
239:
240: public String getColumnName(int col) {
241: for (int i = 0; i < columns.length; i++) {
242: if (!columns[i].isActive())
243: col++;
244: }
245: return columns[col].getName();
246: }
247:
248: public boolean isCellEditable(int row, int col) {
249: return (columns[col].getCellEditor() != null);
250: }
251:
252: public void mouseClicked(MouseEvent e) {
253: }
254:
255: public void mousePressed(MouseEvent e) {
256: showPopupMenu(e);
257: }
258:
259: public void mouseReleased(MouseEvent e) {
260: showPopupMenu(e);
261: }
262:
263: public void mouseEntered(MouseEvent e) {
264: }
265:
266: public void mouseExited(MouseEvent e) {
267: }
268:
269: private void showPopupMenu(MouseEvent e) {
270: if (e.isPopupTrigger()) {
271: Component source = (Component) e.getSource();
272: boolean isQuestionOption = (source instanceof XTable || source instanceof JTextField);
273: Point p = e.getPoint();
274: if (!isQuestionOption) {
275: System.out.println(source.getParent().getParent()
276: .getParent().getParent());
277: // table->viewport->scrollpane->XPopupPanel
278: //((XResponseSetEditor)( ( XPopupPanel )source.getParent().getParent().getParent() ).getOwner()).addPopupActions();
279: } else
280: popupMenu.show(source, p.x, p.y);
281: }
282: }
283:
284: public void valueChanged(ListSelectionEvent e) {
285: int row = table.getSelectedRow();
286: Question question = null;
287: if (row >= 0 && row < getRowCount())
288: question = currentGroup.getQuestion(row);
289: notifier.notifyObservers(question);
290: }
291:
292: public void update(Observable o, Object arg) {
293: currentGroup = (XQuestionGroup) arg;
294: refresh();
295: }
296:
297: private class moveQuestionUp implements ActionListener {
298: public void actionPerformed(ActionEvent e) {
299: if (currentGroup == null)
300: return;
301:
302: int idx = table.getSelectedRow();
303: if (idx <= 0 || idx >= getRowCount())
304: return;
305:
306: Vector questions = currentGroup.getQuestions();
307: Question question = (Question) questions.get(idx);
308: questions.remove(idx);
309: questions.add(--idx, question);
310: table.getSelectionModel().setSelectionInterval(idx, idx);
311: table.revalidate();
312: table.repaint();
313: currentGroup.getPositionQuestionNotifier().notifyObservers(
314: question);
315: }
316: }
317:
318: private class moveQuestionDown implements ActionListener {
319: public void actionPerformed(ActionEvent e) {
320: if (currentGroup == null)
321: return;
322:
323: int idx = table.getSelectedRow();
324: if (idx < 0 || idx >= getRowCount() - 1)
325: return;
326:
327: Vector questions = currentGroup.getQuestions();
328: Question question = (Question) questions.get(idx);
329: questions.remove(idx);
330: questions.add(++idx, question);
331: table.getSelectionModel().setSelectionInterval(idx, idx);
332: table.revalidate();
333: table.repaint();
334: currentGroup.getPositionQuestionNotifier().notifyObservers(
335: question);
336: }
337: }
338:
339: public class AddQuestion implements ActionListener {
340: public void actionPerformed(ActionEvent e) {
341: if (newQuestionDialog.showDialog(currentGroup)) {
342: XQuestionGroup group = newQuestionDialog.getGroup();
343: int questionId = newQuestionDialog.getQuestionId();
344: int questionType = newQuestionDialog.getQuestionType();
345: String questionText = newQuestionDialog
346: .getQuestionText();
347: group.addNewQuestion(questionId, questionText,
348: questionType);
349: int idx = currentGroup.getQuestions().size() - 1;
350: table.revalidate();
351: table.repaint();
352: table.getSelectionModel()
353: .setSelectionInterval(idx, idx);
354: }
355: }
356: }
357:
358: public class DeleteQuestion implements ActionListener {
359: public void actionPerformed(ActionEvent e) {
360: int row = table.getSelectedRow();
361: if (row < 0 || row >= getRowCount())
362: return;
363:
364: Question question = currentGroup.getQuestion(row);
365: currentGroup.deleteQuestion(question);
366: table.clearSelection();
367: table.revalidate();
368: table.repaint();
369: notifier.notifyObservers(null);
370: }
371: }
372:
373: private class QuestionChangedNotifier extends Observable {
374: public void notifyObservers(Object o) {
375: setChanged();
376: super.notifyObservers(o);
377: }
378: }
379:
380: }
|