Newer
Older
/* FeatureDisplay.java
*
* created: Fri Oct 9 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/components/FeatureDisplay.java,v 1.66 2009-06-12 13:50:35 tjc Exp $
import uk.ac.sanger.artemis.util.DatabaseDocument;
import uk.ac.sanger.artemis.util.ReadOnlyException;
import uk.ac.sanger.artemis.util.FileDocument;
import uk.ac.sanger.artemis.util.OutOfRangeException;
import uk.ac.sanger.artemis.util.StringVector;
import uk.ac.sanger.artemis.io.ChadoCanonicalGene;
import uk.ac.sanger.artemis.io.Qualifier;
import uk.ac.sanger.artemis.io.EntryInformation;
import uk.ac.sanger.artemis.io.SimpleEntryInformation;
import uk.ac.sanger.artemis.io.RawStreamSequence;
import uk.ac.sanger.artemis.io.FastaStreamSequence;
import uk.ac.sanger.artemis.io.Sequence;
import uk.ac.sanger.artemis.io.Location;
import uk.ac.sanger.artemis.*;
import uk.ac.sanger.artemis.sequence.*;
import java.awt.event.*;
import java.awt.*;
import java.lang.Math;
import java.util.Vector;
import java.util.Comparator;
import javax.swing.border.Border;
import javax.swing.border.BevelBorder;
import javax.swing.JOptionPane;
/**
* This component is used for displaying an Entry.
*
* @author Kim Rutherford
* @version $Id: FeatureDisplay.java,v 1.66 2009-06-12 13:50:35 tjc Exp $
**/
public class FeatureDisplay extends EntryGroupPanel
implements EntryGroupChangeListener,
EntryChangeListener, FeatureChangeListener,
SelectionChangeListener, GotoListener, SequenceChangeListener,
DisplayComponent, OptionChangeListener, DisplayAdjustmentListener,
DragGestureListener, DropTargetListener,
DragSourceListener
/** Key code for calling zoomToSelection(). */
final static public int ZOOM_TO_SELECTION_KEY = KeyEvent.VK_Z;
final static public int SCROLLBAR_AT_TOP = 1;
final static public int SCROLLBAR_AT_BOTTOM = 2;
private final static int FORWARD = Bases.FORWARD;
private final static int REVERSE = Bases.REVERSE;
private final static int NO_FRAME = FeatureSegment.NO_FRAME;
private final static int FORWARD_STRAND = FeatureSegment.FORWARD_STRAND;
private final static int REVERSE_STRAND = FeatureSegment.REVERSE_STRAND;
private final static int FORWARD_FRAME_1 = FeatureSegment.FORWARD_FRAME_1;
private final static int FORWARD_FRAME_2 = FeatureSegment.FORWARD_FRAME_2;
private final static int FORWARD_FRAME_3 = FeatureSegment.FORWARD_FRAME_3;
private final static int REVERSE_FRAME_3 = FeatureSegment.REVERSE_FRAME_3;
private final static int REVERSE_FRAME_2 = FeatureSegment.REVERSE_FRAME_2;
private final static int REVERSE_FRAME_1 = FeatureSegment.REVERSE_FRAME_1;
private final static int SCALE_LINE = FeatureSegment.SCALE_LINE;
/**
* The JScrollBar for this FeatureDisplay object. We create the scrollbar
* as part of this object rather than in the EntryEdit component because we
* may need to change the parameters of the scrollbar later.
**/
private JScrollBar scrollbar = null;
/** A scroll bar for changing the viewing scale. */
private ZoomScrollBar scale_changer = null;
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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
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
240
241
242
243
244
245
246
247
248
249
250
251
252
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
/** Used to colour the frames. */
private Color light_grey = new Color(240, 240, 240);
/** Used to colour sequence line. */
private Color not_so_light_grey = new Color(200, 200, 200);
/**
* The colour used for the active entry line when
* one_line_per_entry is set.
**/
private Color active_entry_colour = new Color(255, 255, 140);
/**
* This Vector containing the references of those features that are
* currently visible.
**/
private FeatureVector visible_features = new FeatureVector();
/**
* If true updateVisibleFeatureVector() will be called by paint().
* updateVisibleFeatureVector() sets this to false,
* needVisibleFeatureVectorUpdate() sets this to true.
**/
private boolean update_visible_features = true;
/** Contains those objects listening for adjustment events. */
final private Vector adjustment_listener_list = new Vector();
/**
* The index of the first base that we are displaying.
* Can be negative if hard_left_edge is true.
**/
private int left_edge_base = 1;
/** See getScaleFactor(). */
private int scale_factor = 3;
/** See getScaleFactor(). */
private float scale_value = 1;
/** true if labels should be shown. */
private boolean show_labels = true;
/**
* This variable is true if the forward frame lines(or forward entry lines
* - see one_line_per_entry) should be drawn.
**/
private boolean show_forward_lines = true;
/**
* This variable is true if the reverse frame lines(or reverse entry lines
* - see one_line_per_entry) should be drawn.
**/
private boolean show_reverse_lines = true;
/**
* If true draw all features, sequence and scale lines reverse complemented.
**/
private boolean rev_comp_display = false;
/**
* This variable is true if(for each strand) each entry should be on a
* separate line.
**/
private boolean one_line_per_entry = false;
/**
* If true the there will never be a gap between the left edge of the
* screen and the first visible base.
**/
private boolean hard_left_edge = true;
/** true if source features should be shown. */
private boolean show_source_features = false;
/** true if stop codons should be shown. */
private boolean show_stop_codons = true;
/** true if start codons should be shown. */
private boolean show_start_codons = false;
/** true if directional arrows should be shown on features. */
private boolean show_feature_arrows;
/** true a black border will be drawn around each feature. */
private boolean show_feature_borders;
/**
* This variable is true if each base should be drawn in a different colour
* at scale feature 1.
**/
private boolean show_base_colours = false;
/**
* All features(not just CDS features) will be drawn on the frame lines if
* and only if this variable is true. See setFrameFeaturesFlag() and
* getFrameFeaturesFlag().
**/
private boolean frame_features_flag = false;
/**
* The position(s) of the last mouse click on the dna line. The
* MarkerRange contains a reference to the appropriate Strand and contains
* the base positions. See getMarkerRangeFromPosition() to understand why
* one click can give multiple bases.
**/
private MarkerRange click_range = null;
/**
* The last(FeatureSegment) Marker that the user clicked on. This is used
* for dragging the ends of segments.
**/
private Marker click_segment_marker = null;
/**
* This is true if click_segment_marker is the Marker at the start of
* segment false otherwise. The value is only useful if
* click_segment_marker is set.
**/
private boolean click_segment_marker_is_start_marker = false;
/**
* When a FeatureSegment Marker drag starts, this is set to the Marker at
* the other end of the segment. This is used to check that the drag has
* not move the Marker too far(past the end of the segment).
**/
private Marker other_end_of_segment_marker = null;
/**
* Features with a /score qualifier less than this value will not be shown.
**/
private int current_min_score = 0;
/**
* Features with a /score qualifier greater than this value will not be
* shown.
**/
private int current_max_score = 100;
private MouseEvent last_mouse_press_event;
/**
* If set no DisplayAdjustment events will be sent. This is set by
* displayAdjustmentValueChanged() to prevent an event we send from
* returning to us(a FeatureDisplay can listen for DisplayAdjustment
* events from another FeatureDisplay).
**/
private boolean disable_display_events = false;
/**
* Set to true by selectionChanged() to tell updateVisibleFeatureVector()
* to raise the contents of the select before updating.
**/
private boolean raise_selection_flag = false;
/** the minimum distance in pixels between the labels. */
private final static int MINIMUM_LABEL_SPACING = 80;
/** colour used for A. */
private static Color dark_green = new Color(0, 150, 0);
private Object[] protein_keys = { "CDS",
"BLASTCDS",
"polypeptide",
"pseudogenic_exon"};
/**
* Create a new FeatureDisplay object with the horizontal scrollbar at the
* bottom of the component.
* @param entry_group The EntryGroup that this component will display.
* @param selection The Selection object for this component. Selected
* objects will be highlighted.
* @param goto_event_source The object to use when we need to call
* gotoBase().
* @param base_plot_group The BasePlotGroup associated with this JMenu -
* needed to call getCodonUsageAlgorithm()
**/
public FeatureDisplay(final EntryGroup entry_group,
final Selection selection,
final GotoEventSource goto_event_source,
final BasePlotGroup base_plot_group)
{
this(entry_group, selection, goto_event_source,
}
/**
* Create a new FeatureDisplay object.
* @param entry_group The EntryGroup that this component will display.
* @param owning_component The EntryEdit object that contains the selection
* that this component uses.
* @param scrollbar_at_top If true the horizontal scrollbar will be at the
* top of component.
* @param base_plot_group The BasePlotGroup associated with this JMenu -
* needed to call getCodonUsageAlgorithm()
* @param scrollbar_style Controls the type of horizontal scrollbar. Must
* be one of SCROLLBAR_AT_TOP, SCROLLBAR_AT_BOTTOM or NO_SCROLLBAR.
**/
public FeatureDisplay(final EntryGroup entry_group,
final Selection selection,
final GotoEventSource goto_event_source,
final BasePlotGroup base_plot_group,
final int scrollbar_style)
{
super(entry_group, selection, goto_event_source, base_plot_group);
show_feature_arrows =
Options.getOptions().getPropertyTruthValue("draw_feature_arrows");
show_feature_borders =
Options.getOptions().getPropertyTruthValue("draw_feature_borders");
frame_features_flag =
Options.getOptions().getPropertyTruthValue("features_on_frame_lines");
one_line_per_entry =
Options.getOptions().getPropertyTruthValue("one_line_per_entry");
show_labels =
Options.getOptions().getPropertyTruthValue("feature_labels");
show_reverse_lines =
Options.getOptions().getPropertyTruthValue("show_reverse_lines");
show_forward_lines =
Options.getOptions().getPropertyTruthValue("show_forward_lines");
final StringVector frame_line_features =
Options.getOptions().getOptionValues("frame_line_features");
if(frame_line_features != null)
protein_keys = frame_line_features.toArray();
addComponentListener(new ComponentAdapter()
{
public void componentResized(ComponentEvent e)
{
// update the scroll bar as soon as we know the size of the canvas
fixScrollbar();
needVisibleFeatureVectorUpdate();
fireAdjustmentEvent(DisplayAdjustmentEvent.ALL_CHANGE_ADJUST_EVENT);
}
public void componentShown(ComponentEvent e)
{
// update the scroll bar as soon as we know the size of the canvas
fixScrollbar();
needVisibleFeatureVectorUpdate();
fireAdjustmentEvent(DisplayAdjustmentEvent.ALL_CHANGE_ADJUST_EVENT);
}
});
setScaleValue();
if(scrollbar_style == SCROLLBAR_AT_TOP)
createScrollbar(true);
else if(scrollbar_style == SCROLLBAR_AT_BOTTOM)
createScrollbar(false);
createScaleScrollbar();
addListeners();
needVisibleFeatureVectorUpdate();
getSelection().addSelectionChangeListener(this);
getGotoEventSource().addGotoListener(this);
getEntryGroup().addEntryGroupChangeListener(this);
getEntryGroup().addEntryChangeListener(this);
getEntryGroup().addFeatureChangeListener(this);
getBases().addSequenceChangeListener(this, Bases.MIN_PRIORITY);
Options.getOptions().addOptionChangeListener(this);
DragSource dragSource = DragSource.getDefaultDragSource();
dragSource.createDefaultDragGestureRecognizer(
this, // component where drag originates
DnDConstants.ACTION_COPY_OR_MOVE, // actions
this); // drag gesture recognizer
setDropTarget(new DropTarget(this,this));
}
/**
* Overriden to call fixCanvasSize()
**/
public void setVisible(final boolean visible)
{
super.setVisible(visible);
fixCanvasSize();
}
/**
* Set value of the show label flag.
* @param show_label Show labels if and only if this argument is true.
**/
{
if(this.show_labels != show_labels)
{
this.show_labels = show_labels;
fixCanvasSize();
}
}
/**
* Get the value of the "show label" flag.
**/
{
return show_labels;
}
/**
* Set value of the "show forward frame lines" flag.
* @param show_forward_lines Show forward frame lines if and only if
* this argument is true.
**/
{
if(this.show_forward_lines != show_forward_lines)
{
this.show_forward_lines = show_forward_lines;
fixCanvasSize();
}
}
/**
* Get the value of the "show forward frame lines" flag.
**/
{
return show_forward_lines;
}
/**
* Set value of the "show reverse frame lines" flag.
* @param show_reverse_lines Show frame lines if and only if this
* argument is true.
**/
{
if(this.show_reverse_lines != show_reverse_lines)
{
this.show_reverse_lines = show_reverse_lines;
fixCanvasSize();
}
}
/**
* Get the value of the "show source features" flag.
**/
{
return show_source_features;
}
/**
* Set value of the "show source features" flag.
* @param show_source_features Show features with a "source" key if and
* only if this argument is true.
**/
{
if(this.show_source_features != show_source_features)
{
this.show_source_features = show_source_features;
needVisibleFeatureVectorUpdate();
}
}
/**
* Get the value of the "show frame lines" flag.
**/
{
return show_reverse_lines;
}
/**
* Set value of the show base colours flag.
* @param show_base_colours At scale_factor less than two show each base in
* a different colour if and only if this argument is true.
**/
{
if(this.show_base_colours != show_base_colours)
{
this.show_base_colours = show_base_colours;
if(getScaleFactor() > 1)
setScaleFactor(1);
repaint();
}
}
/**
* Get the value of the "show base colours" flag.
**/
{
return show_base_colours;
}
/**
* Set value of the "one line per entry" flag.
* @param one_line_per_entry If true then each entry will be shown on a
* different line, instead of showing frame lines.
**/
{
if(this.one_line_per_entry != one_line_per_entry)
{
this.one_line_per_entry = one_line_per_entry;
fixCanvasSize();
}
}
/**
* Get the value of the "one line per entry" flag.
**/
{
return one_line_per_entry;
}
/**
* Set value of the "hard left edge" flag.
* @param hard_left_edge If true the there will never be a gap between the
* left edge of the screen and the first visible base. If false base one
* can be moved to the centre of the display.
**/
{
if(this.hard_left_edge != hard_left_edge)
{
this.hard_left_edge = hard_left_edge;
if(hard_left_edge && getForwardBaseAtLeftEdge() < 1)
setFirstVisibleForwardBase(1);
fixScrollbar();
}
}
/**
* Set value of the show stop codons flag.
* @param show_stop_codons Show stop codons if and only if this argument is
* true.
**/
{
if(this.show_stop_codons != show_stop_codons)
{
this.show_stop_codons = show_stop_codons;
}
}
/**
* Return the value of the "show stop codons" flag.
**/
return show_stop_codons;
}
/**
* Set value of the show start codons flag.
* @param show_start_codons Show start codons if and only if this argument
* is true.
**/
{
if(this.show_start_codons != show_start_codons)
{
this.show_start_codons = show_start_codons;
}
}
/**
* Return the value of the "show start codons" flag.
**/
{
return show_start_codons;
}
/**
* Set value of the reverse complement display flag.
* @param show_start_codons Draw all features and sequence reverse
* complemented if and only if this argument is true.
**/
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
{
if(this.rev_comp_display != rev_comp_display)
{
this.rev_comp_display = rev_comp_display;
int remember_position = getCentreForwardBase();
// we want to keep the selection visible after the flip, so
// that will override the centre position
final Marker first_base_marker =
getSelection().getStartBaseOfSelection();
if(first_base_marker != null && baseVisible(first_base_marker))
remember_position = first_base_marker.getRawPosition();
final Marker last_base_marker =
getSelection().getStartBaseOfSelection();
if(last_base_marker != null && baseVisible(last_base_marker))
remember_position = last_base_marker.getRawPosition();
fireAdjustmentEvent(DisplayAdjustmentEvent.REV_COMP_EVENT);
makeBaseVisibleInternal(remember_position, isRevCompDisplay(), true);
needVisibleFeatureVectorUpdate();
fixScrollbar();
}
}
/**
* Return the value of the "reverse complement display" flag.
**/
{
return rev_comp_display;
}
/**
* Set value of the show feature arrows flag.
* @param show_feature_arrows Show directional arrows if and only if this
* argument is true.
**/
{
if(this.show_feature_arrows != show_feature_arrows)
{
this.show_feature_arrows = show_feature_arrows;
}
}
/**
* Return the value of the "show feature arrows" flag.
**/
{
return show_feature_arrows;
}
/**
* Set value of the show feature borders flag.
* @param show_feature_borders Draw a border around each feature if and
* only if this argument is true.
**/
{
if(this.show_feature_borders != show_feature_borders)
{
this.show_feature_borders = show_feature_borders;
}
}
/**
* Return the value of the "show feature borders" flag.
**/
{
return show_feature_borders;
}
/**
* Set value of the show frame features flag.
* @param frame_features_flag All features(not just CDS features) will be
* drawn on the frame lines if and only if this argument is true.
**/
{
if(this.frame_features_flag != frame_features_flag)
{
this.frame_features_flag = frame_features_flag;
}
}
/**
* Return the value of the "show frame features" flag.
**/
{
return frame_features_flag;
}
/**
* Set the value of the minimum score for this FeatureDisplay - features
* that have a /score lower than this value are never shown.
**/
{
current_min_score = minimum_score;
needVisibleFeatureVectorUpdate();
}
/**
* Return the value of the minimum score for this FeatureDisplay - see
* setMinimumScore().
**/
{
return current_min_score;
}
/**
* Set the value of the maximum score for this FeatureDisplay - features
* that have a /score higher than this value are never shown.
**/
{
current_max_score = maximum_score;
needVisibleFeatureVectorUpdate();
}
/**
* Return the value of the maximum score for this FeatureDisplay - see
* setMaximumScore().
**/
{
return current_max_score;
}
/**
* Adds the specified event adjustment listener to receive adjustment
* change events from this object.
* @param l the event change listener.
**/
{
adjustment_listener_list.addElement(l);
}
/**
* Removes the specified event listener so that it no longer receives
* adjustment change events from this object.
* @param l the event change listener.
**/
protected void removeDisplayAdjustmentListener(DisplayAdjustmentListener l)
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
{
adjustment_listener_list.removeElement(l);
}
/**
* Handle key press events. This is static because making it non-static
* triggered a java.lang.VerifyError
**/
private static void handleKeyPress(final FeatureDisplay feature_display,
final KeyEvent event)
{
// this is done so that menu shortcuts don't cause each action to be
// performed twice
if(event.getModifiers() != 0)
return;
switch(event.getKeyCode())
{
case ZOOM_TO_SELECTION_KEY:
FeaturePopup.zoomToSelection(feature_display);
break;
default:
break;
}
}
/**
* Set the scale factor and update the display if the scale factor has
* changed. A factor of zero means the full translation will be visible.
* At higher scale factors only stop codons are visible, and a bigger
* number will mean more bases are visible.
**/
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
{
if(this.scale_factor != scale_factor)
{
// we will try to keep the base in the centre of the view to stay where
// it is, so we save it's position in remember_position.
int remember_position = getCentreForwardBase();
// if the first base is visible then keep it visible
if(hard_left_edge && getFirstVisibleForwardBase() == 1)
remember_position = 1;
if(!getSelection().isEmpty())
{
// but, we want to keep the selection visible after a scale change, so
// that will override the centre position
final Marker first_base_marker =
getSelection().getStartBaseOfSelection();
final int first_base_marker_raw_position =
first_base_marker.getRawPosition();
final int first_base_marker_position;
if(isRevCompDisplay())
first_base_marker_position =
getBases().getComplementPosition(first_base_marker_raw_position);
else
first_base_marker_position = first_base_marker_raw_position;
final Marker last_base_marker =
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
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
final int last_base_marker_raw_position =
last_base_marker.getRawPosition();
final int last_base_marker_position;
if(isRevCompDisplay())
last_base_marker_position =
getBases().getComplementPosition(last_base_marker_raw_position);
else
last_base_marker_position = last_base_marker_raw_position;
final int lowest_visible_base = getFirstVisibleForwardBase();
final int highest_visible_base = getLastVisibleForwardBase();
// first selected base or first visible base, whichever is greater
int restricted_first_selected_base = lowest_visible_base;
// last selected base or last visible base, whichever is smaller
int restricted_last_selected_base = highest_visible_base;
if(first_base_marker != null)
{
if(first_base_marker_position > lowest_visible_base &&
first_base_marker_position < highest_visible_base)
restricted_first_selected_base = first_base_marker_position;
}
if(last_base_marker != null)
{
if(last_base_marker_position < highest_visible_base &&
last_base_marker_position > lowest_visible_base)
restricted_last_selected_base = last_base_marker_position;
}
if(getSelection().getMarkerRange() == null)
remember_position = restricted_first_selected_base;
else
{
// keep the centre of the selection in the middle of the display if
// a range of bases is selected
remember_position = restricted_first_selected_base +
(restricted_last_selected_base -
restricted_first_selected_base) / 2;
}
}
this.scale_factor = scale_factor;
setScaleValue();
if(scale_changer != null)
scale_changer.setValue(scale_factor);
setCentreVisibleForwardBase(remember_position);
fixScrollbar();
fireAdjustmentEvent(DisplayAdjustmentEvent.SCALE_ADJUST_EVENT);
needVisibleFeatureVectorUpdate();
908
909
910
911
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
}
}
/**
* Implementation of the FeatureChangeListener interface. We listen to
* FeatureChange events so that we can update the display if qualifiers
* change.
**/
public void featureChanged(final FeatureChangeEvent event)
{
final Feature event_feature = event.getFeature();
// the feature isn't in an active entry
if(!getEntryGroup().contains(event_feature))
return;
// if the feature is visible now or is in the list of visible features
//(ie. it was visible previously) then redisplay.
if(featureVisible(event_feature) ||
getVisibleFeatures().contains(event_feature))
{
// update the visible_features vector
if(getVisibleFeatures().contains(event_feature) &&
!featureVisible(event_feature))
getVisibleFeatures().remove(event_feature);
else
{
// the visibility of the feature has changed
if(!getVisibleFeatures().contains(event_feature) &&
featureVisible(event_feature))
getVisibleFeatures().add(event_feature);
}
}
}
/**
* Implementation of the EntryGroupChangeListener interface. We listen to
* EntryGroupChange events so that we can update the display if entries
* are added or deleted.
**/
public void entryGroupChanged(final EntryGroupChangeEvent event)
{
switch(event.getType())
{
case EntryGroupChangeEvent.ENTRY_ADDED:
case EntryGroupChangeEvent.ENTRY_ACTIVE:
case EntryGroupChangeEvent.ENTRY_DELETED:
case EntryGroupChangeEvent.ENTRY_INACTIVE:
if(getOneLinePerEntryFlag())
fixCanvasSize();
needVisibleFeatureVectorUpdate();
break;
}
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
}
/**
* Implementation of the EntryChangeListener interface. We listen to
* EntryChange events so that we can update the display if features are
* added or deleted.
**/
public void entryChanged(final EntryChangeEvent event)
{
switch(event.getType())
{
case EntryChangeEvent.FEATURE_DELETED:
remove(event.getFeature());
break;
case EntryChangeEvent.FEATURE_ADDED:
add(event.getFeature());
break;
}
}
/**
* Implementation of the SelectionChangeListener interface. We listen to
* SelectionChange events so that we can update the list to reflect the
* current selection.
**/
public void selectionChanged(final SelectionChangeEvent event)
{
// don't bother with events we sent ourself
if(event.getSource() == this)
return;
needVisibleFeatureVectorUpdate();
if(event.getType() == SelectionChangeEvent.SELECTION_CHANGED)
raise_selection_flag = true;