001    // SECTION-START[License Header]
002    // <editor-fold defaultstate="collapsed" desc=" Generated License ">
003    /*
004     *   Copyright (c) 2010 The JOMC Project
005     *   Copyright (c) 2005 Christian Schulte <cs@jomc.org>
006     *   All rights reserved.
007     *
008     *   Redistribution and use in source and binary forms, with or without
009     *   modification, are permitted provided that the following conditions
010     *   are met:
011     *
012     *     o Redistributions of source code must retain the above copyright
013     *       notice, this list of conditions and the following disclaimer.
014     *
015     *     o Redistributions in binary form must reproduce the above copyright
016     *       notice, this list of conditions and the following disclaimer in
017     *       the documentation and/or other materials provided with the
018     *       distribution.
019     *
020     *   THIS SOFTWARE IS PROVIDED BY THE JOMC PROJECT AND CONTRIBUTORS "AS IS"
021     *   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
022     *   THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
023     *   PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JOMC PROJECT OR
024     *   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
025     *   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
026     *   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
027     *   OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
028     *   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
029     *   OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
030     *   ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
031     *
032     *   $Id: SequencesTableModel.java 1478 2010-02-02 10:19:18Z schulte2005 $
033     *
034     */
035    // </editor-fold>
036    // SECTION-END
037    package org.jomc.sequences.util;
038    
039    import java.beans.Beans;
040    import java.beans.ExceptionListener;
041    import java.beans.PropertyChangeListener;
042    import java.beans.PropertyChangeSupport;
043    import java.io.Serializable;
044    import java.math.BigInteger;
045    import java.util.LinkedList;
046    import java.util.List;
047    import javax.swing.event.SwingPropertyChangeSupport;
048    import javax.swing.table.AbstractTableModel;
049    import org.jomc.sequences.Sequence;
050    import org.jomc.sequences.SequencesException;
051    import org.jomc.sequences.SequencesSystemException;
052    
053    // SECTION-START[Documentation]
054    // <editor-fold defaultstate="collapsed" desc=" Generated Documentation ">
055    /**
056     * Swing TableModel Java Bean for displaying and editing a system's SequenceDirectory.
057     * <p><b>Specifications</b><ul>
058     * <li>{@code javax.swing.table.TableModel} {@code Multiton}</li>
059     * </ul></p>
060     * <p><b>Properties</b><ul>
061     * <li>"{@link #isIncrementColumnEditableByDefault incrementColumnEditableByDefault}"
062     * <blockquote>Property of type {@code java.lang.Boolean}.
063     * <p>Flag indicating that the &quot;increment&quot; column is editable by default.</p>
064     * </blockquote></li>
065     * <li>"{@link #isMaximumColumnEditableByDefault maximumColumnEditableByDefault}"
066     * <blockquote>Property of type {@code java.lang.Boolean}.
067     * <p>Flag indicating that the &quot;maximum&quot; column is editable by default.</p>
068     * </blockquote></li>
069     * <li>"{@link #isMinimumColumnEditableByDefault minimumColumnEditableByDefault}"
070     * <blockquote>Property of type {@code java.lang.Boolean}.
071     * <p>Flag indicating that the &quot;minimum&quot; column is editable by default.</p>
072     * </blockquote></li>
073     * <li>"{@link #isNameColumnEditableByDefault nameColumnEditableByDefault}"
074     * <blockquote>Property of type {@code java.lang.Boolean}.
075     * <p>Flag indicating that the &quot;name&quot; column is editable by default.</p>
076     * </blockquote></li>
077     * <li>"{@link #isValueColumnEditableByDefault valueColumnEditableByDefault}"
078     * <blockquote>Property of type {@code java.lang.Boolean}.
079     * <p>Flag indicating that the &quot;value&quot; column is editable by default.</p>
080     * </blockquote></li>
081     * </ul></p>
082     * <p><b>Dependencies</b><ul>
083     * <li>"{@link #getExceptionListener ExceptionListener}"<blockquote>
084     * Dependency on {@code java.beans.ExceptionListener} at specification level 1.4 bound to an instance.</blockquote></li>
085     * <li>"{@link #getLocale Locale}"<blockquote>
086     * Dependency on {@code java.util.Locale} at specification level 1.1 bound to an instance.</blockquote></li>
087     * <li>"{@link #getLogger Logger}"<blockquote>
088     * Dependency on {@code org.jomc.logging.Logger} at specification level 1.0 bound to an instance.</blockquote></li>
089     * <li>"{@link #getSequenceDirectory SequenceDirectory}"<blockquote>
090     * Dependency on {@code org.jomc.sequences.SequenceDirectory} at specification level 1.0 bound to an instance.</blockquote></li>
091     * </ul></p>
092     * <p><b>Messages</b><ul>
093     * <li>"{@link #getIllegalColumnIndexMessage illegalColumnIndex}"<table>
094     * <tr><td valign="top">English:</td><td valign="top"><pre>Illegal column index {0}. {1}</pre></td></tr>
095     * <tr><td valign="top">Deutsch:</td><td valign="top"><pre>Ung&uuml;ltiger Spalten-Index {0}. {1}</pre></td></tr>
096     * </table>
097     * <li>"{@link #getIncrementColumnTitleMessage incrementColumnTitle}"<table>
098     * <tr><td valign="top">English:</td><td valign="top"><pre>Increment</pre></td></tr>
099     * <tr><td valign="top">Deutsch:</td><td valign="top"><pre>Inkrement</pre></td></tr>
100     * </table>
101     * <li>"{@link #getMaximumColumnTitleMessage maximumColumnTitle}"<table>
102     * <tr><td valign="top">English:</td><td valign="top"><pre>Maximum</pre></td></tr>
103     * <tr><td valign="top">Deutsch:</td><td valign="top"><pre>Maximum</pre></td></tr>
104     * </table>
105     * <li>"{@link #getMinimumColumnTitleMessage minimumColumnTitle}"<table>
106     * <tr><td valign="top">English:</td><td valign="top"><pre>Minimum</pre></td></tr>
107     * <tr><td valign="top">Deutsch:</td><td valign="top"><pre>Minimum</pre></td></tr>
108     * </table>
109     * <li>"{@link #getNameColumnTitleMessage nameColumnTitle}"<table>
110     * <tr><td valign="top">English:</td><td valign="top"><pre>Name</pre></td></tr>
111     * <tr><td valign="top">Deutsch:</td><td valign="top"><pre>Name</pre></td></tr>
112     * </table>
113     * <li>"{@link #getValueColumnTitleMessage valueColumnTitle}"<table>
114     * <tr><td valign="top">English:</td><td valign="top"><pre>Value</pre></td></tr>
115     * <tr><td valign="top">Deutsch:</td><td valign="top"><pre>Wert</pre></td></tr>
116     * </table>
117     * </ul></p>
118     *
119     * @author <a href="mailto:cs@jomc.org">Christian Schulte</a> 1.0
120     * @version $Id: SequencesTableModel.java 1478 2010-02-02 10:19:18Z schulte2005 $
121     */
122    // </editor-fold>
123    // SECTION-END
124    // SECTION-START[Annotations]
125    // <editor-fold defaultstate="collapsed" desc=" Generated Annotations ">
126    @javax.annotation.Generated( value = "org.jomc.tools.JavaSources",
127                                 comments = "See http://jomc.sourceforge.net/jomc/1.0-alpha-16/jomc-tools" )
128    // </editor-fold>
129    // SECTION-END
130    public class SequencesTableModel extends AbstractTableModel implements Serializable
131    {
132        // SECTION-START[TableModel]
133    
134        public int getRowCount()
135        {
136            try
137            {
138                return this.getSequences().size();
139            }
140            catch ( final SequencesSystemException e )
141            {
142                this.fireExceptionThrown( e );
143            }
144    
145            return 0;
146        }
147    
148        public int getColumnCount()
149        {
150            return COLUMN_COUNT;
151        }
152    
153        @Override
154        public String getColumnName( final int columnIndex )
155        {
156            final String columnName;
157    
158            switch ( columnIndex )
159            {
160                case NAME_COLUMN_INDEX:
161                    columnName = this.getNameColumnTitleMessage( this.getLocale() );
162                    break;
163    
164                case MINIMUM_COLUMN_INDEX:
165                    columnName = this.getMinimumColumnTitleMessage( this.getLocale() );
166                    break;
167    
168                case MAXIMUM_COLUMN_INDEX:
169                    columnName = this.getMaximumColumnTitleMessage( this.getLocale() );
170                    break;
171    
172                case INCREMENT_COLUMN_INDEX:
173                    columnName = this.getIncrementColumnTitleMessage( this.getLocale() );
174                    break;
175    
176                case VALUE_COLUMN_INDEX:
177                    columnName = this.getValueColumnTitleMessage( this.getLocale() );
178                    break;
179    
180                default:
181                    columnName = super.getColumnName( columnIndex );
182                    this.getLogger().warn( this.getIllegalColumnIndexMessage( this.getLocale(), columnIndex ) );
183                    break;
184    
185            }
186    
187            return columnName;
188        }
189    
190        @Override
191        public Class<?> getColumnClass( final int columnIndex )
192        {
193            final Class columnClass;
194    
195            switch ( columnIndex )
196            {
197                case NAME_COLUMN_INDEX:
198                    columnClass = String.class;
199                    break;
200    
201                case MINIMUM_COLUMN_INDEX:
202                case MAXIMUM_COLUMN_INDEX:
203                case INCREMENT_COLUMN_INDEX:
204                case VALUE_COLUMN_INDEX:
205                    columnClass = BigInteger.class;
206                    break;
207    
208                default:
209                    columnClass = super.getColumnClass( columnIndex );
210                    this.getLogger().warn( this.getIllegalColumnIndexMessage( this.getLocale(), columnIndex ) );
211                    break;
212    
213            }
214    
215            return columnClass;
216        }
217    
218        @Override
219        public boolean isCellEditable( final int rowIndex, final int columnIndex )
220        {
221            final boolean cellEditable;
222    
223            switch ( columnIndex )
224            {
225                case NAME_COLUMN_INDEX:
226                    cellEditable = this.getNameColumnEditable();
227                    break;
228    
229                case MINIMUM_COLUMN_INDEX:
230                    cellEditable = this.getMinimumColumnEditable();
231                    break;
232    
233                case MAXIMUM_COLUMN_INDEX:
234                    cellEditable = this.getMaximumColumnEditable();
235                    break;
236    
237                case INCREMENT_COLUMN_INDEX:
238                    cellEditable = this.getIncrementColumnEditable();
239                    break;
240    
241                case VALUE_COLUMN_INDEX:
242                    cellEditable = this.getValueColumnEditable();
243                    break;
244    
245                default:
246                    cellEditable = super.isCellEditable( rowIndex, columnIndex );
247                    this.getLogger().warn( this.getIllegalColumnIndexMessage( this.getLocale(), columnIndex ) );
248                    break;
249    
250            }
251    
252            return cellEditable;
253        }
254    
255        public Object getValueAt( final int rowIndex, final int columnIndex )
256        {
257            try
258            {
259                final Object value;
260                final Sequence sequence = this.getSequences().get( rowIndex );
261    
262                switch ( columnIndex )
263                {
264                    case NAME_COLUMN_INDEX:
265                        value = sequence.getName();
266                        break;
267    
268                    case MINIMUM_COLUMN_INDEX:
269                        value = sequence.getMinimum();
270                        break;
271    
272                    case MAXIMUM_COLUMN_INDEX:
273                        value = sequence.getMaximum();
274                        break;
275    
276                    case INCREMENT_COLUMN_INDEX:
277                        value = sequence.getIncrement();
278                        break;
279    
280                    case VALUE_COLUMN_INDEX:
281                        value = sequence.getValue();
282                        break;
283    
284                    default:
285                        value = null;
286                        this.getLogger().warn( this.getIllegalColumnIndexMessage( this.getLocale(), columnIndex ) );
287                        break;
288    
289                }
290    
291                return value;
292            }
293            catch ( final SequencesSystemException e )
294            {
295                this.fireExceptionThrown( e );
296            }
297            catch ( final IndexOutOfBoundsException e )
298            {
299                this.fireExceptionThrown( e );
300            }
301    
302            return null;
303        }
304    
305        @Override
306        public void setValueAt( final Object aValue, final int rowIndex, final int columnIndex )
307        {
308            try
309            {
310                final Sequence sequence = this.getSequences().get( rowIndex );
311                final String name = sequence.getName();
312                final long revision = sequence.getRevision();
313    
314                switch ( columnIndex )
315                {
316                    case NAME_COLUMN_INDEX:
317                        sequence.setName( aValue.toString() );
318                        break;
319    
320                    case MINIMUM_COLUMN_INDEX:
321                        sequence.setMinimum( (Long) aValue );
322                        break;
323    
324                    case MAXIMUM_COLUMN_INDEX:
325                        sequence.setMaximum( (Long) aValue );
326                        break;
327    
328                    case INCREMENT_COLUMN_INDEX:
329                        sequence.setIncrement( (Long) aValue );
330                        break;
331    
332                    case VALUE_COLUMN_INDEX:
333                        sequence.setValue( (Long) aValue );
334                        break;
335    
336                    default:
337                        this.getLogger().warn( this.getIllegalColumnIndexMessage( this.getLocale(), columnIndex ) );
338                        break;
339    
340                }
341    
342                if ( !Beans.isDesignTime() )
343                {
344                    this.getSequenceDirectory().editSequence( name, revision, sequence );
345                }
346    
347                this.fireTableRowsUpdated( rowIndex, rowIndex );
348            }
349            catch ( final SequencesException e )
350            {
351                this.fireExceptionThrown( e );
352                this.sequences = null;
353                this.fireTableDataChanged();
354            }
355            catch ( final SequencesSystemException e )
356            {
357                this.fireExceptionThrown( e );
358                this.sequences = null;
359                this.fireTableDataChanged();
360            }
361            catch ( final IndexOutOfBoundsException e )
362            {
363                this.fireExceptionThrown( e );
364                this.sequences = null;
365                this.fireTableDataChanged();
366            }
367        }
368    
369        // SECTION-END
370        // SECTION-START[SequencesTableModel]
371        /** Number of table columns. */
372        public static final int COLUMN_COUNT = 5;
373    
374        /** Index of the column displaying a sequence's name. */
375        public static final int NAME_COLUMN_INDEX = 0;
376    
377        /** Index of the column displaying a sequence's minimum value. */
378        public static final int MINIMUM_COLUMN_INDEX = 1;
379    
380        /** Index of the column displaying a sequence's maximum value. */
381        public static final int MAXIMUM_COLUMN_INDEX = 2;
382    
383        /** Index of the column displaying a sequence's increment value. */
384        public static final int INCREMENT_COLUMN_INDEX = 3;
385    
386        /** Index of the column displaying a sequence's value. */
387        public static final int VALUE_COLUMN_INDEX = 4;
388    
389        /** Name of property {@code nameColumnEditable}. */
390        public static final String NAME_COLUMN_EDITABLE =
391            "org.jomc.sequences.util.SequencesTableModel.NAME_COLUMN_EDITABLE";
392    
393        /** Name of property {@code minimumColumnEditable}. */
394        public static final String MINIMUM_COLUMN_EDITABLE =
395            "org.jomc.sequences.util.SequencesTableModel.MINIMUM_COLUMN_EDITABLE";
396    
397        /** Name of property {@code maximumColumnEditable}. */
398        public static final String MAXIMUM_COLUMN_EDITABLE =
399            "org.jomc.sequences.util.SequencesTableModel.MAXIMUM_COLUMN_EDITABLE";
400    
401        /** Name of property {@code incrementColumnEditable}. */
402        public static final String INCREMENT_COLUMN_EDITABLE =
403            "org.jomc.sequences.util.SequencesTableModel.INCREMENT_COLUMN_EDITABLE";
404    
405        /** Name of property {@code valueColumnEditable}. */
406        public static final String VALUE_COLUMN_EDITABLE =
407            "org.jomc.sequences.util.SequencesTableModel.VALUE_COLUMN_EDITABLE";
408    
409        /** Name of property {@code sequenceFilter}. */
410        public static final String SEQUENCE_FILTER =
411            "org.jomc.sequences.util.SequencesTableModel.SEQUENCE_FILTER";
412    
413        /**
414         * Flag indicating that the {@code name} column is editable.
415         * @serial
416         */
417        private Boolean nameColumnEditable;
418    
419        /**
420         * Flag indicating that the {@code minimum} column is editable.
421         * @serial
422         */
423        private Boolean minimumColumnEditable;
424    
425        /**
426         * Flag indicating that the {@code maximum} column is editable.
427         * @serial
428         */
429        private Boolean maximumColumnEditable;
430    
431        /**
432         * Flag indicating that the {@code increment} column is editable.
433         * @serial
434         */
435        private Boolean incrementColumnEditable;
436    
437        /**
438         * Flag indicating that the {@code value} column is editable.
439         * @serial
440         */
441        private Boolean valueColumnEditable;
442    
443        /**
444         * Entity filter.
445         * @serial
446         */
447        private Sequence sequenceFilter;
448    
449        /** Sequences of the model. */
450        private transient List<Sequence> sequences;
451    
452        /**
453         * Change support.
454         * @serial
455         */
456        private PropertyChangeSupport changeSupport = new SwingPropertyChangeSupport( this );
457    
458        /**
459         * Gets the flag indicating that the {@code name} column is editable.
460         *
461         * @return {@code true} if the {@code name} column is editable; {@code false} if not.
462         */
463        public Boolean getNameColumnEditable()
464        {
465            if ( this.nameColumnEditable == null )
466            {
467                this.nameColumnEditable = this.isNameColumnEditableByDefault();
468                this.changeSupport.firePropertyChange( NAME_COLUMN_EDITABLE, null, this.nameColumnEditable );
469            }
470    
471            return this.nameColumnEditable;
472        }
473    
474        /**
475         * Sets the flag indicating that the {@code name} column is editable.
476         *
477         * @param value {@code true} if the {@code name} column should be editable; {@code false} if not.
478         */
479        public void setNameColumnEditable( final Boolean value )
480        {
481            final Boolean oldValue = this.nameColumnEditable;
482            this.nameColumnEditable = value;
483            this.changeSupport.firePropertyChange( NAME_COLUMN_EDITABLE, oldValue, this.nameColumnEditable );
484        }
485    
486        /**
487         * Gets the flag indicating that the {@code minimum} column is editable.
488         *
489         * @return {@code true} if the {@code minimum} column is editable;{@code false} if not.
490         */
491        public Boolean getMinimumColumnEditable()
492        {
493            if ( this.minimumColumnEditable == null )
494            {
495                this.minimumColumnEditable = this.isMinimumColumnEditableByDefault();
496                this.changeSupport.firePropertyChange( MINIMUM_COLUMN_EDITABLE, null, this.minimumColumnEditable );
497            }
498    
499            return this.minimumColumnEditable;
500        }
501    
502        /**
503         * Set the flag indicating that the {@code minimum} column is editable.
504         *
505         * @param value {@code true} if the {@code minimum} column should be editable; {@code false} if not.
506         */
507        public void setMinimumColumnEditable( final Boolean value )
508        {
509            final Boolean oldValue = this.minimumColumnEditable;
510            this.minimumColumnEditable = value;
511            this.changeSupport.firePropertyChange( MINIMUM_COLUMN_EDITABLE, oldValue, this.minimumColumnEditable );
512        }
513    
514        /**
515         * Gets the flag indicating that the {@code maximum} column is editable.
516         *
517         * @return {@code true} if the {@code maximum} column is editable; {@code false} if not.
518         */
519        public Boolean getMaximumColumnEditable()
520        {
521            if ( this.maximumColumnEditable == null )
522            {
523                this.maximumColumnEditable = this.isMaximumColumnEditableByDefault();
524                this.changeSupport.firePropertyChange( MAXIMUM_COLUMN_EDITABLE, null, this.maximumColumnEditable );
525            }
526    
527            return this.maximumColumnEditable;
528        }
529    
530        /**
531         * Sets the flag indicating that the {@code maximum} column is editable.
532         *
533         * @param value {@code true} if the {@code maximum} column should be editable; {@code false} if not.
534         */
535        public void setMaximumColumnEditable( final Boolean value )
536        {
537            final Boolean oldValue = this.maximumColumnEditable;
538            this.maximumColumnEditable = value;
539            this.changeSupport.firePropertyChange( MAXIMUM_COLUMN_EDITABLE, oldValue, this.maximumColumnEditable );
540        }
541    
542        /**
543         * Gets the flag indicating that the {@code increment} column is editable.
544         *
545         * @return {@code true} if the {@code increment} column is editable; {@code false} if not.
546         */
547        public Boolean getIncrementColumnEditable()
548        {
549            if ( this.incrementColumnEditable == null )
550            {
551                this.incrementColumnEditable = this.isIncrementColumnEditableByDefault();
552                this.changeSupport.firePropertyChange( INCREMENT_COLUMN_EDITABLE, null, this.incrementColumnEditable );
553            }
554    
555            return this.incrementColumnEditable;
556        }
557    
558        /**
559         * Sets the flag indicating that the {@code increment} column is editable.
560         *
561         * @param value {@code true} if the {@code increment} column should be editable; {@code false} if not.
562         */
563        public void setIncrementColumnEditable( final Boolean value )
564        {
565            final Boolean oldValue = this.incrementColumnEditable;
566            this.incrementColumnEditable = value;
567            this.changeSupport.firePropertyChange( INCREMENT_COLUMN_EDITABLE, oldValue, this.incrementColumnEditable );
568        }
569    
570        /**
571         * Gets the flag indicating that the {@code value} column is editable.
572         *
573         * @return {@code true} if the {@code value} column is editable; {@code false} if not.
574         */
575        public Boolean getValueColumnEditable()
576        {
577            if ( this.valueColumnEditable == null )
578            {
579                this.valueColumnEditable = this.isValueColumnEditableByDefault();
580                this.changeSupport.firePropertyChange( VALUE_COLUMN_EDITABLE, null, this.valueColumnEditable );
581            }
582    
583            return this.valueColumnEditable;
584        }
585    
586        /**
587         * Sets the flag indicating that the {@code value} column is editable.
588         *
589         * @param value {@code true} if the {@code value} column should be editable; {@code false} if not.
590         */
591        public void setValueColumnEditable( final Boolean value )
592        {
593            final Boolean oldValue = this.valueColumnEditable;
594            this.valueColumnEditable = value;
595            this.changeSupport.firePropertyChange( VALUE_COLUMN_EDITABLE, oldValue, this.valueColumnEditable );
596        }
597    
598        /**
599         * Gets the entity used for filtering sequences.
600         *
601         * @return Entity used for filtering sequences or {@code null}.
602         */
603        public Sequence getSequenceFilter()
604        {
605            return this.sequenceFilter;
606        }
607    
608        /**
609         * Sets the entity used for filtering sequences.
610         *
611         * @param value Entity to use for filtering sequences or {@code null}.
612         */
613        public void setSequenceFilter( final Sequence value )
614        {
615            final Sequence oldValue = this.sequenceFilter;
616            this.sequenceFilter = value;
617            this.sequences = null;
618            this.fireTableDataChanged();
619            this.changeSupport.firePropertyChange( SEQUENCE_FILTER, oldValue, this.sequenceFilter );
620        }
621    
622        /**
623         * Add a {@code PropertyChangeListener} to the listener list.
624         * <p>The listener is registered for all properties. The same listener object may be added more than once, and will
625         * be called as many times as it is added. If {@code listener} is {@code null}, no exception is thrown and no action
626         * is taken.</p>
627         *
628         * @param listener The listener to be added.
629         */
630        public void addPropertyChangeListener( final PropertyChangeListener listener )
631        {
632            this.changeSupport.addPropertyChangeListener( listener );
633        }
634    
635        /**
636         * Removes a {@code PropertyChangeListener} from the listener list.
637         * <p>This removes a {@code PropertyChangeListener} that was registered for all properties. If {@code listener} was
638         * added more than once, it will be notified one less time after being removed. If {@code listener} is {@code null},
639         * or was never added, no exception is thrown and no action is taken.</p>
640         *
641         * @param listener The listener to be removed.
642         */
643        public void removePropertyChangeListener( final PropertyChangeListener listener )
644        {
645            this.changeSupport.removePropertyChangeListener( listener );
646        }
647    
648        /**
649         * Gets an array of all the listeners that were added to the instance.
650         * <p>If some listeners have been added with a named property, then the returned array will be a mixture of
651         * {@code PropertyChangeListeners} and {@code PropertyChangeListenerProxy}s. If the calling method is interested in
652         * distinguishing the listeners then it must test each element to see if it's a {@code PropertyChangeListenerProxy},
653         * perform the cast, and examine the parameter.</p>
654         *
655         * @return All of the {@code PropertyChangeListeners} added or an empty array if no listeners have been added.
656         *
657         * @see PropertyChangeSupport#getPropertyChangeListeners()
658         */
659        public PropertyChangeListener[] getPropertyChangeListeners()
660        {
661            return this.changeSupport.getPropertyChangeListeners();
662        }
663    
664        /**
665         * Add a {@code PropertyChangeListener} for a specific property.
666         * <p>The listener will be invoked only when an event for that specific property occurs. The same listener object
667         * may be added more than once. For each property, the listener will be invoked the number of times it was added for
668         * that property. If {@code propertyName} or {@code listener} is {@code null}, no exception is thrown and no action
669         * is taken.</p>
670         *
671         * @param propertyName The name of the property to listen on.
672         * @param listener The listener to be added.
673         */
674        public void addPropertyChangeListener( final String propertyName, final PropertyChangeListener listener )
675        {
676            this.changeSupport.addPropertyChangeListener( propertyName, listener );
677        }
678    
679        /**
680         * Removes a {@code PropertyChangeListener} for a specific property.
681         * <p>If {@code listener} was added more than once to the instance for the specified property, it will be notified
682         * one less time after being removed. If {@code propertyName} is {@code null}, no exception is thrown and no action
683         * is taken. If {@code listener} is {@code null}, or was never added for the specified property, no exception is
684         * thrown and no action is taken.</p>
685         *
686         * @param propertyName The name of the property that was listened on.
687         * @param listener The listener to be removed.
688         */
689        public void removePropertyChangeListener( final String propertyName, final PropertyChangeListener listener )
690        {
691            this.changeSupport.removePropertyChangeListener( propertyName, listener );
692        }
693    
694        /**
695         * Gets an array of all the listeners which have been associated with the named property.
696         *
697         * @param propertyName The name of the property being listened to.
698         *
699         * @return All of the {@code PropertyChangeListeners} associated with the named property. If no such listeners have
700         * been added, or if {@code propertyName} is {@code null}, an empty array is returned.
701         */
702        public PropertyChangeListener[] getPropertyChangeListeners( final String propertyName )
703        {
704            return this.changeSupport.getPropertyChangeListeners( propertyName );
705        }
706    
707        /**
708         * Gets the entities of the model.
709         *
710         * @return The entities of the model.
711         *
712         * @throws SequencesSystemException if searching entities fails.
713         */
714        public List<Sequence> getSequences()
715        {
716            if ( this.sequences == null )
717            {
718                this.sequences = new LinkedList<Sequence>();
719    
720                if ( !Beans.isDesignTime() )
721                {
722                    this.sequences.addAll( this.getSequenceDirectory().searchSequences(
723                        this.getSequenceFilter() != null ? this.getSequenceFilter().getName() : null ) );
724    
725                }
726            }
727    
728            return this.sequences;
729        }
730    
731        /**
732         * Notifies any available {@code ExceptionListener} whenever a recoverable exception has been caught.
733         *
734         * @param e The exception that was caught.
735         */
736        protected void fireExceptionThrown( final Exception e )
737        {
738            this.getLogger().error( e );
739    
740            if ( this.getExceptionListener() != null )
741            {
742                for ( ExceptionListener l : this.getExceptionListener() )
743                {
744                    l.exceptionThrown( e );
745                }
746            }
747        }
748    
749        // SECTION-END
750        // SECTION-START[Constructors]
751        // <editor-fold defaultstate="collapsed" desc=" Generated Constructors ">
752    
753        /** Creates a new {@code SequencesTableModel} instance. */
754        @javax.annotation.Generated( value = "org.jomc.tools.JavaSources",
755                                     comments = "See http://jomc.sourceforge.net/jomc/1.0-alpha-16/jomc-tools" )
756        public SequencesTableModel()
757        {
758            // SECTION-START[Default Constructor]
759            super();
760            // SECTION-END
761        }
762        // </editor-fold>
763        // SECTION-END
764        // SECTION-START[Dependencies]
765        // <editor-fold defaultstate="collapsed" desc=" Generated Dependencies ">
766    
767        /**
768         * Gets the {@code ExceptionListener} dependency.
769         * <p>This method returns any available object of the {@code java.beans.ExceptionListener} specification at specification level 1.4.</p>
770         * <p>That specification does not apply to any scope. A new object is returned whenever requested and bound to this instance.</p>
771         * @return The {@code ExceptionListener} dependency.
772         * {@code null} if no object is available.
773         * @throws org.jomc.ObjectManagementException if getting the dependency instance fails.
774         */
775        @javax.annotation.Generated( value = "org.jomc.tools.JavaSources",
776                                     comments = "See http://jomc.sourceforge.net/jomc/1.0-alpha-16/jomc-tools" )
777        private java.beans.ExceptionListener[] getExceptionListener()
778        {
779            return (java.beans.ExceptionListener[]) org.jomc.ObjectManagerFactory.getObjectManager( this.getClass().getClassLoader() ).getDependency( this, "ExceptionListener" );
780        }
781    
782        /**
783         * Gets the {@code Locale} dependency.
784         * <p>This method returns the "{@code default}" object of the {@code java.util.Locale} specification at specification level 1.1.</p>
785         * <p>That specification does not apply to any scope. A new object is returned whenever requested and bound to this instance.</p>
786         * @return The {@code Locale} dependency.
787         * @throws org.jomc.ObjectManagementException if getting the dependency instance fails.
788         */
789        @javax.annotation.Generated( value = "org.jomc.tools.JavaSources",
790                                     comments = "See http://jomc.sourceforge.net/jomc/1.0-alpha-16/jomc-tools" )
791        private java.util.Locale getLocale()
792        {
793            final java.util.Locale _d = (java.util.Locale) org.jomc.ObjectManagerFactory.getObjectManager( this.getClass().getClassLoader() ).getDependency( this, "Locale" );
794            assert _d != null : "'Locale' dependency not found.";
795            return _d;
796        }
797    
798        /**
799         * Gets the {@code Logger} dependency.
800         * <p>This method returns any available object of the {@code org.jomc.logging.Logger} specification at specification level 1.0.</p>
801         * <p>That specification does not apply to any scope. A new object is returned whenever requested and bound to this instance.</p>
802         * <p><b>Properties</b><dl>
803         * <dt>"{@code name}"</dt>
804         * <dd>Property of type {@code java.lang.String}.
805         * </dd>
806         * </dl>
807         * @return The {@code Logger} dependency.
808         * @throws org.jomc.ObjectManagementException if getting the dependency instance fails.
809         */
810        @javax.annotation.Generated( value = "org.jomc.tools.JavaSources",
811                                     comments = "See http://jomc.sourceforge.net/jomc/1.0-alpha-16/jomc-tools" )
812        private org.jomc.logging.Logger getLogger()
813        {
814            final org.jomc.logging.Logger _d = (org.jomc.logging.Logger) org.jomc.ObjectManagerFactory.getObjectManager( this.getClass().getClassLoader() ).getDependency( this, "Logger" );
815            assert _d != null : "'Logger' dependency not found.";
816            return _d;
817        }
818    
819        /**
820         * Gets the {@code SequenceDirectory} dependency.
821         * <p>This method returns any available object of the {@code org.jomc.sequences.SequenceDirectory} specification at specification level 1.0.</p>
822         * <p>That specification applies to {@code Singleton} scope. The singleton object is returned whenever requested and bound to this instance.</p>
823         * @return The {@code SequenceDirectory} dependency.
824         * @throws org.jomc.ObjectManagementException if getting the dependency instance fails.
825         */
826        @javax.annotation.Generated( value = "org.jomc.tools.JavaSources",
827                                     comments = "See http://jomc.sourceforge.net/jomc/1.0-alpha-16/jomc-tools" )
828        private org.jomc.sequences.SequenceDirectory getSequenceDirectory()
829        {
830            final org.jomc.sequences.SequenceDirectory _d = (org.jomc.sequences.SequenceDirectory) org.jomc.ObjectManagerFactory.getObjectManager( this.getClass().getClassLoader() ).getDependency( this, "SequenceDirectory" );
831            assert _d != null : "'SequenceDirectory' dependency not found.";
832            return _d;
833        }
834        // </editor-fold>
835        // SECTION-END
836        // SECTION-START[Properties]
837        // <editor-fold defaultstate="collapsed" desc=" Generated Properties ">
838    
839        /**
840         * Gets the value of the {@code incrementColumnEditableByDefault} property.
841         * @return Flag indicating that the &quot;increment&quot; column is editable by default.
842         * @throws org.jomc.ObjectManagementException if getting the property instance fails.
843         */
844        @javax.annotation.Generated( value = "org.jomc.tools.JavaSources",
845                                     comments = "See http://jomc.sourceforge.net/jomc/1.0-alpha-16/jomc-tools" )
846        private java.lang.Boolean isIncrementColumnEditableByDefault()
847        {
848            final java.lang.Boolean _p = (java.lang.Boolean) org.jomc.ObjectManagerFactory.getObjectManager( this.getClass().getClassLoader() ).getProperty( this, "incrementColumnEditableByDefault" );
849            assert _p != null : "'incrementColumnEditableByDefault' property not found.";
850            return _p;
851        }
852    
853        /**
854         * Gets the value of the {@code maximumColumnEditableByDefault} property.
855         * @return Flag indicating that the &quot;maximum&quot; column is editable by default.
856         * @throws org.jomc.ObjectManagementException if getting the property instance fails.
857         */
858        @javax.annotation.Generated( value = "org.jomc.tools.JavaSources",
859                                     comments = "See http://jomc.sourceforge.net/jomc/1.0-alpha-16/jomc-tools" )
860        private java.lang.Boolean isMaximumColumnEditableByDefault()
861        {
862            final java.lang.Boolean _p = (java.lang.Boolean) org.jomc.ObjectManagerFactory.getObjectManager( this.getClass().getClassLoader() ).getProperty( this, "maximumColumnEditableByDefault" );
863            assert _p != null : "'maximumColumnEditableByDefault' property not found.";
864            return _p;
865        }
866    
867        /**
868         * Gets the value of the {@code minimumColumnEditableByDefault} property.
869         * @return Flag indicating that the &quot;minimum&quot; column is editable by default.
870         * @throws org.jomc.ObjectManagementException if getting the property instance fails.
871         */
872        @javax.annotation.Generated( value = "org.jomc.tools.JavaSources",
873                                     comments = "See http://jomc.sourceforge.net/jomc/1.0-alpha-16/jomc-tools" )
874        private java.lang.Boolean isMinimumColumnEditableByDefault()
875        {
876            final java.lang.Boolean _p = (java.lang.Boolean) org.jomc.ObjectManagerFactory.getObjectManager( this.getClass().getClassLoader() ).getProperty( this, "minimumColumnEditableByDefault" );
877            assert _p != null : "'minimumColumnEditableByDefault' property not found.";
878            return _p;
879        }
880    
881        /**
882         * Gets the value of the {@code nameColumnEditableByDefault} property.
883         * @return Flag indicating that the &quot;name&quot; column is editable by default.
884         * @throws org.jomc.ObjectManagementException if getting the property instance fails.
885         */
886        @javax.annotation.Generated( value = "org.jomc.tools.JavaSources",
887                                     comments = "See http://jomc.sourceforge.net/jomc/1.0-alpha-16/jomc-tools" )
888        private java.lang.Boolean isNameColumnEditableByDefault()
889        {
890            final java.lang.Boolean _p = (java.lang.Boolean) org.jomc.ObjectManagerFactory.getObjectManager( this.getClass().getClassLoader() ).getProperty( this, "nameColumnEditableByDefault" );
891            assert _p != null : "'nameColumnEditableByDefault' property not found.";
892            return _p;
893        }
894    
895        /**
896         * Gets the value of the {@code valueColumnEditableByDefault} property.
897         * @return Flag indicating that the &quot;value&quot; column is editable by default.
898         * @throws org.jomc.ObjectManagementException if getting the property instance fails.
899         */
900        @javax.annotation.Generated( value = "org.jomc.tools.JavaSources",
901                                     comments = "See http://jomc.sourceforge.net/jomc/1.0-alpha-16/jomc-tools" )
902        private java.lang.Boolean isValueColumnEditableByDefault()
903        {
904            final java.lang.Boolean _p = (java.lang.Boolean) org.jomc.ObjectManagerFactory.getObjectManager( this.getClass().getClassLoader() ).getProperty( this, "valueColumnEditableByDefault" );
905            assert _p != null : "'valueColumnEditableByDefault' property not found.";
906            return _p;
907        }
908        // </editor-fold>
909        // SECTION-END
910        // SECTION-START[Messages]
911        // <editor-fold defaultstate="collapsed" desc=" Generated Messages ">
912    
913        /**
914         * Gets the text of the {@code illegalColumnIndex} message.
915         * <p><b>Templates</b><br/><table>
916         * <tr><td valign="top">English:</td><td valign="top"><pre>Illegal column index {0}. {1}</pre></td></tr>
917         * <tr><td valign="top">Deutsch:</td><td valign="top"><pre>Ung&uuml;ltiger Spalten-Index {0}. {1}</pre></td></tr>
918         * </table></p>
919         * @param locale The locale of the message to return.
920         * @param columnIndex Format argument.
921         * @return The text of the {@code illegalColumnIndex} message.
922         *
923         * @throws org.jomc.ObjectManagementException if getting the message instance fails.
924         */
925        @javax.annotation.Generated( value = "org.jomc.tools.JavaSources",
926                                     comments = "See http://jomc.sourceforge.net/jomc/1.0-alpha-16/jomc-tools" )
927        private String getIllegalColumnIndexMessage( final java.util.Locale locale, final java.lang.Number columnIndex )
928        {
929            final String _m = org.jomc.ObjectManagerFactory.getObjectManager( this.getClass().getClassLoader() ).getMessage( this, "illegalColumnIndex", locale, columnIndex );
930            assert _m != null : "'illegalColumnIndex' message not found.";
931            return _m;
932        }
933    
934        /**
935         * Gets the text of the {@code incrementColumnTitle} message.
936         * <p><b>Templates</b><br/><table>
937         * <tr><td valign="top">English:</td><td valign="top"><pre>Increment</pre></td></tr>
938         * <tr><td valign="top">Deutsch:</td><td valign="top"><pre>Inkrement</pre></td></tr>
939         * </table></p>
940         * @param locale The locale of the message to return.
941         * @return The text of the {@code incrementColumnTitle} message.
942         *
943         * @throws org.jomc.ObjectManagementException if getting the message instance fails.
944         */
945        @javax.annotation.Generated( value = "org.jomc.tools.JavaSources",
946                                     comments = "See http://jomc.sourceforge.net/jomc/1.0-alpha-16/jomc-tools" )
947        private String getIncrementColumnTitleMessage( final java.util.Locale locale )
948        {
949            final String _m = org.jomc.ObjectManagerFactory.getObjectManager( this.getClass().getClassLoader() ).getMessage( this, "incrementColumnTitle", locale );
950            assert _m != null : "'incrementColumnTitle' message not found.";
951            return _m;
952        }
953    
954        /**
955         * Gets the text of the {@code maximumColumnTitle} message.
956         * <p><b>Templates</b><br/><table>
957         * <tr><td valign="top">English:</td><td valign="top"><pre>Maximum</pre></td></tr>
958         * <tr><td valign="top">Deutsch:</td><td valign="top"><pre>Maximum</pre></td></tr>
959         * </table></p>
960         * @param locale The locale of the message to return.
961         * @return The text of the {@code maximumColumnTitle} message.
962         *
963         * @throws org.jomc.ObjectManagementException if getting the message instance fails.
964         */
965        @javax.annotation.Generated( value = "org.jomc.tools.JavaSources",
966                                     comments = "See http://jomc.sourceforge.net/jomc/1.0-alpha-16/jomc-tools" )
967        private String getMaximumColumnTitleMessage( final java.util.Locale locale )
968        {
969            final String _m = org.jomc.ObjectManagerFactory.getObjectManager( this.getClass().getClassLoader() ).getMessage( this, "maximumColumnTitle", locale );
970            assert _m != null : "'maximumColumnTitle' message not found.";
971            return _m;
972        }
973    
974        /**
975         * Gets the text of the {@code minimumColumnTitle} message.
976         * <p><b>Templates</b><br/><table>
977         * <tr><td valign="top">English:</td><td valign="top"><pre>Minimum</pre></td></tr>
978         * <tr><td valign="top">Deutsch:</td><td valign="top"><pre>Minimum</pre></td></tr>
979         * </table></p>
980         * @param locale The locale of the message to return.
981         * @return The text of the {@code minimumColumnTitle} message.
982         *
983         * @throws org.jomc.ObjectManagementException if getting the message instance fails.
984         */
985        @javax.annotation.Generated( value = "org.jomc.tools.JavaSources",
986                                     comments = "See http://jomc.sourceforge.net/jomc/1.0-alpha-16/jomc-tools" )
987        private String getMinimumColumnTitleMessage( final java.util.Locale locale )
988        {
989            final String _m = org.jomc.ObjectManagerFactory.getObjectManager( this.getClass().getClassLoader() ).getMessage( this, "minimumColumnTitle", locale );
990            assert _m != null : "'minimumColumnTitle' message not found.";
991            return _m;
992        }
993    
994        /**
995         * Gets the text of the {@code nameColumnTitle} message.
996         * <p><b>Templates</b><br/><table>
997         * <tr><td valign="top">English:</td><td valign="top"><pre>Name</pre></td></tr>
998         * <tr><td valign="top">Deutsch:</td><td valign="top"><pre>Name</pre></td></tr>
999         * </table></p>
1000         * @param locale The locale of the message to return.
1001         * @return The text of the {@code nameColumnTitle} message.
1002         *
1003         * @throws org.jomc.ObjectManagementException if getting the message instance fails.
1004         */
1005        @javax.annotation.Generated( value = "org.jomc.tools.JavaSources",
1006                                     comments = "See http://jomc.sourceforge.net/jomc/1.0-alpha-16/jomc-tools" )
1007        private String getNameColumnTitleMessage( final java.util.Locale locale )
1008        {
1009            final String _m = org.jomc.ObjectManagerFactory.getObjectManager( this.getClass().getClassLoader() ).getMessage( this, "nameColumnTitle", locale );
1010            assert _m != null : "'nameColumnTitle' message not found.";
1011            return _m;
1012        }
1013    
1014        /**
1015         * Gets the text of the {@code valueColumnTitle} message.
1016         * <p><b>Templates</b><br/><table>
1017         * <tr><td valign="top">English:</td><td valign="top"><pre>Value</pre></td></tr>
1018         * <tr><td valign="top">Deutsch:</td><td valign="top"><pre>Wert</pre></td></tr>
1019         * </table></p>
1020         * @param locale The locale of the message to return.
1021         * @return The text of the {@code valueColumnTitle} message.
1022         *
1023         * @throws org.jomc.ObjectManagementException if getting the message instance fails.
1024         */
1025        @javax.annotation.Generated( value = "org.jomc.tools.JavaSources",
1026                                     comments = "See http://jomc.sourceforge.net/jomc/1.0-alpha-16/jomc-tools" )
1027        private String getValueColumnTitleMessage( final java.util.Locale locale )
1028        {
1029            final String _m = org.jomc.ObjectManagerFactory.getObjectManager( this.getClass().getClassLoader() ).getMessage( this, "valueColumnTitle", locale );
1030            assert _m != null : "'valueColumnTitle' message not found.";
1031            return _m;
1032        }
1033        // </editor-fold>
1034        // SECTION-END
1035    }