001: /*
002: * SalomeTMF is a Test Management Framework
003: * Copyright (C) 2005 France Telecom R&D
004: *
005: * This library is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU Lesser General Public
007: * License as published by the Free Software Foundation; either
008: * version 2 of the License, or (at your option) any later version.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: *
015: * You should have received a copy of the GNU Lesser General Public
016: * License along with this library; if not, write to the Free Software
017: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
018: *
019: * @author Marche Mikael
020: *
021: * Contact: mikael.marche@rd.francetelecom.com
022: */
023:
024: package salomeTMF_plug.requirements.ihm;
025:
026: import java.awt.BorderLayout;
027: import java.awt.Dimension;
028: import java.awt.FontMetrics;
029: import java.awt.GridLayout;
030: import java.awt.event.ActionEvent;
031: import java.awt.event.ActionListener;
032: import java.util.Observable;
033: import java.util.Observer;
034: import java.util.Vector;
035:
036: import javax.swing.BorderFactory;
037: import javax.swing.JButton;
038: import javax.swing.JPanel;
039: import javax.swing.JScrollPane;
040: import javax.swing.JTabbedPane;
041: import javax.swing.JTable;
042: import javax.swing.JTree;
043: import javax.swing.ListSelectionModel;
044: import javax.swing.event.ChangeEvent;
045: import javax.swing.event.ChangeListener;
046: import javax.swing.event.ListSelectionEvent;
047: import javax.swing.event.ListSelectionListener;
048: import javax.swing.event.TreeSelectionEvent;
049: import javax.swing.event.TreeSelectionListener;
050: import javax.swing.tree.DefaultMutableTreeNode;
051: import javax.swing.tree.TreePath;
052:
053: import org.jfree.chart.ChartFactory;
054: import org.jfree.chart.ChartPanel;
055: import org.jfree.chart.JFreeChart;
056: import org.jfree.chart.plot.PiePlot3D;
057: import org.jfree.data.general.DefaultPieDataset;
058: import org.jfree.util.Rotation;
059: import org.objectweb.salome_tmf.data.Campaign;
060: import org.objectweb.salome_tmf.ihm.languages.Language;
061: import org.objectweb.salome_tmf.ihm.main.datawrapper.DataModel;
062: import org.objectweb.salome_tmf.ihm.models.DynamicTree;
063: import org.objectweb.salome_tmf.ihm.tools.Tools;
064:
065: import salomeTMF_plug.requirements.ReqPlugin;
066: import salomeTMF_plug.requirements.data.ReqLeaf;
067: import salomeTMF_plug.requirements.data.Requirement;
068: import salomeTMF_plug.requirements.sqlWrapper.ReqWrapper;
069: import salomeTMF_plug.requirements.sqlWrapper.SQLWrapper;
070:
071: public class RequirementCampPanel extends JPanel implements
072: ActionListener, ListSelectionListener, Observer {
073: //ChangeListener
074: JButton viewReqButton;
075: // JButton infoReqButton;
076:
077: JTable reqTable;
078:
079: JPanel buttonsPanel;
080: JScrollPane tablePane;
081: JTabbedPane salomeParent;
082: JTree salomeDynamicTree;
083:
084: ChartPanel chartPanel;
085:
086: RequirementTree pReqTree;
087: //JTree reqTree;
088:
089: Campaign pCurrentCampaign;
090: Vector reqCovered;
091: Vector filtredreqCovered;
092:
093: PiePlot3D plot;
094: DefaultPieDataset dataset;
095: FiltrePanel pFiltrePanel;
096: int nbReqTotal = 0;
097:
098: public RequirementCampPanel(RequirementTree _pReqTree) {
099:
100: pReqTree = _pReqTree;
101: initComponent();
102: }
103:
104: void initComponent() {
105: reqCovered = new Vector();
106: filtredreqCovered = new Vector();
107:
108: viewReqButton = new JButton(Language.getInstance().getText(
109: "Visualiser"));
110: //infoReqButton = new JButton(Language.getInstance().getText("Statistique"));
111:
112: viewReqButton.addActionListener(this );
113: //infoReqButton.addActionListener(this);
114:
115: viewReqButton.setEnabled(false);
116: //infoReqButton.setEnabled(true);
117:
118: buttonsPanel = new JPanel(new GridLayout(1, 2));
119: //buttonsPanel.add(infoReqButton);
120: buttonsPanel.add(viewReqButton);
121:
122: SimpleTableModel model = new SimpleTableModel();
123:
124: reqTable = new JTable(model);
125: try {
126: //reqTable.setDefaultRenderer(Class.forName( "java.lang.Object" ), new PriorityTableCellRenderer(reqCovered));
127: reqTable.setDefaultRenderer(Class
128: .forName("java.lang.Object"),
129: new PriorityTableCellRenderer(filtredreqCovered));
130: } catch (Exception e) {
131: e.printStackTrace();
132: }
133: //model.addColumn("Id");
134: model.addColumn("id");
135: model.addColumn(Language.getInstance().getText("Nom"));
136: model.addColumn(Language.getInstance().getText("Categorie"));
137: model.addColumn(Language.getInstance().getText("Complexite"));
138: model.addColumn(Language.getInstance().getText("Etat"));
139:
140: reqTable.setPreferredScrollableViewportSize(new Dimension(600,
141: 200));
142: reqTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
143: ListSelectionModel rowSM = reqTable.getSelectionModel();
144: rowSM.addListSelectionListener(this );
145:
146: tablePane = new JScrollPane(reqTable);
147: tablePane.setBorder(BorderFactory.createRaisedBevelBorder());
148:
149: dataset = new DefaultPieDataset();
150: dataset.setValue(Language.getInstance().getText(
151: "Exigence_non_couverte"), new Double(100.0));
152: dataset.setValue(Language.getInstance().getText(
153: "Exigence_couverte"), new Double(0.0));
154:
155: JFreeChart chart = ChartFactory.createPieChart3D(Language
156: .getInstance().getText("Exigence_couverte"), // chart title
157: dataset, // data
158: true, // include legend
159: true, false);
160:
161: plot = (PiePlot3D) chart.getPlot();
162: plot.setStartAngle(290);
163: plot.setDirection(Rotation.CLOCKWISE);
164: plot.setForegroundAlpha(0.5f);
165: plot.setNoDataMessage("No data to display");
166: chartPanel = new ChartPanel(chart);
167:
168: JPanel graphPanel = new JPanel(new BorderLayout());
169: pFiltrePanel = new FiltrePanel(null, this );
170: graphPanel.add(chartPanel, BorderLayout.CENTER);
171: graphPanel.add(pFiltrePanel, BorderLayout.SOUTH);
172:
173: setLayout(new BorderLayout());
174: add(buttonsPanel, BorderLayout.NORTH);
175: add(tablePane, BorderLayout.CENTER);
176: //add(chartPanel, BorderLayout.SOUTH);
177: add(graphPanel, BorderLayout.SOUTH);
178:
179: }
180:
181: public void setParent(JTabbedPane _salomeParent) {
182: if (salomeParent != null) {
183: return;
184: } else {
185: salomeParent = _salomeParent;
186: salomeParent.addChangeListener(new ChangeListener() {
187: public void stateChanged(ChangeEvent e) {
188: if (((JTabbedPane) e.getSource())
189: .getSelectedComponent().equals(
190: RequirementCampPanel.this )) {
191: System.out.println("Update Requiment for test");
192: Campaign pCamp = DataModel.getCurrentCampaign();
193: if (pCamp == pCurrentCampaign || pCamp == null) {
194: return;
195: }
196: InitData(pCamp, true);
197: }
198: }
199: });
200: }
201: }
202:
203: public void setCampTree(DynamicTree pDynamicTree) {
204: if (salomeDynamicTree == null) {
205: salomeDynamicTree = pDynamicTree.getTree();
206: salomeDynamicTree
207: .addTreeSelectionListener(new TreeSelectionListener() {
208: public void valueChanged(TreeSelectionEvent e) {
209: DefaultMutableTreeNode node = (DefaultMutableTreeNode) salomeDynamicTree
210: .getLastSelectedPathComponent();
211:
212: if (node == null)
213: return;
214:
215: Object nodeInfo = node.getUserObject();
216: /* React to the node selection. */
217: if ((nodeInfo instanceof Campaign)) {
218: if (salomeParent
219: .getSelectedComponent()
220: .equals(
221: RequirementCampPanel.this )) {
222: Campaign pCamp = (Campaign) nodeInfo;
223: if (pCamp == pCurrentCampaign
224: || pCamp == null) {
225: return;
226: }
227: InitData(pCamp, true);
228: }
229: }
230: }
231: });
232: }
233: }
234:
235: /**
236: * Call When an Test caver change
237: * @param updateSQL
238: */
239: void refreshCurrentCover(boolean updateSQL) {
240: if (pCurrentCampaign != null) {
241: InitData(pCurrentCampaign, updateSQL);
242: }
243: }
244:
245: /**
246: * Campaign nopt change but refresh because :
247: * - New req added
248: * - Filtre change
249: */
250: void refreshCurrentDataModel() {
251: if (pCurrentCampaign != null) {
252: int reqCoveredWrapperSize = reqCovered.size();
253: filtredreqCovered.clear();
254: int filtre = pFiltrePanel.getFiltre();
255: for (int i = 0; i < reqCoveredWrapperSize; i++) {
256: Requirement pReq = (Requirement) reqCovered
257: .elementAt(i);
258: if (pReq instanceof ReqLeaf) {
259: if (!filtredreqCovered.contains(pReq)) {
260: int reqP = ((ReqLeaf) pReq)
261: .getPriorityFromModel();
262: if ((reqP | filtre) == filtre) {
263: filtredreqCovered.add(pReq);
264: }
265: }
266: }
267: }
268: updateReqUse(filtredreqCovered);
269: updateChart(filtredreqCovered, false);
270: }
271: }
272:
273: void InitData(Campaign pCamp, boolean updateSQL) {
274:
275: pCurrentCampaign = pCamp;
276: Vector reqCoveredWrapper;
277: reqCovered.clear();
278: filtredreqCovered.clear();
279: nbReqTotal = 0;
280:
281: int filtre = pFiltrePanel.getFiltre();
282:
283: int transNumber = -1;
284: try {
285: transNumber = SQLWrapper.beginTransaction();
286: reqCoveredWrapper = Requirement
287: .getReqWrapperCoveredByCamp(pCamp.getIdBdd());
288: int size = reqCoveredWrapper.size();
289: for (int j = 0; j < size; j++) {
290: ReqWrapper pReqWrapper = (ReqWrapper) reqCoveredWrapper
291: .elementAt(j);
292: DefaultMutableTreeNode node = pReqTree
293: .findRequirementFromParent(pReqWrapper);
294: Requirement pReq = null;
295: if (node != null) {
296: pReq = (Requirement) node.getUserObject();
297: if (!reqCovered.contains(pReq)) {
298: reqCovered.add(pReq);
299: }
300: if (pReq instanceof ReqLeaf) {
301: if (!filtredreqCovered.contains(pReq)) {
302: int reqP = ((ReqLeaf) pReq)
303: .getPriorityFromModel();
304: if ((reqP | filtre) == filtre) {
305: filtredreqCovered.add(pReq);
306: }
307: }
308: }
309: } else {
310: pReqTree.reload();
311: node = pReqTree
312: .findRequirementFromParent(pReqWrapper);
313: if (node != null) {
314: pReq = (Requirement) node.getUserObject();
315: if (!reqCovered.contains(pReq)) {
316: reqCovered.add(pReq);
317: }
318: if (pReq instanceof ReqLeaf) {
319: if (!filtredreqCovered.contains(pReq)) {
320: int reqP = ((ReqLeaf) pReq)
321: .getPriorityFromModel();
322: if ((reqP | filtre) == filtre) {
323: filtredreqCovered.add(pReq);
324: }
325: }
326: }
327: } else {
328: //Hum Data corruption !!!
329: Tools
330: .ihmExceptionView(new Exception(
331: "Hum ??, it seem that data integrity are corrupted"));
332:
333: }
334: }
335: }
336: // Init table data
337: /*updateReqUse(reqCovered);
338: updateChart(reqCovered);
339: */
340: updateReqUse(filtredreqCovered);
341: updateChart(filtredreqCovered, updateSQL);
342:
343: SQLWrapper.commitTrans(transNumber);
344: } catch (Exception e) {
345: try {
346: SQLWrapper.rollBackTrans(transNumber);
347: } catch (Exception e1) {
348:
349: }
350: Tools.ihmExceptionView(e);
351: }
352: }
353:
354: void updateReqUse(Vector reqCovered) {
355:
356: int reqSize = reqCovered.size();
357: ((SimpleTableModel) reqTable.getModel()).clearTable();
358:
359: for (int i = 0; i < reqSize; i++) {
360: Requirement pReq = (Requirement) reqCovered.elementAt(i);
361: Vector data = new Vector();
362: //data.add(pReq.getNameFromModel());
363: data.add("" + pReq.getIdBdd());
364: data.add(pReq.getLongName());
365: /*if (pReq.getDescriptionFromModel().length()> 60){
366: data.add(pReq.getDescriptionFromModel().substring(0, 59)+"...");
367: } else {
368: data.add(pReq.getDescriptionFromModel());
369: }*/
370: data.add(ReqWrapper.getCatString(((ReqLeaf) pReq)
371: .getCatFromModel()));
372: data.add(ReqWrapper.getComplexString(((ReqLeaf) pReq)
373: .getComplexeFromModel()));
374: data.add(ReqWrapper.getStateString(((ReqLeaf) pReq)
375: .getStateFromModel()));
376:
377: ((SimpleTableModel) reqTable.getModel()).insertRow(i, data);
378: }
379: setColumnSize(reqTable);
380: }
381:
382: public void actionPerformed(ActionEvent e) {
383: if (e.getSource().equals(viewReqButton)) {
384: viewReqPerformed(e);
385: }
386: }
387:
388: void viewReqPerformed(ActionEvent e) {
389: int selectedRow = reqTable.getSelectedRow();
390:
391: if (selectedRow > -1) {
392: //if (reqCovered != null) {
393: if (filtredreqCovered != null) {
394: //Requirement pReq = (Requirement)reqCovered.elementAt(selectedRow);
395: Requirement pReq = (Requirement) filtredreqCovered
396: .elementAt(selectedRow);
397:
398: DefaultMutableTreeNode node = pReqTree
399: .findRequirementFromParent(pReq);
400: if (node != null) {
401: //pReqTree.refreshNode(node);
402: ReqPlugin.selectReqTab();
403: pReqTree.setSelectionPath(new TreePath(node
404: .getPath()));
405:
406: }
407: }
408: }
409: }
410:
411: public void valueChanged(ListSelectionEvent e) {
412: //Ignore extra messages.
413: if (e.getValueIsAdjusting()) {
414: return;
415: }
416:
417: ListSelectionModel lsm = (ListSelectionModel) e.getSource();
418: if (lsm.isSelectionEmpty()) {
419: //no rows are selected
420: viewReqButton.setEnabled(false);
421: } else {
422: //int selectedRow = lsm.getMinSelectionIndex();
423: viewReqButton.setEnabled(true);
424: //selectedRow is selected
425: }
426: }
427:
428: public void setColumnSize(JTable table) {
429: FontMetrics fm = table.getFontMetrics(table.getFont());
430: for (int i = 0; i < table.getColumnCount(); i++) {
431: int max = 0;
432: for (int j = 0; j < table.getRowCount(); j++) {
433: int taille = fm.stringWidth((String) table.getValueAt(
434: j, i));
435: if (taille > max)
436: max = taille;
437: }
438: String nom = (String) table.getColumnModel().getColumn(i)
439: .getIdentifier();
440: int taille = fm.stringWidth(nom);
441: if (taille > max)
442: max = taille;
443: table.getColumnModel().getColumn(i).setPreferredWidth(
444: max + 10);
445: }
446: }
447:
448: void updateChart(Vector reqCovered, boolean doSQL) {
449: int nbReqCovered = reqCovered.size();
450: //int nbReqTotal = 0;
451:
452: try {
453: if (doSQL) {
454: nbReqTotal = Requirement
455: .getReqWrapperLeafInCurrentProject().size();
456: } else if (nbReqTotal == 0) {
457: nbReqTotal = Requirement
458: .getReqWrapperLeafInCurrentProject().size();
459: }
460: } catch (Exception e) {
461: nbReqTotal = 0;
462: }
463:
464: dataset = new DefaultPieDataset();
465: if (nbReqTotal > 0) {
466: Double nbCovered = new Double((nbReqCovered * 100)
467: / nbReqTotal);
468: Double nbNotCovered = new Double(100 - (nbReqCovered * 100)
469: / nbReqTotal);
470: dataset.setValue(Language.getInstance().getText(
471: "Exigence_non_couverte"), nbNotCovered);
472: dataset.setValue(Language.getInstance().getText(
473: "Exigence_couverte"), nbCovered);
474: }
475: plot.setDataset(dataset);
476: }
477:
478: /******************************** Observer *************************/
479:
480: public void update(Observable o, Object arg) {
481: if (arg instanceof ReqEvent) {
482: ReqEvent event = (ReqEvent) arg;
483: if (event.code == ReqEvent.FILTRE_REQ_CHANGE) {
484: refreshCurrentDataModel();
485: }
486: }
487: }
488: }
|