lookup confusing me

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
11 messages Options
Reply | Threaded
Open this post in threaded view
|

lookup confusing me

Peter Cheung
Hi
   I have trouble with lookup, the below code only print out the current file instead of all opened files.
Lookup lookup = Utilities.actionsGlobalContext();

Collection<? extends DataObject> list = lookup.lookupAll(DataObject.class);
for (DataObject dataObject : list) {
ModuleLib.log(dataObject);
}

If i use "Lookup.getDefault().lookupAll", looupAll() even returns nothing. Please help

Thanks
FromPeter

Reply | Threaded
Open this post in threaded view
|

Re: lookup confusing me

geertjan.wielenga@oracle.com

Gj

Sent from my iPhone

On 14 Sep 2017, at 18:39, Peter Cheung <[hidden email]> wrote:

Hi
   I have trouble with lookup, the below code only print out the current file instead of all opened files.
Lookup lookup = Utilities.actionsGlobalContext();

Collection<? extends DataObject> list = lookup.lookupAll(DataObject.class);
for (DataObject dataObject : list) {
ModuleLib.log(dataObject);
}

If i use "Lookup.getDefault().lookupAll", looupAll() even returns nothing. Please help

Thanks
FromPeter

Reply | Threaded
Open this post in threaded view
|

Re: lookup confusing me

Neil C Smith-2
In reply to this post by Peter Cheung


On Thu, Sep 14, 2017 at 5:40 PM Peter Cheung <[hidden email]> wrote:
   I have trouble with lookup, the below code only print out the current file instead of all opened files.

Why would you expect it to do anything else?!

Maybe look at http://wiki.netbeans.org/DevFaqGetOpenEditorWindows or other pages on the Developer FAQ.

Best wishes,

Neil
--
Neil C Smith
Artist & Technologist

Praxis LIVE - hybrid visual IDE for creative coding - www.praxislive.org
Reply | Threaded
Open this post in threaded view
|

Re: lookup confusing me

Oliver Rettig
In reply to this post by Peter Cheung
Hi Peter,

the global context represents the active/selected element(s). So If you have
selected one or more DataObjects, you can find them in the lookup of the global
context.

The meaning of "All" in the method lookup.lookupAll () is, that you get all of
these objects in a list instead only the first found.

The selection can be empty, so the lookup of the global context can be empty.

Does it help or have I misunderstood your question?

The more interesting question is how to get a list of all opend files? In some
of my apps I have implemented my own global lookup/cache to keep them. But
maybe there is a more intelligent way.

best regards
Oliver

> Hi
>    I have trouble with lookup, the below code only print out the current
> file instead of all opened files. Lookup lookup =
> Utilities.actionsGlobalContext();
>
> Collection<? extends DataObject> list = lookup.lookupAll(DataObject.class);
> for (DataObject dataObject : list) {
> ModuleLib.log(dataObject);
> }
>
> If i use "Lookup.getDefault().lookupAll", looupAll() even returns nothing.
> Please help
>
> Thanks
> FromPeter


Reply | Threaded
Open this post in threaded view
|

Re: lookup confusing me

arsi
In reply to this post by Peter Cheung

Hi,

Test this:

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Map;
import java.util.WeakHashMap;
import javax.swing.text.Document;
import javax.swing.text.JTextComponent;
import org.netbeans.api.editor.EditorRegistry;
import org.netbeans.modules.editor.NbEditorUtilities;
import org.openide.loaders.DataObject;
import org.openide.modules.OnStart;

/**
 *
 * @author arsi
 */
@OnStart
public class Demo implements Runnable {

    public static final Map<DataObject, Object> opened = new WeakHashMap<>();

    @Override
    public void run() {
        PropertyChangeListener l = new PropertyChangeListener() {
            @Override
            public void propertyChange(PropertyChangeEvent evt) {
                if (evt.getPropertyName().equals(EditorRegistry.FOCUS_GAINED_PROPERTY) || evt.getPropertyName().equals(EditorRegistry.FOCUSED_DOCUMENT_PROPERTY)) {
                    JTextComponent jtc = (JTextComponent) evt.getNewValue();
                    if (jtc != null) {
                        Document d = jtc.getDocument();
                        DataObject dobj = NbEditorUtilities.getDataObject(d);
                        if (dobj != null && !opened.containsKey(dobj)) {
                            opened.put(dobj, null);
                        }
                    }
                } else if (evt.getPropertyName().equals(EditorRegistry.COMPONENT_REMOVED_PROPERTY)) {
                    JTextComponent jtc = (JTextComponent) evt.getOldValue();
                    if (jtc != null) {
                        Document d = jtc.getDocument();
                        DataObject dobj = NbEditorUtilities.getDataObject(d);
                        opened.remove(dobj);
                    }
                }
            }
        };

        EditorRegistry.addPropertyChangeListener(l);
    }

}
ArSi



From: Peter Cheung
Sent: Thursday, September 14, 2017 6:39PM
To: Dev
Subject: [platform-dev] lookup confusing me


Hi
   I have trouble with lookup, the below code only print out the current file instead of all opened files.
Lookup lookup = Utilities.actionsGlobalContext();

Collection<? extends DataObject> list = lookup.lookupAll(DataObject.class);
for (DataObject dataObject : list) {
ModuleLib.log(dataObject);
}

If i use "Lookup.getDefault().lookupAll", looupAll() even returns nothing. Please help

Thanks
FromPeter







 

Reply | Threaded
Open this post in threaded view
|

Re: lookup confusing me

Oliver Rettig
In reply to this post by Oliver Rettig
> The more interesting question is how to get a list of all opend files? In
> some of my apps I have implemented my own global lookup/cache to keep them.
> But maybe there is a more intelligent way.

Maybe you can get a list of all of your open TopComponents and than you can
ask each TopComponent lookup for your DataObject.

> best regards
> Oliver
>
> > Hi
> >
> >    I have trouble with lookup, the below code only print out the current
> >
> > file instead of all opened files. Lookup lookup =
> > Utilities.actionsGlobalContext();
> >
> > Collection<? extends DataObject> list =
> > lookup.lookupAll(DataObject.class);
> > for (DataObject dataObject : list) {
> > ModuleLib.log(dataObject);
> > }
> >
> > If i use "Lookup.getDefault().lookupAll", looupAll() even returns nothing.
> > Please help
> >
> > Thanks
> > FromPeter


Reply | Threaded
Open this post in threaded view
|

Re: lookup confusing me

Peter Cheung
i tried to lookupall TopComponents but nothing return. Now i can use lookup listener to track which file is opened. But if the file is closed i have no event. And i think getting the list of all opened files using a listener is too heavy. It should be calling one single function to do that.

Peter.

> On 15 Sep 2017, at 6:02 AM, Oliver Rettig <[hidden email]> wrote:
>
>> The more interesting question is how to get a list of all opend files? In
>> some of my apps I have implemented my own global lookup/cache to keep them.
>> But maybe there is a more intelligent way.
>
> Maybe you can get a list of all of your open TopComponents and than you can
> ask each TopComponent lookup for your DataObject.
>
>> best regards
>> Oliver
>>
>>> Hi
>>>
>>>   I have trouble with lookup, the below code only print out the current
>>>
>>> file instead of all opened files. Lookup lookup =
>>> Utilities.actionsGlobalContext();
>>>
>>> Collection<? extends DataObject> list =
>>> lookup.lookupAll(DataObject.class);
>>> for (DataObject dataObject : list) {
>>> ModuleLib.log(dataObject);
>>> }
>>>
>>> If i use "Lookup.getDefault().lookupAll", looupAll() even returns nothing.
>>> Please help
>>>
>>> Thanks
>>> FromPeter
>
>

Reply | Threaded
Open this post in threaded view
|

Re: lookup confusing me

Graeme
In reply to this post by Peter Cheung
It's not clear exactly what you are trying to achieve when you say "all opened files".  

As others have said, you don't seem to understand what NetBeans Lookups are or what they are used for so I would recommend reading up on Lookup.

If you understood Lookup, you would know that the global Lookup does not allow you to find all instances of a particular class type within your application.

It's not really clear if you are trying to find all DataObject instances or if you are trying to find opened files that are associated with "editor" Top Components.

Neil provided a link to a Wiki page http://wiki.netbeans.org/DevFaqGetOpenEditorWindows that shows you how you can determine which editors are open from which you can get the associated DataObject.  If you are trying to find editor files - this is all you need.

That however would not find other DataObjects that were opened using the FileSystem/DataSystems API's directly e.g.             

If you called DataObject dobj = DataObject.find(FileUtil.toFileObject(new File("/path/to/somefile"));

When a DataObject instance is created it is registered in a DataObjectPool unfortunately this pool is not public.  You could however get the DataObjects registered in the pool using reflection.  Using a dirty hack like this really isn't recommended and you really need to understand what you are doing.   

This approach would return ALL DataObject instances and not just DataObject instances that you opened (the platform opens many configuration files, other plugins could create DataObjects).  Determining which DataObjects you are truly interested in would be another problem for you to solve. Manipulating objects you did not create/own could have serious consequences!

For demonstration purposes only:

            Field poolField = Class.forName("org.openide.loaders.DataObjectPool").getDeclaredField("POOL");
            poolField.setAccessible(true);
            Object pool = poolField.get(null);
            Field mapField = pool.getClass().getDeclaredField("map");
            mapField.setAccessible(true);
            Object map = mapField.get(pool);            
            Map<Object, Object> refMap = (Map<Object,Object>)map;
            for(Object o: refMap.values()) {
                Field objField = o.getClass().getDeclaredField("obj");
                objField.setAccessible(true);
                Reference<DataObject> result = (Reference<DataObject>)objField.get(o);
                DataObject dataObject = (DataObject)result.get();
                System.out.println(dataObject); // Here's the DataObject you want
            }

The above code would print all DataObject instances - you could return them in a list, filter objects of interest etc.

Do you intend your modules to be used within the IDE or a custom NB Platform application where you might be able to customize your harness?  If the later you could provide the functionality you need without using reflection by accessing DataObjectPool and providing a public method to return the information you need.

Hopefully you are only interested in Editor files and Neil has already provided the perfect solution for that.  

Using non-public API's is a really bad idea, but sometimes the only way to achieve what you want (I've seen reflection used within NB sources).  

Just make sure you fully understand the ramifications.



From: Peter Cheung [[hidden email]]
Sent: Thursday, September 14, 2017 12:39 PM
To: [hidden email]
Subject: [platform-dev] lookup confusing me

Hi
   I have trouble with lookup, the below code only print out the current file instead of all opened files.
Lookup lookup = Utilities.actionsGlobalContext();

Collection<? extends DataObject> list = lookup.lookupAll(DataObject.class);
for (DataObject dataObject : list) {
ModuleLib.log(dataObject);
}

If i use "Lookup.getDefault().lookupAll", looupAll() even returns nothing. Please help

Thanks
FromPeter

Reply | Threaded
Open this post in threaded view
|

Re: lookup confusing me

Peter Cheung
Dear Ingleby
   Thank you for your help, from you link I finally can get all current editorpanes and the dataobjects from it, below are the code and saved it to my blog, thanks

Set<TopComponent> comps = TopComponent.getRegistry().getOpened();
for (TopComponent tc : comps) {
ModuleLib.log("tc=" + tc);
Node[] arr = tc.getActivatedNodes();
if (arr != null) {
for (int j = 0; j < arr.length; j++) {
DataObject dataObject = (DataObject) arr[j].getCookie(DataObject.class);
ModuleLib.log("dataObject=" + dataObject);
EditorCookie ec = (EditorCookie) arr[j].getCookie(EditorCookie.class);
if (ec != null) {
JEditorPane[] editorPane = ec.getOpenedPanes();
if (editorPane != null) {
ModuleLib.log("editorPane=" + editorPane);
}
}
}
}
}


From: Ingleby, Graeme <[hidden email]>
Sent: Friday, September 15, 2017 1:39 PM
To: [hidden email]
Subject: [platform-dev] Re: lookup confusing me
 
It's not clear exactly what you are trying to achieve when you say "all opened files".  

As others have said, you don't seem to understand what NetBeans Lookups are or what they are used for so I would recommend reading up on Lookup.

If you understood Lookup, you would know that the global Lookup does not allow you to find all instances of a particular class type within your application.

It's not really clear if you are trying to find all DataObject instances or if you are trying to find opened files that are associated with "editor" Top Components.

Neil provided a link to a Wiki page http://wiki.netbeans.org/DevFaqGetOpenEditorWindows that shows you how you can determine which editors are open from which you can get the associated DataObject.  If you are trying to find editor files - this is all you need.

That however would not find other DataObjects that were opened using the FileSystem/DataSystems API's directly e.g.             

If you called DataObject dobj = DataObject.find(FileUtil.toFileObject(new File("/path/to/somefile"));

When a DataObject instance is created it is registered in a DataObjectPool unfortunately this pool is not public.  You could however get the DataObjects registered in the pool using reflection.  Using a dirty hack like this really isn't recommended and you really need to understand what you are doing.   

This approach would return ALL DataObject instances and not just DataObject instances that you opened (the platform opens many configuration files, other plugins could create DataObjects).  Determining which DataObjects you are truly interested in would be another problem for you to solve. Manipulating objects you did not create/own could have serious consequences!

For demonstration purposes only:

            Field poolField = Class.forName("org.openide.loaders.DataObjectPool").getDeclaredField("POOL");
            poolField.setAccessible(true);
            Object pool = poolField.get(null);
            Field mapField = pool.getClass().getDeclaredField("map");
            mapField.setAccessible(true);
            Object map = mapField.get(pool);            
            Map<Object, Object> refMap = (Map<Object,Object>)map;
            for(Object o: refMap.values()) {
                Field objField = o.getClass().getDeclaredField("obj");
                objField.setAccessible(true);
                Reference<DataObject> result = (Reference<DataObject>)objField.get(o);
                DataObject dataObject = (DataObject)result.get();
                System.out.println(dataObject); // Here's the DataObject you want
            }

The above code would print all DataObject instances - you could return them in a list, filter objects of interest etc.

Do you intend your modules to be used within the IDE or a custom NB Platform application where you might be able to customize your harness?  If the later you could provide the functionality you need without using reflection by accessing DataObjectPool and providing a public method to return the information you need.

Hopefully you are only interested in Editor files and Neil has already provided the perfect solution for that.  

Using non-public API's is a really bad idea, but sometimes the only way to achieve what you want (I've seen reflection used within NB sources).  

Just make sure you fully understand the ramifications.



From: Peter Cheung [[hidden email]]
Sent: Thursday, September 14, 2017 12:39 PM
To: [hidden email]
Subject: [platform-dev] lookup confusing me

Hi
   I have trouble with lookup, the below code only print out the current file instead of all opened files.
Lookup lookup = Utilities.actionsGlobalContext();

Collection<? extends DataObject> list = lookup.lookupAll(DataObject.class);
for (DataObject dataObject : list) {
ModuleLib.log(dataObject);
}

If i use "Lookup.getDefault().lookupAll", looupAll() even returns nothing. Please help

Thanks
FromPeter

Reply | Threaded
Open this post in threaded view
|

Re: lookup confusing me

Peter Cheung
In reply to this post by Neil C Smith-2

Thanks Neil




From: Neil C Smith <[hidden email]>
Sent: Friday, September 15, 2017 1:37 AM
To: [hidden email]
Subject: [platform-dev] Re: lookup confusing me
 


On Thu, Sep 14, 2017 at 5:40 PM Peter Cheung <[hidden email]> wrote:
   I have trouble with lookup, the below code only print out the current file instead of all opened files.

Why would you expect it to do anything else?!

Maybe look at http://wiki.netbeans.org/DevFaqGetOpenEditorWindows or other pages on the Developer FAQ.

Best wishes,

Neil
--
Neil C Smith
Artist & Technologist

Praxis LIVE - hybrid visual IDE for creative coding - www.praxislive.org
Reply | Threaded
Open this post in threaded view
|

Re: lookup confusing me

Peter Cheung
In reply to this post by Graeme

Super Thanks Ingleby for your detailed reply.




From: Ingleby, Graeme <[hidden email]>
Sent: Friday, September 15, 2017 1:39 PM
To: [hidden email]
Subject: [platform-dev] Re: lookup confusing me
 
It's not clear exactly what you are trying to achieve when you say "all opened files".  

As others have said, you don't seem to understand what NetBeans Lookups are or what they are used for so I would recommend reading up on Lookup.

If you understood Lookup, you would know that the global Lookup does not allow you to find all instances of a particular class type within your application.

It's not really clear if you are trying to find all DataObject instances or if you are trying to find opened files that are associated with "editor" Top Components.

Neil provided a link to a Wiki page http://wiki.netbeans.org/DevFaqGetOpenEditorWindows that shows you how you can determine which editors are open from which you can get the associated DataObject.  If you are trying to find editor files - this is all you need.


That however would not find other DataObjects that were opened using the FileSystem/DataSystems API's directly e.g.             

If you called DataObject dobj = DataObject.find(FileUtil.toFileObject(new File("/path/to/somefile"));

When a DataObject instance is created it is registered in a DataObjectPool unfortunately this pool is not public.  You could however get the DataObjects registered in the pool using reflection.  Using a dirty hack like this really isn't recommended and you really need to understand what you are doing.   

This approach would return ALL DataObject instances and not just DataObject instances that you opened (the platform opens many configuration files, other plugins could create DataObjects).  Determining which DataObjects you are truly interested in would be another problem for you to solve. Manipulating objects you did not create/own could have serious consequences!

For demonstration purposes only:

            Field poolField = Class.forName("org.openide.loaders.DataObjectPool").getDeclaredField("POOL");
            poolField.setAccessible(true);
            Object pool = poolField.get(null);
            Field mapField = pool.getClass().getDeclaredField("map");
            mapField.setAccessible(true);
            Object map = mapField.get(pool);            
            Map<Object, Object> refMap = (Map<Object,Object>)map;
            for(Object o: refMap.values()) {
                Field objField = o.getClass().getDeclaredField("obj");
                objField.setAccessible(true);
                Reference<DataObject> result = (Reference<DataObject>)objField.get(o);
                DataObject dataObject = (DataObject)result.get();
                System.out.println(dataObject); // Here's the DataObject you want
            }

The above code would print all DataObject instances - you could return them in a list, filter objects of interest etc.

Do you intend your modules to be used within the IDE or a custom NB Platform application where you might be able to customize your harness?  If the later you could provide the functionality you need without using reflection by accessing DataObjectPool and providing a public method to return the information you need.

Hopefully you are only interested in Editor files and Neil has already provided the perfect solution for that.  

Using non-public API's is a really bad idea, but sometimes the only way to achieve what you want (I've seen reflection used within NB sources).  

Just make sure you fully understand the ramifications.



From: Peter Cheung [[hidden email]]
Sent: Thursday, September 14, 2017 12:39 PM
To: [hidden email]
Subject: [platform-dev] lookup confusing me

Hi
   I have trouble with lookup, the below code only print out the current file instead of all opened files.
Lookup lookup = Utilities.actionsGlobalContext();

Collection<? extends DataObject> list = lookup.lookupAll(DataObject.class);
for (DataObject dataObject : list) {
ModuleLib.log(dataObject);
}

If i use "Lookup.getDefault().lookupAll", looupAll() even returns nothing. Please help

Thanks
FromPeter