View Javadoc

1   /***
2    * ReportTableModel.java
3    *
4    * This file is part of the creme library.
5    * The creme library intends to ease the development effort of large
6    * applications by providing easy to use support classes.
7    *
8    * Copyright (C) 2002 Denis Bregeon
9    *
10   * This library is free software; you can redistribute it and/or
11   * modify it under the terms of the GNU Lesser General Public
12   * License as published by the Free Software Foundation; either
13   * version 2.1 of the License, or (at your option) any later version.
14   *
15   * This library is distributed in the hope that it will be useful,
16   * but WITHOUT ANY WARRANTY; without even the implied warranty of
17   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18   * Lesser General Public License for more details.
19   *
20   * You should have received a copy of the GNU Lesser General Public
21   * License along with this library; if not, write to the Free Software
22   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23   *
24   * contact information: dbregeon@sourceforge.net
25   */
26  package org.jcreme.swing.reporting;
27  
28  import org.jcreme.reporting.ModifiableReport;
29  import org.jcreme.reporting.Report;
30  import org.jcreme.reporting.ReportChangeEvent;
31  import org.jcreme.reporting.ReportChangeListener;
32  import org.jcreme.swing.table.AbstractSortableTableModel;
33  
34  /***
35   * This is an implementation of an AbstractSortableTableModel based on the
36   * TableReport interface. This model enables to present a TableReport in a
37   * sortable way.
38   * 
39   * @author $Author: dbregeon $
40   * @version $Revision: 1.1 $
41   */
42  public class ReportTableModel extends AbstractSortableTableModel implements
43          ReportChangeListener {
44      /***
45       * The underlying report.
46       */
47      private Report report = null;
48  
49      private transient ReportChangeEvent sourceEvent = null;
50  
51      /***
52       * Creates new BondPositionReportTableModel
53       * 
54       * @param report
55       *            the report to be displayed in a JTable.
56       */
57      public ReportTableModel(Report report) {
58          this.report = report;
59          report.addReportChangeListener(this);
60      }
61  
62      /***
63       * Gives access to the number of rows in the report.
64       * 
65       * @return the number of rows in the model.
66       */
67      public int getRowCount() {
68          return this.report.getRowCount();
69      }
70  
71      /***
72       * This method returns the value at the original (non sorted) row.
73       * 
74       * @param row
75       *            the row for which the value is requested.
76       * @param column
77       *            the column for which the value is requested.
78       * @return the value at the original (non sorted) row for the given column.
79       */
80      protected Object getOriginalValueAt(int row, int column) {
81          return this.report.getValueAt(row, column);
82      }
83  
84      /***
85       * This method enables to change the value at the original (non sorted) row.
86       * 
87       * @param value
88       *            the value to set these coordinates in the original model.
89       * @param row
90       *            the row number in the original model.
91       * @param column
92       *            the column in the model.
93       */
94      protected void setOriginalValueAt(Object value, int row, int column) {
95          if (this.report instanceof ModifiableReport) {
96              try {
97                  ((ModifiableReport) this.report).setValueAt(value, row, column);
98              } catch (IllegalArgumentException e) {
99                  e.printStackTrace();
100             }
101         }
102     }
103 
104     /***
105      * Gives access to the number of columns in the report.
106      * 
107      * @return the number of columns in the model.
108      */
109     public int getColumnCount() {
110         return this.report.getColumnCount();
111     }
112 
113     /***
114      * Gives access to the name of a column.
115      * 
116      * @param column
117      *            the index of the column for which we want the name.
118      * @return the name of the column at the given index.
119      */
120     public String getColumnName(int column) {
121         return this.report.getColumnName(column);
122     }
123 
124     /***
125      * This method enables to transform the changes in the report into event
126      * that report changes in the model.
127      * 
128      * @param e
129      *            the event sent by the report.
130      */
131     public void reportChanged(ReportChangeEvent e) {
132         if (e.getType() == ReportChangeEvent.COLUMN_LIST) {
133             fireTableStructureChanged();
134         } else {
135             try {
136                 // To ensure that a new event does not erase the previous one.
137                 // This thread could not proceed into the synchronized part of
138                 // the sort anyway.
139                 synchronized (this) {
140                     while (this.sourceEvent != null) {
141                         synchronized (this.sourceEvent) {
142                             System.err.println("Blocks reportChanged.");
143                             this.sourceEvent.wait();
144                         }
145                     }
146                 }
147                 this.sourceEvent = e;
148                 sort(getSortingColumns());
149             } catch (InterruptedException ex) {
150                 ex.printStackTrace();
151             }
152         }
153     }
154 
155     /***
156      * Override the original method to provide a more precise behaviour when the
157      * change originates in the report (partial change). When the change does
158      * not originate in the report, the original behaviour is upheld.
159      */
160     public void fireTableDataChanged() {
161         ReportChangeEvent e = this.sourceEvent;
162         this.sourceEvent = null;
163         // Releases the waiting thread in the reportChanged method.
164         if (e != null) {
165             synchronized (e) {
166                 e.notifyAll();
167             }
168             int[][] intervals = null;
169             switch (e.getType()) {
170             case ReportChangeEvent.INSERT: {
171                 intervals = originalIntervalToSortedIntervals(e.getFirstRow(),
172                         e.getLastRow());
173                 for (int i = 0; i < intervals.length; i++) {
174                     fireTableRowsInserted(intervals[i][0], intervals[i][1]);
175                 }
176                 break;
177             }
178             case ReportChangeEvent.UPDATE: {
179                 intervals = originalIntervalToSortedIntervals(e.getFirstRow(),
180                         e.getLastRow());
181                 for (int i = 0; i < intervals.length; i++) {
182                     fireTableRowsUpdated(intervals[i][0], intervals[i][1]);
183                 }
184                 break;
185             }
186             case ReportChangeEvent.DELETE: {
187                 fireTableRowsDeleted(e.getFirstRow(), e.getLastRow());
188                 break;
189             }
190             }
191         } else {
192             super.fireTableDataChanged();
193         }
194     }
195 
196     /***
197      * Gives access to the class of the values that are in a column.
198      * 
199      * @param columnIndex
200      *            the column for which we want the type.
201      * @return the type of the values in the given column.
202      */
203     public Class getColumnClass(int columnIndex) {
204         return this.report.getColumnClass(columnIndex);
205     }
206 
207     /*
208      * (non-Javadoc)
209      * 
210      * @see org.jcreme.swing.table.AbstractSortableTableModel#isOriginalCellEditable(int,
211      *      int)
212      */
213     protected boolean isOriginalCellEditable(int row, int column) {
214         boolean result = false;
215         if (this.report instanceof ModifiableReport) {
216             result = ((ModifiableReport) this.report).isEditable(row, column);
217         }
218         return result;
219     }
220 
221 }