001    /**
002     * iFish - An iRiver iHP jukebox database creation tool
003     *
004     * Copyright (C) 2009 Richard "Shred" Körber
005     *   http://ifish.shredzone.org
006     *
007     * This program is free software: you can redistribute it and/or modify
008     * it under the terms of the GNU General Public License as published by
009     * the Free Software Foundation, either version 3 of the License, or
010     * (at your option) any later version.
011     *
012     * This program is distributed in the hope that it will be useful,
013     * but WITHOUT ANY WARRANTY; without even the implied warranty of
014     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
015     * GNU General Public License for more details.
016     *
017     * You should have received a copy of the GNU General Public License
018     * along with this program.  If not, see <http://www.gnu.org/licenses/>.
019     */
020    package net.shredzone.ifish.gui;
021    
022    import net.shredzone.ifish.db.*;
023    import net.shredzone.ifish.i18n.L;
024    import javax.swing.event.*;
025    import java.io.*;
026    import java.util.*;
027    
028    /**
029     * This is an extension of the NaviDb class to make it usable in JTables.
030     *
031     * @author    Richard Körber &lt;dev@shredzone.de&gt;
032     * @version   $Id: NaviDbTableModel.java 291 2009-04-28 21:29:27Z shred $
033     */
034    public class NaviDbTableModel extends NaviDb implements javax.swing.table.TableModel {
035      protected final List<Entry> lSequence = new ArrayList<Entry>();
036      private   final Set<TableModelListener> sNotify = new HashSet<TableModelListener>();
037      
038      /**
039       * Create a new, empty NaviDbTableModel.
040       */
041      public NaviDbTableModel() {
042        super();
043      }
044      
045      /**
046       * Create a database and fill it with a database file.
047       *
048       * @param   file          Database file to be read
049       * @param   charset       Desired Charset
050       * @throws  IOException   File was erraneous or could not be read
051       * @throws  DatabaseException   An error occured during database creation
052       * @throws  UnsupportedEncodingException    Charset not known
053       */
054      public NaviDbTableModel( File file, String charset )
055      throws IOException, DatabaseException, UnsupportedEncodingException {
056        super( file, charset );
057      }
058    
059      /**
060       * Get the number of rows.
061       *
062       * @return  Number of Rows (entries)
063       */
064      @Override
065      public int getRowCount() {
066        return sEntries.size();
067      }
068      
069      /**
070       * Get the number of columns
071       *
072       * @return  Number of Columns
073       */
074      @Override
075      public int getColumnCount() {
076        return 6;
077      }
078    
079      /**
080       * Get the column title.
081       *
082       * @param   columnIndex     Addressed column
083       * @return  It's title
084       */
085      @Override
086      public String getColumnName(int columnIndex) {
087        String name = null;
088        switch( columnIndex ) {
089          case 0:   name = L.tr("table.head.index");  break;
090          case 1:   name = L.tr("table.head.title");  break;
091          case 2:   name = L.tr("table.head.artist"); break;
092          case 3:   name = L.tr("table.head.album");  break;
093          case 4:   name = L.tr("table.head.genre");  break;
094          case 5:   name = L.tr("table.head.file");   break;
095        }
096        return name;
097      }
098      
099      /**
100       * Get the class that represents the column.
101       *
102       * @param   columnIndex     Addressed column
103       * @return  The representing class
104       */
105      @Override
106      public Class<?> getColumnClass( int columnIndex ) {
107        if( columnIndex==0 ) {
108          return Integer.class;
109        }else {
110          return String.class;
111        }
112      }
113      
114      /**
115       * Check if a cell is editable. Will always return false.
116       *
117       * @param   rowIndex        Addressed Row
118       * @param   columnIndex     Addressed Column
119       * @return  true: editable, false: immutable
120       */
121      @Override
122      public boolean isCellEditable( int rowIndex, int columnIndex ) {
123        return false;
124      }
125      
126      /**
127       * Get the value of a certain cell.
128       *
129       * @param   rowIndex        Addressed Row
130       * @param   columnIndex     Addressed Column
131       * @return  Value of this cell
132       */
133      @Override
134      public Object getValueAt( int rowIndex, int columnIndex ) {
135        Entry entry = getEntryAt( rowIndex );
136        if( entry==null ) return null;
137        
138        Object result = null;
139        switch( columnIndex ) {
140          case 0:   result = new Integer( rowIndex+1 ); break;
141          case 1:   result = entry.getTitle();          break;
142          case 2:   result = entry.getArtist();         break;
143          case 3:   result = entry.getAlbum();          break;
144          case 4:   result = entry.getGenre();          break;
145          case 5:   result = entry.getFileName();       break;
146        }
147        return result;
148      }
149      
150      /**
151       * Get the entry of a certain row.
152       *
153       * @param   rowIndex        Addressed Row
154       * @return  Entry
155       */
156      public Entry getEntryAt( int rowIndex ) {
157        return (Entry) lSequence.get( rowIndex );
158      }
159      
160      /** 
161       * Change the value of a cell. This is unsupported.
162       *
163       * @param   aValue          New value
164       * @param   rowIndex        Addressed Row
165       * @param   columnIndex     Addressed Column
166       */
167      @Override
168      public void setValueAt( Object aValue, int rowIndex, int columnIndex) {
169        throw new UnsupportedOperationException( "cannot change value" );
170      }
171    
172      /**
173       * Add a TableModelListener.
174       *
175       * @param   l             TableModelListener to add.
176       */
177      @Override
178      public void addTableModelListener( TableModelListener l ) {
179        sNotify.add( l );
180      }
181      
182      /**
183       * Remove a TableModelListener. If it was not added, nothing will happen.
184       *
185       * @param   l             TableModelListener to be removed.
186       */
187      @Override
188      public void removeTableModelListener( TableModelListener l ) {
189        sNotify.remove( l );
190      }
191      
192      /**
193       * Fire a model event.
194       *
195       * @param   row           Affected row
196       */
197      protected void fireTableModelEvent( int row ) {
198        TableModelEvent tme = new TableModelEvent( this, row );
199        for (TableModelListener l : sNotify) {
200          l.tableChanged( tme );
201        }
202      }
203      
204      /**
205       * Add an entry to the database.
206       *
207       * @param   entry         Entry to be added
208       */
209      @Override
210      public void addEntry( Entry entry )
211      throws DatabaseException {
212        super.addEntry( entry );
213        
214        //--- Store the position ---
215        int row = sEntries.headSet( entry ).size();
216        if( lSequence.contains(entry) ) {
217          lSequence.set( row, entry );    // Replace if already existed
218        }else {
219          lSequence.add( row, entry );    // Add if it didn't exist
220        }
221        
222        //--- Update the JTable ---
223        fireTableModelEvent( row );
224      }
225      
226      /**
227       * Remove an entry from the database. If the entry does not exist,
228       * nothing will happen.
229       *
230       * @param   entry         Entry to be removed
231       */
232      @Override
233      public void removeEntry( Entry entry ) {
234        //--- Get the position ---
235        int row = sEntries.headSet( entry ).size();
236    
237        //--- Remove from list ---
238        lSequence.remove( entry );
239    
240        //--- Remove entry ---    
241        super.removeEntry( entry );
242    
243        //--- Update the JTable ---
244        fireTableModelEvent( row );
245      }
246    }