// 
//     Licensed to the Apache Software Foundation (ASF) under one
//     or more contributor license agreements.  See the NOTICE file
//     distributed with this work for additional information
//     regarding copyright ownership.  The ASF licenses this file
//     to you under the Apache License, Version 2.0 (the
//     "License"); you may not use this file except in compliance
//     with the License.  You may obtain a copy of the License at
// 
//       http://www.apache.org/licenses/LICENSE-2.0
// 
//     Unless required by applicable law or agreed to in writing,
//     software distributed under the License is distributed on an
//     "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
//     KIND, either express or implied.  See the License for the
//     specific language governing permissions and limitations
//     under the License.
//

= DevFaqOpenFileAtLine
:jbake-type: wiki
:jbake-tags: wiki, devfaq, needsreview
:jbake-status: published
:keywords: Apache NetBeans wiki DevFaqOpenFileAtLine
:description: Apache NetBeans wiki DevFaqOpenFileAtLine
:toc: left
:toc-title:
:syntax: true

=== How can I open a particular file at a particular line number and column?

Here is the basic idea (there are variations depending on your needs, so read the Javadoc):

[source,java]
----

File f = ...;
int lineNumber = ...;
FileObject fobj = FileUtil.toFileObject(f);
DataObject dobj = null;
try {
    dobj = DataObject.find(fobj);
} catch (DataObjectNotFoundException ex) {
    ex.printStackTrace();
}
if (dobj != null)
{
    LineCookie lc = (LineCookie) dobj .getCookie(LineCookie.class);
    if (lc == null) {/* cannot do it */ return;}
    Line l = lc.getLineSet().getOriginal(lineNumber);
    l.show(Line.SHOW_GOTO);
}
----

---

Applies to: NetBeans 5.x, 6.0, 6.1

For NetBeans 6.5 and later you should use something like:

[source,java]
----

File f = ...;
int lineNumber = ...;
FileObject fobj = FileUtil.toFileObject(f);
DataObject dobj = null;
try {
    dobj = DataObject.find(fobj);
} catch (DataObjectNotFoundException ex) {
    ex.printStackTrace();
}
if (dobj != null)
{
    LineCookie lc = (LineCookie) dobj .getCookie(LineCookie.class);
    if (lc == null) {/* cannot do it */ return;}
    Line l = lc.getLineSet().getOriginal(lineNumber);
    l.show(Line.ShowOpenType.OPEN, Line.ShowVisibilityType.FOCUS);
}
----

See the JavaDoc for `Line.ShowOpenType` and `Line.ShowVisibilityType` to see different options of showing the line (with focus, without focus, opening the editor if not open, etc.).

Example "How to open a document at line and at a specific column"

[source,java]
----

    int lineNumber=42;
    int colNumber=43;

    //misses checks for NPEs
    FileObject fo = ...;
    LineCookie lc = DataObject.find(fo).getLookup().lookup(LineCookie.class);
    Line line = lc.getLineSet().getOriginal(lineNumber);
    line.show(Line.ShowOpenType.OPEN, Line.ShowVisibilityType.FRONT, colNumber);
----

=== Apache Migration Information

The content in this page was kindly donated by Oracle Corp. to the
Apache Software Foundation.

This page was exported from link:http://wiki.netbeans.org/DevFaqOpenFileAtLine[http://wiki.netbeans.org/DevFaqOpenFileAtLine] , 
that was last modified by NetBeans user Markiewb 
on 2016-08-28T10:23:11Z.


*NOTE:* This document was automatically converted to the AsciiDoc format on 2018-02-07, and needs to be reviewed.
