/** * makes cursor hand if at the end of an exon using mouses position, does not change pos or tier * variable */ public void mouseMoved(MouseEvent e) { // setPos sets the pos variable to the mouse position, cant do this // because on right click menu want to preserve the pos clicked on // and setPos here changes pos if user moves mouse after right click // setPos (e.getX(), e.getY()); // moveMouseTier and moveMousePos can differ from this.tier and pos int mouseMoveTier = baseEditorPanel.getTierForPixelPosition(e.getY()); // SeqAlignPanel int mouseMovePos = calculatePosition(e.getX(), e.getY()); // make the cursor a hand if it is at the end of a feature int type = baseEditorPanel.getBoundaryType(mouseMovePos, mouseMoveTier); if (type == baseEditorPanel.NO_BOUNDARY) baseEditorPanel.setCursor(Cursor.getDefaultCursor()); else baseEditorPanel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); }
protected void resetDragState() { baseEditorPanel.setCursor(Cursor.getDefaultCursor()); dragStartPos = -1; dragType = -1; // These are min and max in genomic coord. space limit_5prime = -1; limit_3prime = -1; baseEditorPanel.setSelectBeginPos(-1); // selectCurrentPos = -1; baseEditorPanel.setSelectCurrentPos(-1); dragFeature = null; dragging = false; preDragStartBasePair = -1; preDragEndBasePair = -1; }
private BaseFineEditor( AnnotatedFeatureI editMe, GuiCurationState curationState, SeqFeatureI geneHolder, Set<SeqFeatureI> selectedResults) { super((editMe.isForwardStrand() ? "Forward" : "Reverse") + " Strand Exon Editor"); this.curationState = curationState; curationState.getController().addListener(this); curationState.getController().addListener(new BaseEditorDataListener()); szap = curationState.getSZAP(); transformer = szap.getScaleView().getTransform(); int seqStart = curationState.getCurationSet().getLow(); int seqEnd = curationState.getCurationSet().getHigh(); CurationSet s = curationState.getCurationSet(); // FeatureSetI annFeatSet=((DrawableFeatureSet)view.getDrawableSet()).getFeatureSet(); // REFACTOR BaseEditorPanel - (what allows for selection and modification of the annotations?) // create BaseViewPanel -> have BaseEditorPanel extend it // take the header outside of the editorPanel (is it really inside right now?) // create a new panel using BaseViewPanel /* * The viewable components of the new BaseFineEditor (should this be renamed?): * * 1) The Genomic Strand * 2) The Annotations (will these always be a copy of the genomic strand?) * q1) Can annotations also be nucliotides? - A: Yes. Create a separate view for those. * q2) Does it make sense to view both the forward and reverse strand at once? * q3) How do we know what to load - A: highlight the region we want to look at? * q4) Will we expect users to be able to view many annotations at once? * q4) How will the user know which annotation they are looking at? - A: Display the name when hovering over? * 3) The Results * q1) See above questions. * 4) Result Score information * 5) An overview - Right now this is at the transcript (gene model?) level * q1) What should be contained in this view? * * */ // I think that right now every base in the ede is a copy of the genomic, will that always be // the case? // is there ever sequence associated with an annotation. editorPanel = new BaseEditorPanel( curationState, this, !editMe.isForwardStrand(), seqStart, seqEnd, geneHolder); addResults(selectedResults); initGui(editMe); // cant do til after editorPanel made // cant do this til after initGui (editorPanel needs to know size) editorPanel.displayAnnot(editMe); attachListeners(); showEditRegion(); displayAnnot(getTransOrOneLevelAnn(editMe)); translationViewer.repaint(); setVisible(true); // Might just be linux, but bofe gets iconified on close if (getState() == Frame.ICONIFIED) setState(Frame.NORMAL); }
private BaseFineEditor( AnnotatedFeatureI editMe, GuiCurationState curationState, SeqFeatureI geneHolder) { super((editMe.isForwardStrand() ? "Forward" : "Reverse") + " Strand Exon Editor"); this.curationState = curationState; curationState.getController().addListener(this); curationState.getController().addListener(new BaseEditorDataListener()); szap = curationState.getSZAP(); transformer = szap.getScaleView().getTransform(); int seqStart = curationState.getCurationSet().getLow(); int seqEnd = curationState.getCurationSet().getHigh(); // FeatureSetI annFeatSet=((DrawableFeatureSet)view.getDrawableSet()).getFeatureSet(); editorPanel = new BaseEditorPanel( curationState, this, !editMe.isForwardStrand(), seqStart, seqEnd, geneHolder); initGui(editMe); // cant do til after editorPanel made // cant do this til after initGui (editorPanel needs to know size) editorPanel.displayAnnot(editMe); attachListeners(); showEditRegion(); displayAnnot(getTransOrOneLevelAnn(editMe)); translationViewer.repaint(); setVisible(true); // Might just be linux, but bofe gets iconified on close if (getState() == Frame.ICONIFIED) setState(Frame.NORMAL); }
public void dispose() { removeComponents(this); editorPanel.cleanup(); // 1.3.1 popup mem leak & remove listener szap.removeHighlightRegion(editorPanel); editorPanel = null; translationViewer = null; viewport.removeChangeListener(scrollListener); viewport = null; lengthLabel = null; // featureNameLabel = null; transcriptComboBox = null; szap = null; transformer = null; scrollListener = null; indicatorColor = null; colorSwatch = null; // changeListener = null; // removeWindowListener(windowListener); // windowListener = null; getController().removeListener(this); // getController() = null; // view = null; findButton = null; clearFindsButton = null; goToButton = null; upstream_button = null; downstream_button = null; super.dispose(); }
public void setPos(int x, int y) { /* after much to-ing and fro-ing it has become apparent that pos(itions) within a row's seqwrapper are 0-based (Not 1-based as the sequence is */ this.tier = baseEditorPanel.getTierForPixelPosition(y); // method of SeqAlignPanel this.pos = calculatePosition(x, y); }
/** Middle mouse scrolls to where clicked, left mouse selects Right mouse brings up popup menu */ public void mouseClicked(MouseEvent e) { setPos(e.getX(), e.getY()); if (MouseButtonEvent.isRightMouseClickNoShift(e)) { if (tier > 2) baseEditorPanel.displayRightClickMenu(e.getX(), e.getY()); } if (MouseButtonEvent.isMiddleMouseClickNoShift(e)) { baseEditorPanel.scrollToPosition(pos); } // This is for Windows, which doesn't support middle clicks else if (MouseButtonEvent.isRightMouseClickWithShift(e)) { baseEditorPanel.scrollToPosition(pos); } if (MouseButtonEvent.isLeftMouseClick(e)) { baseEditorPanel.selectAnnot(pos, tier); baseEditorPanel.repaint(); } }
/** Does all the handle selection checks for BaseFineEditor and BaseEditorPanel */ boolean canHandleSelection(FeatureSelectionEvent evt, Object self) { if ((noExternalSelection() && isExternalSelection(evt)) && !evt.forceSelection()) return false; if (evt.getSource() == self) return false; if (!this.isVisible()) return false; if (evt.getFeatures().size() == 0) return false; SeqFeatureI sf = evt.getFeatures().getFeature(0); // if strand of selection is not our strand return boolean is_reverse = (sf.getStrand() == -1); if (is_reverse != editorPanel.getReverseStrand()) return false; if (!(sf instanceof AnnotatedFeatureI)) return false; // repaint transVw? else return true; }
/** Enables or disables tree mode. */ public void setTreeModeEnabled(boolean enabled) { BaseEditorPanel opanel = _panel; remove(opanel); add( _panel = enabled ? new TreeEditorPanel(_ctx, opanel.getAncestors(), opanel.getOmitColumns()) : new EditorPanel( _ctx, EditorPanel.CategoryMode.PANELS, opanel.getAncestors(), opanel.getOmitColumns())); _panel.addChangeListener(this); _panel.setObject(opanel.getObject()); revalidate(); }
/** * puts up vertical lines in szap(main window) indicating the region EDE is displaying - make * private? */ private void showEditRegion() { colorIndex = (colorIndex + 1) % colorList.length; indicatorColor = colorList[colorIndex]; colorSwatch.setBackground(indicatorColor); szap.addHighlightRegion(editorPanel, indicatorColor, editorPanel.getReverseStrand()); }
public boolean handleAnnotationChangeEvent(AnnotationChangeEvent evt) { if (this.isVisible() && evt.getSource() != this) { if (evt.isCompound()) { for (int i = 0; i < evt.getNumberOfChildren(); ++i) { handleAnnotationChangeEvent(evt.getChildChangeEvent(i)); } return true; } if (evt.isEndOfEditSession()) { // Dont want scrolling on ann change, also sf for redraw is the // gene, so it just goes to 1st trans which is problematic. displayAnnot(currentAnnot); repaint(); // this is the needed repaint after the changes return true; } /* AnnotatedFeatureI gene = evt.getChangedAnnot(); for (Object o : szap.getAnnotations().getFeatures()) { AnnotatedFeatureI feat = (AnnotatedFeatureI)o; if (feat.getId().equals(gene.getId())) { //gene = feat; break; } } */ if (evt.isAdd()) { AnnotatedFeatureI annotToDisplay = null; AnnotatedFeatureI gene = evt.getChangedAnnot(); int trans_count = gene.size(); for (int i = 0; i < trans_count; ++i) { Transcript t = (Transcript) gene.getFeatureAt(i); if (evt.isUndo()) { // System.out.printf("Attaching %s(%d)\n", t, t.hashCode()); editorPanel.attachAnnot(t); if (currentAnnot != null && t.getName().equals(currentAnnot.getName())) { annotToDisplay = t; } } } if (annotToDisplay == null) { annotToDisplay = (AnnotatedFeatureI) evt.getChangedAnnot().getFeatureAt(0); } displayAnnot(annotToDisplay); return true; } if (evt.isDelete()) { AnnotatedFeatureI gene = evt.getChangedAnnot(); int trans_count = gene.size(); for (int i = 0; i < trans_count; ++i) { if (evt.isUndo()) { Transcript t = (Transcript) gene.getFeatureAt(i); // System.out.printf("Detaching %s(%d)\n", t, t.hashCode()); editorPanel.detachTranscript(t); } } return true; } /* // getAnnotation() can be null after a delete - return if null? SeqFeatureI sf = evt.getAnnotTop(); // If the annotation event is not for the editors strand then return boolean is_reverse = (sf.getStrand() == -1); if (editorPanel.getReverseStrand() != is_reverse) return false; if (evt.isDelete() && evt.isRootAnnotChange()) { AnnotatedFeatureI gene = evt.getChangedAnnot(); int trans_count = gene.size(); for (int i = 0; i < trans_count; i++) { Transcript t = (Transcript) gene.getFeatureAt (i); editorPanel.detachTranscript (t); if (t == currentAnnot) currentAnnot = null; } } else if (evt.isDelete() && evt.isTranscriptChange()) { Transcript t = (Transcript) evt.getChangedAnnot(); editorPanel.detachTranscript (t); if (t == currentAnnot) currentAnnot = null; } else if ((evt.isAdd() || evt.isSplit() || evt.isMerge()) && evt.isRootAnnotChange()) { AnnotatedFeatureI gene = evt.getChangedAnnot(); int trans_count = gene.size(); for (int i = 0; i < trans_count; i++) { Transcript t = (Transcript) gene.getFeatureAt (i); int tier = editorPanel.attachAnnot (t); } } else if (evt.isAdd() && evt.isTranscriptChange()) { Transcript t = (Transcript) evt.getChangedAnnot(); int tier = editorPanel.attachAnnot (t); } // Exon split or intron made - same thing isnt it? else if (evt.isAdd() && evt.isExonChange()) { Transcript t = (Transcript) evt.getParentFeature(); // removing and adding transcript will force editorPanel // to pick up new exon editorPanel.detachTranscript(t); editorPanel.attachAnnot(t); } else if (evt.isDelete() && evt.isExonChange()) { Transcript t = (Transcript) evt.getParentFeature(); // removing and adding transcript will force editorPanel to remove exon editorPanel.detachTranscript(t); editorPanel.attachAnnot(t); // or editorPanel.removeFeature((Exon)evt.getSecondFeature()); } // else if (evt.isReplace()) { //&&evt.isTopAnnotChange - always true of replace // AnnotatedFeatureI old_gene = evt.getReplacedFeature(); // AnnotatedFeatureI new_gene = (AnnotatedFeatureI)evt.getChangedFeature(); // int trans_count = old_gene.size(); // /* This does assume that there are no changes in the number // of transcripts between the old and the new. Might be safer // to separate the 2 loops */ // for (int i = 0; i < trans_count; i++) { // Transcript t; // t = (Transcript) old_gene.getFeatureAt (i); // editorPanel.detachTranscript (t); // t = (Transcript) new_gene.getFeatureAt (i); // int tier = editorPanel.attachTranscript (t); // } // // This is so that we don't select a different transcript // AnnotatedFeatureI current_gene = (current_transcript != null ? // current_transcript.getGene() : null); // if (current_gene != null && current_gene == old_gene) { // int index = current_gene.getFeatureIndex(current_transcript); // current_transcript = (Transcript) new_gene.getFeatureAt(index); // } // } // this isnt possible - all replaces are for top annots // else if (evt.isReplace() && evt.isTranscriptChange()) { // Transcript old_trans = (Transcript)evt.getReplacedFeature(); // Transcript new_trans = (Transcript)evt.getChangedFeature(); // editorPanel.detachTranscript (old_trans); // int tier = editorPanel.attachTranscript (new_trans); // // This is so that we don't select a different transcript // if (current_transcript != null && current_transcript == old_trans) { // current_transcript = new_trans; // } // } } return true; }
private void addResults(Set<SeqFeatureI> results) { editorPanel.addResults(results); }
/** * Right mouse: highlight base. Left mouse: figure dragType, dragFeature, dragStartPos, * startDragTier */ public void mousePressed(MouseEvent e) { setPos(e.getX(), e.getY()); // show base at right mouse click highlighted (on release - popup menu) if (MouseButtonEvent.isRightMouseClickNoShift(e)) { BaseRenderer rend = baseEditorPanel.getRendererAt(tier); if (rend instanceof SelectableDNARenderer) { ((SelectableDNARenderer) rend).setTargetPos(pos, tier); baseEditorPanel.repaint(); return; } } if (!MouseButtonEvent.isLeftMouseClick(e)) return; if (dragStartPos == -1) { if (e.isControlDown()) dragType = baseEditorPanel.SEQ_SELECT_DRAG; else dragType = baseEditorPanel.getBoundaryType(pos, tier); dragFeature = baseEditorPanel.getFeatureAtPosition(pos, tier); dragStartPos = pos; startPos = pos; startDragTier = tier; if (dragFeature == null && ((dragType != baseEditorPanel.SEQ_SELECT_DRAG) || startDragTier > baseEditorPanel.getTierCount() || startDragTier < 3)) { resetDragState(); return; } if (dragType == baseEditorPanel.START_BOUNDARY) { /* the 5 prime edge of the feature (exon) can be moved within limits. These are no farther in the 3prime direction than the end of the feature and no farther in the 5prime direction than the beginning (5prime) of the preceding intron */ limit_3prime = (int) dragFeature.getEnd(); int lowBound = baseEditorPanel.basePairToPos(dragFeature.getStart()); // subtract one to move into the preceding intron double[] lowRange = baseEditorPanel.getRangeAtPosition(tier, lowBound - 1); if (lowRange[0] < 0) limit_5prime = baseEditorPanel.posToBasePair(0); else limit_5prime = baseEditorPanel.posToBasePair((int) lowRange[0]); baseEditorPanel.setCursor(Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR)); } else if (dragType == baseEditorPanel.END_BOUNDARY) { limit_5prime = (int) dragFeature.getStart(); int highBound = baseEditorPanel.basePairToPos((int) dragFeature.getEnd()); double[] highRange = baseEditorPanel.getRangeAtPosition(tier, highBound + 1); SequenceI seq = baseEditorPanel.getSequenceForTier(tier); if (highRange[1] > seq.getLength()) limit_3prime = baseEditorPanel.posToBasePair(seq.getLength()); else limit_3prime = baseEditorPanel.posToBasePair((int) highRange[1]); baseEditorPanel.setCursor(Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR)); } else if (dragType == baseEditorPanel.SEQ_SELECT_DRAG) { baseEditorPanel.setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR)); baseEditorPanel.setSelectBeginPos(pos); baseEditorPanel.setSelectCurrentPos(pos); } } }
/** Cacluates logical position of x,y pixel values, but does not set the pos variable */ private int calculatePosition(int x, int y) { int row = baseEditorPanel.getRowForPixelPosition(y); int col = baseEditorPanel.getColForPixelPosition(x); // getColumnCount from super class SeqAlignPanel return (baseEditorPanel.getColumnCount() * row) + col; }
/** * If right mouse deselect base If end of feature drag notify AnnotationEditor (endRangeChange) * and recalc translation end from start */ public void mouseReleased(MouseEvent e) { // RIGHT MOUSE CLICK if (MouseButtonEvent.isRightMouseClick(e)) { BaseRenderer rend = baseEditorPanel.getRendererAt(tier); if (rend instanceof SelectableDNARenderer) { ((SelectableDNARenderer) rend).setTargetPos(-1, -1); baseEditorPanel.repaint(); } } // SEQ SELECT DRAG if (dragType == baseEditorPanel.SEQ_SELECT_DRAG) { SequenceI seq = baseEditorPanel.getSequenceForTier(startDragTier); int lowBP = baseEditorPanel.posToResidue(baseEditorPanel.selectLowPos()); int highBP = baseEditorPanel.posToResidue(baseEditorPanel.selectHighPos()); String sequence = seq.getResidues(lowBP, highBP); String header = " Arbitrary selection (" + seq.getName() + ": " + lowBP + "," + highBP + ")"; // controllingWindow.copySeqToClipboard(new Sequence (header, sequence)); ClipboardUtil.copySeqToClipboard(new Sequence(header, sequence)); resetDragState(); baseEditorPanel.repaint(); return; } // NOT SEQ SELECT DRAG else { // NOT DRAGGING - RETURN if (!MouseButtonEvent.isLeftMouseClick(e) || !dragging || dragFeature == null) { resetDragState(); return; } // DRAGGING ANNOT ENDS if (dragging && dragFeature != null && dragFeature.isAnnot()) { // NOTIFY ANNOTATION EDITOR (generates transaction) int oldStart = (preDragStartBasePair == -1) ? dragFeature.getStart() : preDragStartBasePair; int oldEnd = (preDragEndBasePair == -1) ? dragFeature.getEnd() : preDragEndBasePair; AnnotationEditor ae = baseEditorPanel.getAnnotationEditor(); ae.setAnnotTerminus( dragFeature.getAnnotatedFeature(), oldStart, oldEnd, dragFeature.getStart(), dragFeature.getEnd()); // RECALC CDS (if exon/transcript - not for 1 level annots) if (dragFeature.isExon() && dragFeature.getRefFeature() != null && (dragFeature.getRefFeature().isTranscript())) { // ExonI exon = (ExonI)dragFeature; // Transcript t = (Transcript)exon.getRefFeature(); SeqFeatureI transcript = dragFeature.getRefFeature(); TranslationI cds = transcript.getTranslation(); int transStart = transcript.getStart(); int cdsStart = cds.getTranslationStart(); boolean isForward = transcript.isForwardStrand(); if (cds.isMissing5prime() && ((isForward && transStart < cdsStart) || (!isForward && transStart > cdsStart))) { cds.calcTranslationStartForLongestPeptide(); // missing start } else { cds.setTranslationEndFromStart(); // got start - set end } } baseEditorPanel.repaint(); } } resetDragState(); baseEditorPanel.getCurationState().getSZAP().repaint(); }
/** * Display AnnotatedFeatureI feature. Exon, Transcript, and Gene are all GenericAnnotationI. No * selection event is fired. (selectAnnot fires and displays) */ private void displayAnnot(AnnotatedFeatureI annot) { currentAnnot = annot; if (currentAnnot == null) { transcriptComboBox.removeAllItems(); transcriptComboBox.addItem("<no feature selected>"); lengthLabel.setText("Translation length: <no feature selected>"); upstream_button.setLabel(""); downstream_button.setLabel(""); translationViewer.setTranscript(null, editorPanel.getSelectedTier()); // ?? return; } // else { setupTranscriptComboBox(currentAnnot); SeqFeatureI topAnnot = currentAnnot; if (topAnnot.isTranscript()) topAnnot = currentAnnot.getRefFeature(); if (topAnnot.isProteinCodingGene()) { String translation = currentAnnot.translate(); if (translation == null) { lengthLabel.setText("Translation length: <no start selected>"); } else { lengthLabel.setText("Translation length: " + currentAnnot.translate().length()); } } else { lengthLabel.setText(topAnnot.getFeatureType() + " annotation"); } FeatureSetI holder = (FeatureSetI) topAnnot.getRefFeature(); neighbor_up = null; neighbor_down = null; if (holder != null) { int index = holder.getFeatureIndex(topAnnot); // get next neighbor up that has whole sequence for (int i = index - 1; i >= 0 && neighbor_up == null; i--) { FeatureSetI gene_sib = (FeatureSetI) holder.getFeatureAt(i); if (gene_sib.getFeatureAt(0) instanceof Transcript) { Transcript trans = (Transcript) gene_sib.getFeatureAt(0); if (trans.haveWholeSequence()) // szap.getCurationSet())) neighbor_up = trans; } } // get next neighbor down that has whole sequence for (int i = index + 1; i < holder.size() && neighbor_down == null; i++) { FeatureSetI gene_sib = (FeatureSetI) holder.getFeatureAt(i); if (gene_sib.getFeatureAt(0) instanceof Transcript) { Transcript trans = (Transcript) gene_sib.getFeatureAt(0); if (trans.haveWholeSequence()) // szap.getCurationSet())) neighbor_down = trans; } } } upstream_button.setLabel( neighbor_up == null ? "" : "Go to next 5' annotation (" + neighbor_up.getParent().getName() + ")"); upstream_button.setVisible(neighbor_up != null); downstream_button.setLabel( neighbor_down == null ? "" : "Go to next 3' annotation (" + neighbor_down.getParent().getName() + ")"); downstream_button.setVisible(neighbor_down != null); // } // todo - translationViewer take in 1 level annot if (currentAnnot.isTranscript()) translationViewer.setTranscript((Transcript) currentAnnot, editorPanel.getSelectedTier()); }
/** * Left Mouse dragging drags end of feature if drag type right or left boundary. dragType is * figured in mousePressed */ public void mouseDragged(MouseEvent e) { if (!MouseButtonEvent.isLeftMouseClick(e)) return; // dragFeature set in mousePressed // not needed if (dragging == false && dragFeature != null) { // changer = baseEditorPanel.getAnnotationEditor().beginRangeChange(dragFeature);// ?? preDragStartBasePair = dragFeature.getStart(); preDragEndBasePair = dragFeature.getEnd(); } dragging = true; // dragType determined in MousePressed if (dragType == baseEditorPanel.START_BOUNDARY) baseEditorPanel.setCursor(Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR)); else if (dragType == baseEditorPanel.END_BOUNDARY) baseEditorPanel.setCursor(Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR)); else if (dragType == baseEditorPanel.SEQ_SELECT_DRAG) { baseEditorPanel.setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR)); } setPos(e.getX(), e.getY()); startPos = pos; // going right // substract the one because during dragging // the person operating the mouse drags it // one position beyond where they want the // drop to occur. // pos--; if (dragType == baseEditorPanel.START_BOUNDARY) { // Is this position okay to use as the new // low end or will it make the feature too short? if (baseEditorPanel.notTooSmall( pos, baseEditorPanel.basePairToPos((int) dragFeature.getEnd()))) // this actually changes the model - do we really need to do that // with every mouse drag - cant we just change it at the end of the // drag? No - the EDE relies on the feature being changed - bummer baseEditorPanel.changeStart(dragFeature, pos - dragStartPos, limit_5prime, limit_3prime); } else if (dragType == baseEditorPanel.END_BOUNDARY) { // Is this position okay to use as the new // high end or will it make the feature too short? if (baseEditorPanel.notTooSmall( baseEditorPanel.basePairToPos((int) dragFeature.getStart()), pos)) // This changes the actual exon model! EDE relies on this baseEditorPanel.changeEnd(dragFeature, pos - dragStartPos, limit_5prime, limit_3prime); } else if (dragType == baseEditorPanel.SEQ_SELECT_DRAG) { int redrawLowPos = baseEditorPanel.selectLowPos(); int redrawHighPos = baseEditorPanel.selectHighPos(); if (pos < redrawLowPos) redrawLowPos = pos; if (pos > redrawHighPos) redrawHighPos = pos; // selectCurrentPos = pos; baseEditorPanel.setSelectCurrentPos(pos); baseEditorPanel.repaint(redrawLowPos, redrawHighPos); return; } // repaint with exon seq feature ends changed baseEditorPanel.repaint(pos, dragStartPos); dragStartPos = pos; }