Newer
Older
/* SimpleEntryGroup.java
*
* created: Wed Nov 11 1998
*
* This file is part of Artemis
*
* Copyright(C) 1998,1999,2000,2001,2002 Genome Research Limited
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or(at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* $Header: //tmp/pathsoft/artemis/uk/ac/sanger/artemis/SimpleEntryGroup.java,v 1.8 2008-06-11 15:15:23 tjc Exp $
**/
package uk.ac.sanger.artemis;
import uk.ac.sanger.artemis.sequence.*;
import uk.ac.sanger.artemis.io.GFFDocumentEntry;
import uk.ac.sanger.artemis.io.IndexedGFFDocumentEntry;
import uk.ac.sanger.artemis.io.Range;
import uk.ac.sanger.artemis.io.StreamSequence;
import uk.ac.sanger.artemis.io.SimpleDocumentEntry;
import uk.ac.sanger.artemis.io.DatabaseDocumentEntry;
import uk.ac.sanger.artemis.io.DocumentEntry;
import uk.ac.sanger.artemis.util.DatabaseDocument;
import uk.ac.sanger.artemis.util.ReadOnlyException;
import uk.ac.sanger.artemis.util.OutOfRangeException;
import java.util.Vector;
import java.util.NoSuchElementException;
/**
* This class implements a vector of Entry objects, with additional methods
* for querying and changing the feature tables of all the entries at
* once. Objects of this class act a bit like single Entry objects.
*
* @author Kim Rutherford
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
**/
public class SimpleEntryGroup extends EntryVector
implements EntryGroup
{
/** vector of those objects listening for entry change events. */
final private Vector entry_group_listener_list = new Vector();
/** vector of those objects listening for entry change events. */
final private Vector entry_listener_list = new Vector();
/** vector of those objects listening for feature change events. */
final private Vector feature_listener_list = new Vector();
/** vector of entries that are currently active (visible). */
final private EntryVector active_entries = new EntryVector();
/**
* The default Entry for this SimpleEntryGroup. The "default" is the Entry
* where new features are created.
**/
private Entry default_entry = null;
/** Bases object that was passed to the constructor. */
private Bases bases;
/** Incremented by ref(), decremented by unref(). */
private int reference_count = 0;
/** The ActionController of this EntryGroup (used for undo). */
final private ActionController action_controller = new ActionController();
/**
* Create a new empty SimpleEntryGroup object.
**/
public SimpleEntryGroup(final Bases bases)
{
this.bases = bases;
addFeatureChangeListener(getActionController());
addEntryChangeListener(getActionController());
getBases().addSequenceChangeListener(getActionController(),
Bases.MIN_PRIORITY);
addEntryGroupChangeListener(getActionController());
}
public SimpleEntryGroup()
{
addFeatureChangeListener(getActionController());
addEntryGroupChangeListener(getActionController());
}
/**
* Returns true if and only if there are any unsaved changes in any of the
* Entry objects in this EntryGroup.
**/
public boolean hasUnsavedChanges()
{
final int my_size = size();
for(int entry_index = 0; entry_index < my_size;
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
++entry_index)
{
if(elementAt(entry_index).hasUnsavedChanges())
return true;
}
return false;
}
/**
* Return the default Entry for this SimpleEntryGroup. The "default" is the
* Entry where new features are created.
**/
public Entry getDefaultEntry()
{
return default_entry;
}
/**
* Set the default Entry. The "default" is the Entry where new features
* are created.
* @param entry The new default entry. If this Entry is not active this
* method will return immediately.
**/
public void setDefaultEntry(Entry entry)
{
if(entry != null && !isActive(entry))
return;
// do nothing
if(default_entry == entry)
return;
else
default_entry = entry;
// now inform the listeners that a change has occured
final EntryGroupChangeEvent event =
new EntryGroupChangeEvent(this, getDefaultEntry(),
EntryGroupChangeEvent.NEW_DEFAULT_ENTRY);
fireEvent(entry_group_listener_list, event);
}
/**
* Return the index of a feature within this object. This method treats
* all the features in all the active entries as if they were in one big
* array. The first feature of the first entry will have index 1, the
* first from the second entry will have index 1 +(the number of features
* in the first entry), etc.
* @param feature The feature to find the index of.
* @return The index of the feature or -1 if the feature isn't in any of
* the entries. The first index is 0 the last is the total number of
* features in all the entries of this object minus one.
**/
public int indexOf(Feature feature)
{
int feature_count_of_previous_entries = 0;
final int feature_index = this_entry.indexOf(feature);
if(feature_index != -1)
return feature_index + feature_count_of_previous_entries;
feature_count_of_previous_entries += this_entry.getFeatureCount();
}
return -1;
}
/**
* Return true if any of the active entries in the group contains the given
* feature.
**/
public boolean contains(Feature feature)
{
final int active_entries_size = active_entries.size();
for(int i = 0; i < active_entries_size; ++i)
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
{
final Entry current_entry = active_entries.elementAt(i);
if(current_entry.contains(feature))
return true;
}
return false;
}
/**
* Return true if the given Entry is active(visible). The Feature objects
* in an Entry that is not active will be ignored by the methods that deal
* will features: featureAt(), indexOf(), contains(), features(), etc.
**/
public boolean isActive(Entry entry)
{
if(active_entries.contains(entry))
return true;
else
return false;
}
/**
* Set the "active" setting of the Entry at the given index. If the index
* refers to the default entry and new_active is false, the default entry
* will be set to the active entry or null if there are no active entries.
* @param index The index of the Entry to change.
* @param active The new active setting.
**/
public void setIsActive(int index, boolean new_active)
{
final Entry entry = elementAt(index);
if(new_active)
{
// no change
if(isActive(entry))
return;
else
{
// this is slow but it guarantees that the Entry references in the
// active_entries vector are in the same order as in the
// SimpleEntryGroup
final EntryVector new_active_entries = new EntryVector();
{
if(active_entries.contains(elementAt(i)) || index == i)
new_active_entries.add(elementAt(i));
}
active_entries.removeAllElements();
final int new_active_entries_size = new_active_entries.size();
for(int i = 0; i < new_active_entries_size; ++i)
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
active_entries.add(new_active_entries.elementAt(i));
if(active_entries.size() >= 1 && getDefaultEntry() == null)
{
// there was no default entry before calling addElement() so
// make the first non-sequence entry the default entry
if(active_entries.elementAt(0) == getSequenceEntry() &&
active_entries.size() == 1)
{
// don't set the default entry to be the sequence entry unless
// the user asks for it
setDefaultEntry(null);
}
else
{
if(active_entries.size() == 1)
setDefaultEntry(active_entries.elementAt(0));
else
setDefaultEntry(active_entries.elementAt(1));
}
}
}
}
else
{
// no change
if(!isActive(entry))
return;
else
{
active_entries.removeElement(entry);
if(entry == getDefaultEntry())
{
if(active_entries.size() > 0)
{
if(active_entries.elementAt(0) == getSequenceEntry())
{
// don't set the default entry to be the sequence entry unless
// the user asks for it
if(active_entries.size() > 1)
setDefaultEntry(active_entries.elementAt(1));
else
setDefaultEntry(null);
}
else
setDefaultEntry(active_entries.elementAt(0));
}
else
setDefaultEntry(null);
}
}
}
// now inform the listeners that a change has occured
final EntryGroupChangeEvent event;
// change state
if(new_active) // become active
event = new EntryGroupChangeEvent(this, entry,
EntryGroupChangeEvent.ENTRY_ACTIVE);
else // become inactive
event = new EntryGroupChangeEvent(this, entry,
EntryGroupChangeEvent.ENTRY_INACTIVE);
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
fireEvent(entry_group_listener_list, event);
}
/**
* Set the "active" setting of the given Entry. The Entry is the default
* entry and new_active is false, the default entry will be set to the
* active entry or null if there are no active entries.
* @param entry The Entry to activate or deactivate.
* @param new_active The new active setting.
**/
public void setIsActive(final Entry entry, final boolean new_active)
{
setIsActive(indexOf(entry), new_active);
}
/**
* Return the Entry from this SimpleEntryGroup that contains the sequence
* to view or return null if none of the entries contains a sequence.
**/
public Entry getSequenceEntry()
{
if(size() == 0)
return null;
else
return elementAt(0);
}
/**
* Returns the base length of the sequence of the first Entry in this group
* or 0 if this group is empty.
**/
public int getSequenceLength()
{
return getBases().getLength();
}
/**
* Returns the Bases object of the first Entry in this group or null if
* this group is empty.
**/
public Bases getBases()
{
return bases;
}
/**
* Reverse and complement the sequence and all features in every Entry in
* this SimpleEntryGroup.
**/
public void reverseComplement()
throws ReadOnlyException
{
if(isReadOnly())
throw new ReadOnlyException();
// reverse the sequence
getBases().reverseComplement();
}
/**
* Return true if and only if one or more of the entries or features in
* this SimpleEntryGroup are read-only.
**/
public boolean isReadOnly()
{
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
{
final Entry this_entry = elementAt(i);
if(this_entry.isReadOnly())
return true;
final FeatureEnumeration feature_enum = this_entry.features();
while(feature_enum.hasMoreFeatures())
{
if(feature_enum.nextFeature().isReadOnly())
return true;
}
}
return false;
}
/**
* Increment the reference count for this EntryGroup.
**/
public void ref()
{
++reference_count;
}
/**
* Decrement the reference count for this EntryGroup. When the reference
* count goes to zero a EntryGroupChangeEvent is sent to all
* EntryGroupChangeListeners with type EntryGroupChangeEvent.DONE_GONE.
* The listeners should then stop using the EntryGroup and release any
* associated resources.
**/
public void unref()
{
--reference_count;
if(reference_count == 0)
{
// remove all the entries which will close any edit or view windows
while(size() > 0)
{
final Entry this_entry = elementAt(0);
remove(this_entry);
this_entry.getEMBLEntry().dispose();
}
// now inform the listeners that the EntryGroup is no more
final EntryGroupChangeEvent event =
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
EntryGroupChangeEvent.DONE_GONE);
fireEvent(entry_group_listener_list, event);
}
}
/**
* Return the current reference count.
**/
public int refCount()
{
return reference_count;
}
/**
* Return the Feature at the given index. This method treats all the
* features in all the entries as if they were in one big array. See
* the comment on indexOf().
* @param index The index of the required Feature.
* @return The Feature at the given index. The first index is 0 the last
* is the total number of features in all the entries of this object minus
* one. If the index is out of range then null will be returned.
**/
public Feature featureAt(int index)
{
if(index < 0)
throw new Error("internal error - index out of range: " + index);
++entry_index)
{
final Entry this_entry = active_entries.elementAt(entry_index);
if(index < this_entry.getFeatureCount())
return this_entry.getFeature(index);
index -= this_entry.getFeatureCount();
}
throw new Error("internal error - index out of range: " + index);
}
/**
* Return a vector containing the references of the Feature objects within
* the given range of indices.
* @param start_index The index of the first feature to return.
* @param end_index The index of the last feature to return.
**/
public FeatureVector getFeaturesInIndexRange(final int start_index,
final int end_index)
{
final FeatureVector return_vector = new FeatureVector();
return_vector.add(featureAt(i));
return return_vector;
}
/**
* Return a vector containing the references of the Feature objects within
* the given range for all the active entries in the SimpleEntryGroup.
* @param range Return features that overlap this range - ie the start of
* the feature is less than or equal to the end of the range and the end
* of the feature is greater than or equal to the start of the range.
* @return The non-source key features of this feature table the are within
* the given range. The returned object is a copy - changes will not
* effect the FeatureTable object itself.
**/
public FeatureVector getFeaturesInRange(Range range)
throws OutOfRangeException
{
final FeatureVector return_vector = new FeatureVector();
{
final Entry this_entry = elementAt(i);
if(isActive(this_entry))
{
final FeatureVector visible_entry_features =
elementAt(i).getFeaturesInRange(range);
final int visible_entry_features_size = visible_entry_features.size();
for(int feature_index = 0; feature_index < visible_entry_features_size;
++feature_index)
{
final Feature this_feature =
visible_entry_features.elementAt(feature_index);
return_vector.add(this_feature);
}
}
}
return return_vector;
}
/**
* Return a vector containing the references of the Feature objects from
* all the active entries in the SimpleEntryGroup.
* @return The non-source key features in active entries of this
* SimpleEntryGroup. The returned object is a copy - changes will not
* effect the SimpleEntryGroup object itself.
**/
public FeatureVector getAllFeatures()
{
final FeatureVector return_vector = new FeatureVector();
{
final Entry this_entry = elementAt(i);
if(isActive(this_entry))
{
final FeatureVector entry_features = elementAt(i).getAllFeatures();
++feature_index)
{
final Feature this_feature =
entry_features.elementAt(feature_index);
return_vector.add(this_feature);
}
}
}
return return_vector;
}
/**
* Return a count of the number of Feature objects from all the active
* entries in the SimpleEntryGroup.
* @return A count of the non-source key features in active entries of this
* SimpleEntryGroup.
**/
public int getAllFeaturesCount()
{
int return_count = 0;
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
{
final Entry this_entry = elementAt(i);
if(isActive(this_entry))
return_count += this_entry.getFeatureCount();
}
return return_count;
}
/**
* Add an Entry to this object and then emit the appropriate EntryChange
* events.
**/
public void addElement(Entry entry)
{
super.addElement(entry);
// set the default Entry to whichever Entry gets added first
if(default_entry == null)
default_entry = entry;
active_entries.add(entry);
// now inform the listeners that an addition has occured
final EntryGroupChangeEvent event =
new EntryGroupChangeEvent(this, entry,
EntryGroupChangeEvent.ENTRY_ADDED);
fireEvent(entry_group_listener_list, event);
// make the new entry the default entry if and only if there was no entry
// previously or there was only one entry previously and it contained
// sequence but no features
if(size() == 1)
setDefaultEntry(entry);
else
{
if(size() == 2)
{
final Entry first_entry = elementAt(0);
if(first_entry.getFeatureCount() == 0)
{
final Bases first_entry_bases = first_entry.getBases();
if(first_entry_bases != null &&
setDefaultEntry(entry);
}
}
}
entry.addEntryChangeListener(this);
entry.addFeatureChangeListener(this);
}
/**
* A convenience method that does the same as addElement(Entry).
**/
public void add(final Entry entry)
{
if(entry.getEMBLEntry() instanceof IndexedGFFDocumentEntry)
((IndexedGFFDocumentEntry)entry.getEMBLEntry()).setEntryGroup(this);
else if(entry.getEMBLEntry() instanceof GFFDocumentEntry)
((GFFDocumentEntry)entry.getEMBLEntry()).adjustCoordinates( getSequenceEntry() );
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
addElement(entry);
}
/**
* Remove an Entry from this object and then emit the appropriate
* EntryGroupChange events. The first entry in the group can only be
* removed if it is the only Entry because the first Entry contains the
* sequence.
* @return true if the removal succeeded, false if it fails(which can if
* the given Entry isn't in this SimpleEntryGroup or if the user tries to
* remove the first Entry).
**/
public boolean removeElement(final Entry entry)
{
// this call will sort out the default entry
setIsActive(indexOf(entry), false);
entry.dispose();
final boolean remove_return = super.removeElement(entry);
entry.removeEntryChangeListener(this);
entry.removeFeatureChangeListener(this);
active_entries.removeElement(entry);
// now inform the listeners that a deletion has occured
final EntryGroupChangeEvent event =
new EntryGroupChangeEvent(this, entry,
EntryGroupChangeEvent.ENTRY_DELETED);
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
fireEvent(entry_group_listener_list, event);
return remove_return;
}
/**
* A convenience method that does the same as removeElement(Entry).
**/
public boolean remove(final Entry entry)
{
return removeElement(entry);
}
/**
* Create a new(blank) Feature in the default Entry of this
* SimpleEntryGroup. See getDefaultEntry() and Entry.createFeature().
* @return The new Feature.
**/
public Feature createFeature() throws ReadOnlyException
{
final Feature new_feature = getDefaultEntry().createFeature();
return new_feature;
}
/**
* Create a new(empty) Entry in this SimpleEntryGroup. See
* Entry.newEntry().
* @return The reference of the new Entry.
**/
public Entry createEntry()
{
Entry new_entry = null;
Entry default_entry = getDefaultEntry();
if(default_entry != null &&
default_entry.getEMBLEntry() != null &&
default_entry.getEMBLEntry() instanceof DatabaseDocumentEntry)
{
DatabaseDocument doc =
(DatabaseDocument)((DocumentEntry)default_entry.getEMBLEntry()).getDocument();
DatabaseDocument new_doc = doc.createDatabaseDocument();
try
{
DatabaseDocumentEntry new_doc_entry =
new DatabaseDocumentEntry();
new_doc_entry.setDocument(new_doc);
new_entry = new Entry(getBases(), new_doc_entry);
}
catch(Exception e)
{
e.printStackTrace();
}
}
else
new_entry = Entry.newEntry(getBases());
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
add(new_entry);
return new_entry;
}
/**
* Create a new(empty) Entry in this SimpleEntryGroup. See
* Entry.newEntry().
* @param name The(file) name of the new Entry.
* @return The reference of the new Entry.
**/
public Entry createEntry(final String name)
{
final Entry new_entry = createEntry();
new_entry.setName(name);
return new_entry;
}
/**
* Returns an enumeration of the Feature objects in this
* SimpleEntryGroup. The returned FeatureEnumeration object will generate
* all features in this object in turn. The first item generated is the
* item at index 0, then the item at index 1, and so on.
**/
public FeatureEnumeration features()
{
return new FeatureEnumerator();
}
/**
* An Enumeration of Feature objects.
**/
public class FeatureEnumerator implements FeatureEnumeration
{
/**
* The EntryVector object that we are enumerating. Set to null when there
* are no more Feature objects.
**/
private EntryVector active_entries;
/**
* The index of the Entry that we will get the next Feature from.
**/
private int entry_index = -1;
/** Enumeration for the current entry */
private FeatureEnumeration feature_enumerator;
/**
* Create a new FeatureEnumeration that will enumerate the enclosing
* SimpleEntryGroup object. The SimpleEntryGroup object must not be
* changed while the enumeration is active.
**/
public FeatureEnumerator()
{
active_entries = getActiveEntries();
entry_index = 0;
if(active_entries.size() > 0)
feature_enumerator =
active_entries.elementAt(entry_index).features();
else
feature_enumerator = null;
}
/**
* See the FeatureEnumeration interface for details.
**/
public boolean hasMoreFeatures()
{
if(feature_enumerator == null)
return false;
if(feature_enumerator.hasMoreFeatures())
return true;
++entry_index;
if(entry_index == active_entries.size())
return false;
else
{
feature_enumerator =
active_entries.elementAt(entry_index).features();
return hasMoreFeatures();
}
}
/**
* See the FeatureEnumeration interface for details.
**/
public Feature nextFeature()
throws NoSuchElementException
{
if(feature_enumerator == null)
throw new NoSuchElementException();
return feature_enumerator.nextFeature();
}
}
/**
* Implementation of the FeatureChangeListener interface. We listen for
* changes in every feature of every entry in this group.
**/
public void featureChanged(FeatureChangeEvent event)
{
// pass the action straight through
fireEvent(feature_listener_list, event);
}
/**
* Implementation of the EntryChangeListener interface. We listen for
* changes from every entry in this group and pass the events though to all
* the object listening for EntryChangeEvents for the event from this
* SimpleEntryGroup.
**/
public void entryChanged(EntryChangeEvent event)
{
// pass the action straight through
fireEvent(entry_listener_list, event);
}
/**
* Send an event to those object listening for it.
* @param listeners A Vector of the objects that the event should be sent
* to.
* @param event The event to send
**/
private void fireEvent(Vector listeners, ChangeEvent event)
{
final Vector targets;
// copied from a book - synchronising the whole method might cause a
// deadlock
synchronized(this)
{
targets = (Vector)listeners.clone();
}
final int targets_size = targets.size();
for(int i = 0; i < targets_size; ++i)
{
ChangeListener target =(ChangeListener) targets.elementAt(i);
if(event instanceof EntryGroupChangeEvent)
{
final EntryGroupChangeListener entry_group_change_listener =
(EntryGroupChangeListener) target;
final EntryGroupChangeEvent group_change_event =
(EntryGroupChangeEvent) event;
entry_group_change_listener.entryGroupChanged(group_change_event);
}
else
{
if(event instanceof EntryChangeEvent)
{
final EntryChangeListener entry_change_listener =
(EntryChangeListener) target;
// if(entry_change_listener instanceof ChadoTransactionManager)
// {
// if(!seen_chado_manager)
// {
// entry_change_listener.entryChanged((EntryChangeEvent) event);
// seen_chado_manager = true;
// }
// }
// else
entry_change_listener.entryChanged((EntryChangeEvent) event);
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
}
else
{
final FeatureChangeListener feature_change_listener =
(FeatureChangeListener) target;
feature_change_listener.featureChanged((FeatureChangeEvent) event);
}
}
}
}
/**
* Adds the specified event listener to receive entry group change events
* from this object.
* @param l the event change listener.
**/
public void addEntryGroupChangeListener(EntryGroupChangeListener l)
{
entry_group_listener_list.addElement(l);
}
/**
* Removes the specified event listener so that it no longer receives
* entry group change events from this object.
* @param l the event change listener.
**/
public void removeEntryGroupChangeListener(EntryGroupChangeListener l)
{
entry_group_listener_list.removeElement(l);
}
/**
* Adds the specified event listener to receive entry change events from
* this object.
* @param l the event change listener.
**/
public void addEntryChangeListener(EntryChangeListener l)
{
entry_listener_list.addElement(l);
}
/**
* Removes the specified event listener so that it no longer receives
* entry change events from this object.
* @param l the event change listener.
**/
public void removeEntryChangeListener(EntryChangeListener l)
{
entry_listener_list.removeElement(l);
}
/**
* Adds the specified event listener to receive feature change events from
* this object.
* @param l the event change listener.
**/
public void addFeatureChangeListener(FeatureChangeListener l)
{
feature_listener_list.addElement(l);
}
/**
* Removes the specified event listener so that it no longer receives
* feature change events from this object.
* @param l the event change listener.
**/
public void removeFeatureChangeListener(FeatureChangeListener l)
{
feature_listener_list.removeElement(l);
}
/**
* Return the reference of an EntryVector containing the active entries of
* this EntryGroup.
**/
public EntryVector getActiveEntries()
{
return(EntryVector) active_entries.clone();
}
/**
* This method translates the start and end of every each Range in every
* Location into another coordinate system. The Ranges will be truncated
* if necessary.
* @param constraint This contains the start and end base of the new
* coordinate system. The position given by constraint.getStart() will
* be at postion/base 1 in the new coordinate system.
* @return a copy of the EntryGroup which has been translated into the new