Java Code Examples for javax.swing.text.AbstractDocument#readLock()

The following examples show how to use javax.swing.text.AbstractDocument#readLock() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: PHPTokenList.java    From netbeans with Apache License 2.0 6 votes vote down vote up
private int[] findNextPHPDocComment() throws BadLocationException {
    TokenSequence<PHPTokenId> ts = null;
    if (doc instanceof AbstractDocument) {
        AbstractDocument ad = (AbstractDocument) doc;
        ad.readLock();
        try {
            ts = LexUtilities.getPHPTokenSequence(ad, nextBlockStart);
        } finally {
            ad.readUnlock();
        }
    }
    if (ts == null) {
        return new int[]{-1, -1};
    }

    ts.move(nextBlockStart);
    while (ts.moveNext()) {
        if (ts.token().id() == PHPTokenId.PHPDOC_COMMENT) {
            return new int[]{ts.offset(), ts.offset() + ts.token().length()};
        }
    }
    return new int[]{-1, -1};
}
 
Example 2
Source File: GapDocumentView.java    From netbeans with Apache License 2.0 6 votes vote down vote up
public void run() {
    AbstractDocument doc = (AbstractDocument)getDocument();
    if (doc!=null){
        doc.readLock();
        try {
            LockView lockView = LockView.get(GapDocumentView.this);
            if (lockView != null) {
                lockView.lock();
                try {
                    layoutLock();
                    try {
                        updateView(lockView);
                    } finally {
                        updateLayout();
                        layoutUnlock();
                    }
                } finally {
                    lockView.unlock();
                }
            } // missing lock view => likely disconnected from hierarchy
        } finally {
            doc.readUnlock();
        }
    }
}
 
Example 3
Source File: NbGenerateCodeAction.java    From netbeans with Apache License 2.0 6 votes vote down vote up
private static MimePath getFullMimePath(Document document, int offset) {
    String langPath = null;

    if (document instanceof AbstractDocument) {
        AbstractDocument adoc = (AbstractDocument)document;
        adoc.readLock();
        try {
            List<TokenSequence<?>> list = TokenHierarchy.get(document).embeddedTokenSequences(offset, true);
            if (list.size() > 1) {
                langPath = list.get(list.size() - 1).languagePath().mimePath();
            }
        } finally {
            adoc.readUnlock();
        }
    }

    if (langPath == null) {
        langPath = NbEditorUtilities.getMimeType(document);
    }

    if (langPath != null) {
        return MimePath.parse(langPath);
    } else {
        return null;
    }
}
 
Example 4
Source File: ParserManagerImpl.java    From netbeans with Apache License 2.0 6 votes vote down vote up
static void refreshHack () {
        Iterator<Document> it = managers.keySet ().iterator ();
        while (it.hasNext ()) {
            AbstractDocument document = (AbstractDocument) it.next ();
            document.readLock ();
            try {
                MutableTextInput mti = (MutableTextInput) document.getProperty (MutableTextInput.class);
                mti.tokenHierarchyControl ().rebuild ();
            } finally {
                document.readUnlock ();
            }
//            final StyledDocument document = (StyledDocument) it.next ();
//            NbDocument.runAtomic (document, new Runnable () {
//                public void run() {
//                    MutableTextInput mti = (MutableTextInput) document.getProperty (MutableTextInput.class);
//                    mti.tokenHierarchyControl ().rebuild ();
//                }
//            });
        }
    }
 
Example 5
Source File: CodeFoldingTestCase.java    From netbeans with Apache License 2.0 6 votes vote down vote up
public static String foldHierarchyToString(JTextComponent target){
    String ret = "";
    AbstractDocument adoc = (AbstractDocument)target.getDocument();

    // Dump fold hierarchy
    FoldHierarchy hierarchy = FoldHierarchy.get(target);
    adoc.readLock();
    try {
        hierarchy.lock();
        try {
            Fold root = hierarchy.getRootFold();
            ret = (root == null) ? "root is null" : foldToStringChildren(root, 0); //NOI18N
        } finally {
            hierarchy.unlock();
        }
    } finally {
        adoc.readUnlock();
    }
    return ret;
}
 
Example 6
Source File: EditorCaret.java    From netbeans with Apache License 2.0 6 votes vote down vote up
/**
 * Schedule recomputation of visual bounds of all carets.
 */
private void requestUpdateAllCaretsBounds() {
    JTextComponent c = component;
    AbstractDocument doc;
    if (c != null && (doc = activeDoc) != null) {
        doc.readLock();
        try {
            List<CaretInfo> sortedCarets = getSortedCarets();
            for (CaretInfo caret : sortedCarets) {
                caret.getCaretItem().markUpdateCaretBounds();
            }
        } finally {
            doc.readUnlock();
        }
    }
}
 
Example 7
Source File: EditorCaret.java    From netbeans with Apache License 2.0 5 votes vote down vote up
/** Update visual position of caret(s) */
private void dispatchUpdate(boolean forceInvokeLater) {
    boolean alreadyPending;
    synchronized (listenerList) {
        alreadyPending = caretUpdatePending;
        caretUpdatePending = true;
    }
    if (!alreadyPending) {
        Runnable updateRunnable = new Runnable() {
            public @Override void run() {
                AbstractDocument doc = activeDoc;
                if (doc != null) {
                    doc.readLock();
                    try {
                        update(false);
                    } finally {
                        doc.readUnlock();
                    }
                } else {
                    // #269262 avoid that update() is not invoked
                    synchronized (listenerList) {
                        caretUpdatePending = false;
                    }
                }
            }
        };

        if (!forceInvokeLater && SwingUtilities.isEventDispatchThread()) {
            updateRunnable.run();
        } else {
            SwingUtilities.invokeLater(updateRunnable);
        }
    }
}
 
Example 8
Source File: FoldUtilitiesImpl.java    From netbeans with Apache License 2.0 5 votes vote down vote up
public static void collapseOrExpand(FoldHierarchy hierarchy, Collection foldTypes,
boolean collapse) {

    Document d = hierarchy.getComponent().getDocument();
    if (!(d instanceof AbstractDocument)) {
        // no op, the folding hierarchy does not work for != AbstractDocument
        return;
    }
    AbstractDocument adoc = (AbstractDocument)d;
    adoc.readLock();
    try {
        hierarchy.lock();
        try {
            List foldList = findRecursive(null,
                hierarchy.getRootFold(), foldTypes);
            if (collapse) {
                hierarchy.collapse(foldList);
            } else {
                hierarchy.expand(foldList);
            }
        } finally {
            hierarchy.unlock();
        }
    } finally {
        adoc.readUnlock();
    }
}
 
Example 9
Source File: SimpleFoldManagerTest.java    From netbeans with Apache License 2.0 5 votes vote down vote up
/**
 * Test the creation of several folds.
 */
public void test() throws Exception {
    FoldHierarchyTestEnv env = new FoldHierarchyTestEnv(new SimpleFoldManagerFactory());
    AbstractDocument doc = env.getDocument();
    doc.insertString(0, "1234567890", null);
    FoldHierarchy hierarchy = env.getHierarchy();
    doc.readLock();
    try {
        hierarchy.lock();
        try {
            
            Fold rootFold = hierarchy.getRootFold();
            int foldCount = rootFold.getFoldCount();
            int expectedFoldCount = 1;
            assertTrue("Incorrect fold count " + foldCount, // NOI18N
                (foldCount == expectedFoldCount)
            );
            
            Fold fold = rootFold.getFold(0);
            FoldType foldType = fold.getType();
            int foldStartOffset = fold.getStartOffset();
            int foldEndOffset = fold.getEndOffset();
            assertTrue("Incorrect fold type " + foldType, // NOI18N
                (foldType == AbstractFoldManager.REGULAR_FOLD_TYPE));
            assertTrue("Incorrect fold start offset " + foldStartOffset, // NOI18N
                (foldStartOffset == FOLD_START_OFFSET_1));
            assertTrue("Incorrect fold end offset " + foldEndOffset, // NOI18N
                (foldEndOffset == FOLD_END_OFFSET_1));
            
            // Check fold size
            assertSize("Size of the fold " , Collections.singleton(fold), // NOI18N
                MAX_FOLD_MEMORY_SIZE, new FoldMemoryFilter(fold));
            
        } finally {
            hierarchy.unlock();
        }
    } finally {
        doc.readUnlock();
    }
}
 
Example 10
Source File: XMLBraceMatcher.java    From netbeans with Apache License 2.0 5 votes vote down vote up
/**
 * Checks to see if an end tag exists for a start tag at a given offset.
 * @param document
 * @param offset
 * @return true if an end tag is found for the start, false otherwise.
 */
public static boolean hasEndTag(Document document, int offset, String startTag) {
    AbstractDocument doc = (AbstractDocument)document;
    doc.readLock();
    try {
        TokenHierarchy th = TokenHierarchy.get(doc);
        TokenSequence ts = th.tokenSequence();
        Token token = findTokenAtContext(ts, offset);
        Stack<String> stack = new Stack<String>();
        while(ts.moveNext()) {
            Token t = ts.token();
            if(XMLTokenId.TAG != t.id())
                continue;
            String tag = t.text().toString();
            if(">".equals(tag))
                continue;
            if(stack.empty()) {
                if(("</"+startTag).equals(tag)) {
                    stack.empty();
                    stack = null;
                    return true;
                }
            } else {                
                if(tag.equals("/>") || ("</"+stack.peek()).equals(tag)) {
                    stack.pop();
                    continue;
                }
            }
            stack.push(tag.substring(1));
        }            
    } finally {
        doc.readUnlock();
    }
    
    return false;
}
 
Example 11
Source File: AnnotationView.java    From netbeans with Apache License 2.0 5 votes vote down vote up
int[] getLinesSpan(int currentLine) {
    AbstractDocument adoc = doc;
    if (adoc != null)
        adoc.readLock();
    try {
        double componentHeight = getComponentHeight();
        double usableHeight = getUsableHeight();

        double position  = _modelToView(currentLine, componentHeight, usableHeight);

        if (position == (-1))
            return new int[] {currentLine, currentLine};

        int    startLine = currentLine;
        int    endLine   = currentLine;

        while (position == _modelToView(startLine - 1, componentHeight, usableHeight) && startLine > 0)
            startLine--;

        while ((endLine + 1) < Utilities.getRowCount(doc) && position == _modelToView(endLine + 1, componentHeight, usableHeight))
            endLine++;

        return new int[] {startLine, endLine};
    } finally {
        if (adoc != null)
            adoc.readUnlock();
    }
}
 
Example 12
Source File: DrawEngineDocView.java    From netbeans with Apache License 2.0 5 votes vote down vote up
public void propertyChange(java.beans.PropertyChangeEvent evt) {
    JTextComponent component = (JTextComponent)getContainer();
    if (component==null || evt==null || 
        (!EditorUI.LINE_HEIGHT_CHANGED_PROP.equals(evt.getPropertyName()) &&
         !EditorUI.TAB_SIZE_CHANGED_PROP.equals(evt.getPropertyName())
        )
    ) {
        return;
    }
    
    AbstractDocument doc = (AbstractDocument)getDocument();
    if (doc!=null) {
        doc.readLock();
        try{
            LockView lockView = LockView.get(this);
            lockView.lock();
            try {
                rebuild(0, getViewCount());
            } finally {
                lockView.unlock();
            }
        } finally {
            doc.readUnlock();
        }
    component.revalidate();
    }
}
 
Example 13
Source File: CodeFoldingTestCase.java    From netbeans with Apache License 2.0 5 votes vote down vote up
protected void waitForFolding(JTextComponent target, int maxMiliSeconds){
    //wait for parser and folding hierarchy creation
    int time = (int) maxMiliSeconds / 100;
    
    AbstractDocument adoc = (AbstractDocument)target.getDocument();
    
    // Dump fold hierarchy
    FoldHierarchy hierarchy = FoldHierarchy.get(target);
    int foldCount = 0;
    while (foldCount==0 && time > 0) {
        
        adoc.readLock();
        try {
            hierarchy.lock();
            try {
                foldCount = hierarchy.getRootFold().getFoldCount();
            } finally {
                hierarchy.unlock();
            }
        } finally {
            adoc.readUnlock();
        }
        
        try {
            Thread.currentThread().sleep(100);
        } catch (InterruptedException ex) {
            time=0;
        }
        time--;
        
    }
        
}
 
Example 14
Source File: RectangularSelectionTransferHandler.java    From netbeans with Apache License 2.0 4 votes vote down vote up
@Override
public void exportToClipboard(JComponent c, Clipboard clip, int action) throws IllegalStateException {
    List<Position> regions;
    if (c instanceof JTextComponent &&
            (Boolean.TRUE.equals(c.getClientProperty(RECTANGULAR_SELECTION_PROPERTY))) &&
            (regions = RectangularSelectionUtils.regionsCopy(c)) != null)
    {
        final JTextComponent tc = (JTextComponent) c;
        String[] data;
        StringBuilder stringSelectionBuffer;
        AbstractDocument doc = (AbstractDocument) tc.getDocument();
        doc.readLock();
        try {
            // Cannot delegate to overriden transfer handler - at least not the JTextComponent.DefaultTransferHandler
            // because it would:
            // for COPY action whole selection would be copied which is wrong
            // for MOVE selection it would in addition remove <dot,mark> portion of the document.
            // Therefore handle string selection here explicitly.
            CharSequence docText = DocumentUtilities.getText(doc);
            stringSelectionBuffer = new StringBuilder(100);
            int size = regions.size();
            data = new String[size >>> 1];
            for (int i = 0; i < size; i++) {
                Position startPos = regions.get(i++);
                Position endPos = regions.get(i);
                CharSequence lineSel = docText.subSequence(startPos.getOffset(), endPos.getOffset());
                int halfI = (i >>> 1);
                if (halfI != 0) {
                    stringSelectionBuffer.append('\n');
                }
                stringSelectionBuffer.append(lineSel);
                data[halfI] = lineSel.toString();
            }
        } finally {
            doc.readUnlock();
        }

        clip.setContents(
                new WrappedTransferable(
                    new StringSelection(stringSelectionBuffer.toString()),
                    new RectangularSelectionData(data)),
                null);

        if (action == TransferHandler.MOVE) {
            try {
                RectangularSelectionUtils.removeSelection(doc, regions);
            } catch (BadLocationException ex) {
                Exceptions.printStackTrace(ex);
            }
        }
        return;

    } else { // No rectangular selection
        delegate.exportToClipboard(c, clip, action);
    }
}
 
Example 15
Source File: EditorCaret.java    From netbeans with Apache License 2.0 4 votes vote down vote up
private void updateRectangularSelectionPositionBlocks() {
    JTextComponent c = component;
    if (rectangularSelection) {
        AbstractDocument doc = activeDoc;
        if (doc != null) {
            doc.readLock();
            try {
                if (rsRegions == null) {
                    rsRegions = new ArrayList<Position>();
                    component.putClientProperty(RECTANGULAR_SELECTION_REGIONS_PROPERTY, rsRegions);
                }
                synchronized (rsRegions) {
                    if (LOG.isLoggable(Level.FINE)) {
                        LOG.fine("EditorCaret.updateRectangularSelectionPositionBlocks: position regions:\n");
                    }
                    rsRegions.clear();
                    if (rsPaintRect != null) {
                        LockedViewHierarchy lvh = ViewHierarchy.get(c).lock();
                        try {
                            float rowHeight = lvh.getDefaultRowHeight();
                            double y = rsPaintRect.y;
                            double maxY = y + rsPaintRect.height;
                            double minX = rsPaintRect.getMinX();
                            double maxX = rsPaintRect.getMaxX();
                            do {
                                int startOffset = lvh.viewToModel(minX, y, null);
                                int endOffset = lvh.viewToModel(maxX, y, null);
                                // They could be swapped due to RTL text
                                if (startOffset > endOffset) {
                                    int tmp = startOffset;
                                    startOffset = endOffset;
                                    endOffset = tmp;
                                }
                                Position startPos = activeDoc.createPosition(startOffset);
                                Position endPos = activeDoc.createPosition(endOffset);
                                rsRegions.add(startPos);
                                rsRegions.add(endPos);
                                if (LOG.isLoggable(Level.FINE)) {
                                    LOG.fine("    <" + startOffset + "," + endOffset + ">\n");
                                }
                                y += rowHeight;
                            } while (y < maxY);
                            c.putClientProperty(RECTANGULAR_SELECTION_REGIONS_PROPERTY, rsRegions);
                        } finally {
                            lvh.unlock();
                        }
                    }
                }
            } catch (BadLocationException ex) {
                Exceptions.printStackTrace(ex);
            } finally {
                doc.readUnlock();
            }
        }
    }
}
 
Example 16
Source File: FoldOperationTest.java    From netbeans with Apache License 2.0 4 votes vote down vote up
/**
 * Checks that folds are created beween two folds, encapsulating existing folds.
 * 
 * @throws Exception 
 */
public void testUpdateCreateFold() throws Exception {
    final TestFoldManager[] mgr = new TestFoldManager[1];
    FoldHierarchyTestEnv env = new FoldHierarchyTestEnv(new FoldManagerFactory() {
        @Override
        public FoldManager createFoldManager() {
            return mgr[0] = new TestFoldManager();
        }
    });
    AbstractDocument doc = env.getDocument();
    doc.insertString(0, "12345678901234567890", null);

    FoldHierarchy hierarchy = env.getHierarchy();
    
    List<FoldInfo> infos = createDefaultInfos();
    
    // add a new fold between #1 and #2
    infos.add(FoldInfo.range(2, 3, FoldType.MEMBER));
    
    // add a new fold at the end:
    infos.add(FoldInfo.range(19,20, FoldType.MEMBER));
    
    // add a fold, which encapsulates #2 - #5
    infos.add(FoldInfo.range(3, 18, FoldType.MEMBER));
    
    // add a fold, which encapsulates ##5
    infos.add(FoldInfo.range(13, 16, FoldType.MEMBER));
    
    doc.readLock();
    try {
        hierarchy.lock();
        TestFoldManager m = mgr[0];
        try {
            Collection<Fold> remove = new ArrayList<Fold>();
            Collection<FoldInfo> create = new ArrayList<FoldInfo>();
            
            final boolean[] changed = new boolean[1];
            
            hierarchy.addFoldHierarchyListener(new FoldHierarchyListener() {
                @Override
                public void foldHierarchyChanged(FoldHierarchyEvent evt) {
                    changed[0] = true;
                }
            });
            Map<FoldInfo, Fold> mapping = m.operation.update(infos, remove, create);
            
            // 3 folds added, no deleted:
            assertEquals(4, create.size());
            assertEquals(0, remove.size());
            
        } finally {
            hierarchy.unlock();
        }
    } finally {
        doc.readUnlock();
    }
}
 
Example 17
Source File: XMLBraceMatcher.java    From netbeans with Apache License 2.0 4 votes vote down vote up
public int[] doFindOrigin() throws InterruptedException, BadLocationException {
    AbstractDocument doc = (AbstractDocument)document;
    doc.readLock();
    try {
        TokenHierarchy th = TokenHierarchy.get(doc);
        TokenSequence ts = th.tokenSequence();
        Token token = atOffset(ts, searchOffset);
        token = ts.token();
        int start = ts.offset();
        if(token == null)
            return null;
        XMLTokenId id = (XMLTokenId)token.id();
        String tokenText = token.text().toString();

        switch(id) {
            case PI_START:
            case PI_END: {
                return new int[] {start, start+token.length()};
            }
            case TAG: {
                //for ">" move back till the start tag
                if(">".equals(tokenText)) {
                    while(move(ts)) {
                        if(ts.token().id() == XMLTokenId.TAG)
                            break;
                    }
                }                    
                return findTagPosition(ts, false);
            }
            case BLOCK_COMMENT: {
                if(!tokenText.startsWith(COMMENT_START) &&
                   !tokenText.endsWith(COMMENT_END))
                   return null;
                return findGenericOrigin(ts, COMMENT_START, COMMENT_END);
            }
            case CDATA_SECTION: {
                if(!tokenText.startsWith(CDATA_START) &&
                   !tokenText.endsWith(CDATA_END))
                    return null;
                return findGenericOrigin(ts, CDATA_START, CDATA_END);
            }
            case DECLARATION: {
                if(!tokenText.startsWith(DECLARATION_START) &&
                   !tokenText.endsWith(DECLARATION_END))
                    return null;
                return findGenericOrigin(ts, DECLARATION_START, DECLARATION_END);
            }

            default:
                break;
        }
    } finally {
        doc.readUnlock();
    }
    return null;
}
 
Example 18
Source File: XMLBraceMatcher.java    From netbeans with Apache License 2.0 4 votes vote down vote up
public int[] doFindMatches() throws InterruptedException, BadLocationException {
    AbstractDocument doc = (AbstractDocument)document;
    doc.readLock();
    try {
        TokenHierarchy th = TokenHierarchy.get(doc);
        TokenSequence ts = th.tokenSequence();
        Token token = atOffset(ts, searchOffset);
        if(token == null) return null;
        XMLTokenId id = (XMLTokenId)token.id();
        switch(id) {
            case PI_START: {
                return findMatchingPair(ts, XMLTokenId.PI_END, true);
            }
            case PI_END: {
                return findMatchingPair(ts, XMLTokenId.PI_START, false);
            }
            case TAG: {
                //for ">" move back till the start tag
                if(">".equals(ts.token().text().toString())) {
                    while(ts.movePrevious()) {
                        if(ts.token().id() == XMLTokenId.TAG)
                            break;
                    }
                }                    
                String tagName = ts.token().text().toString();
                if(tagName.startsWith("</")) {
                    return findMatchingTagBackward(ts, tagName.substring(2));
                }
                if(tagName.startsWith("<")) {
                    return findMatchingTagForward(ts, tagName.substring(1));
                }
            }
            case BLOCK_COMMENT: {
                return findGenericMatch(ts, COMMENT_START, COMMENT_END);
            }
            case CDATA_SECTION: {
                return findGenericMatch(ts, CDATA_START, CDATA_END);
            }
            case DECLARATION: {
                return findGenericMatch(ts, DECLARATION_START, DECLARATION_END);
            }
        }
    } finally {
        doc.readUnlock();
    }
    return null;
}
 
Example 19
Source File: ActionFactory.java    From netbeans with Apache License 2.0 4 votes vote down vote up
public void actionPerformed(ActionEvent evt, JTextComponent target) {
    AbstractDocument adoc = (AbstractDocument)target.getDocument();

    // Dump fold hierarchy
    FoldHierarchy hierarchy = FoldHierarchy.get(target);
    adoc.readLock();
    try {
        hierarchy.lock();
        try {
            /*DEBUG*/System.err.println("FOLD HIERARCHY DUMP:\n" + hierarchy); // NOI18N
            TokenHierarchy<?> th = TokenHierarchy.get(adoc);
            /*DEBUG*/System.err.println("TOKEN HIERARCHY DUMP:\n" + (th != null ? th : "<NULL-TH>")); // NOI18N

        } finally {
            hierarchy.unlock();
        }
    } finally {
        adoc.readUnlock();
    }

    View rootView = null;
    TextUI textUI = target.getUI();
    if (textUI != null) {
        rootView = textUI.getRootView(target); // Root view impl in BasicTextUI
        if (rootView != null && rootView.getViewCount() == 1) {
            rootView = rootView.getView(0); // Get DocumentView
        }
    }
    if (rootView != null) {
        String rootViewDump = (rootView instanceof DocumentView)
                ? ((DocumentView)rootView).toStringDetail()
                : rootView.toString();
        /*DEBUG*/System.err.println("DOCUMENT VIEW: " + System.identityHashCode(rootView) + // NOI18N
                "\n" + rootViewDump); // NOI18N
        int caretOffset = target.getCaretPosition();
        int caretViewIndex = rootView.getViewIndex(caretOffset, Position.Bias.Forward);
        /*DEBUG*/System.err.println("caretOffset=" + caretOffset + ", caretViewIndex=" + caretViewIndex); // NOI18N
        if (caretViewIndex >= 0 && caretViewIndex < rootView.getViewCount()) {
            View caretView = rootView.getView(caretViewIndex);
            /*DEBUG*/System.err.println("caretView: " + caretView); // NOI18N
        }
        /*DEBUG*/System.err.println(FixLineSyntaxState.lineInfosToString(adoc));
        // Check the hierarchy correctness
        //org.netbeans.editor.view.spi.ViewUtilities.checkViewHierarchy(rootView);
    }
    
    if (adoc instanceof BaseDocument) {
        /*DEBUG*/System.err.println("DOCUMENT:\n" + ((BaseDocument)adoc).toStringDetail()); // NOI18N
    }
}
 
Example 20
Source File: GlyphGutter.java    From netbeans with Apache License 2.0 4 votes vote down vote up
public @Override void mouseDragged(MouseEvent e) {
    EditorUI eui = editorUI;
    if (eui == null) {
        return;
    }
    JTextComponent component = eui.getComponent();
    BaseTextUI textUI = (BaseTextUI)component.getUI();
    AbstractDocument aDoc = (AbstractDocument)component.getDocument();
    aDoc.readLock();
    try {
        // The drag must be extended to a next line in order to perform any selection
        int lineStartOffset = textUI.getPosFromY(e.getY());
        boolean updateDragEndOffset = false;
        if (dragStartOffset == -1) { // Drag starts now
            dragStartOffset = lineStartOffset;
            dragEndOffset = lineStartOffset;
        } else if (dragStartOffset == dragEndOffset) {
            if (lineStartOffset != dragStartOffset) {
                updateDragEndOffset = true;
            }
        } else {
            updateDragEndOffset = true;
        }
        if (updateDragEndOffset) {
            // Extend selection to active line's end or begining depending on dragStartOffset
            Caret caret = component.getCaret();
            if (lineStartOffset >= dragStartOffset) {
                if (caret.getMark() != dragStartOffset) {
                    caret.setDot(dragStartOffset);
                }
                // Check if the sele
                // Extend to next line's begining
                dragEndOffset = Math.min(Utilities.getRowEnd((BaseDocument) aDoc, lineStartOffset) + 1, aDoc.getLength());
            } else { // Backward selection
                // Check if the selection is already reverted i.e. it starts at dragStartOffset's line end
                if (caret.getMark() == dragStartOffset) {
                    caret.setDot(Utilities.getRowEnd((BaseDocument)aDoc, dragStartOffset) + 1);
                }
                dragEndOffset = lineStartOffset;
            }
            component.moveCaretPosition(dragEndOffset);
        }
    } catch (BadLocationException ble) {
        // Ignore rather than notify
    } finally {
        aDoc.readUnlock();
    }
}