执行操作后,我使用此代码打开DataObject的TopComponent:
TopComponent tc = MultiViews.createMultiView("text/experiment+xml", expDO);
tc.open();
tc.requestActive();
这样可以正常工作,但如果我双击DataObject的节点,即使刚刚为它打开了TopComponent,也会打开一个新的TopComponent。
但是,如果我只通过双击打开TopComponent,则始终为DataObject打开一个唯一的TopComponent。
仅当我使用上面的代码打开TopComponent时才会发生此行为。 我怀疑TopComponent没有在TopComponent.registry中注册,但我不知道如何实现这一点。
编辑: 这是DataObject实现(我避免了注册mime-type和Action的注释):
public class ExperimentDataObject extends MultiDataObject implements PropertyChangeListener {
private final Logger LOGGER = Logger.getLogger(this.getClass().getName());
private Lookup lookup;
private InstanceContent ic = new InstanceContent();
private final Project project;
private final Experiment experiment;
public ExperimentDataObject(FileObject expFO, MultiFileLoader loader) throws DataObjectExistsException, IOException {
super(expFO, loader);
registerEditor("text/experiment+xml", true);
this.project = FileOwnerQuery.getOwner( expFO );
this.experiment = getObject();
this.experiment.setConfigFile(expFO);
experiment.addPropertyChangeListener(this);
expFO.setAttribute(AwsItem.ITEM_TYPE, AwsItemType.EXPERIMENT);
expFO.setAttribute(AwsItem.PROP_PROJECT, this.project);
LOGGER.trace("ExperimentDataObject " + this.getName() + " created.");
}
@Override
protected int associateLookup() {
return 1;
}
private class MyOpenCookie implements OpenCookie {
public void open(){
TopComponent tc = MultiViews.createMultiView("text/experiment+xml", ExperimentDataObject.this);
tc.open();
tc.requestActive();
}
}
/**
* Lookup implementation.
* @return
*/
@Override
public Lookup getLookup() {
if (lookup == null) {
lookup = new AbstractLookup(ic);
ic.add(this);
ic.add(project);
ic.add(experiment);
ic.add(new MyOpenCookie());
}
LOGGER.trace("ExperimentDO.getLookup() called.");
return lookup;
}
/**
* Creates the ExperimentDataNode for this DataObject
* @return
*/
@Override
protected Node createNodeDelegate() {
return new ExperimentDataNode(this);
}
/**
* Generates the experiment java object.<br>
* It must be created when the DataObject is constructed, in this way, the instance object is in
* the lookup of the DataObject.
*
* @return Experiment instance object
*/
private Experiment getObject() throws IOException {
XStream xstream = new XStream(new PureJavaReflectionProvider());
xstream.processAnnotations(Experiment.class);
return (Experiment) xstream.fromXML(FileUtil.toFile(this.getPrimaryFile()));
}
/**
* Saves the experiment java object to the config FileObject.<br>Doesn't matter if the experiment object has charged dataConfig in its DataItem's, because the object Experiment.ChannelData.dataItems is transient and they are not serialized.
*/
public void saveConfig() throws IOException {
FileLock doFileLock = this.getPrimaryFile().lock();
String xmlStr;
XStream xstream = new XStream(new DomDriver());
xstream.processAnnotations(Experiment.class);
xmlStr = xstream.toXML(experiment);
byte[] bytes = xmlStr.getBytes(Charset.forName("UTF-8"));
OutputStream os = this.getPrimaryFile().getOutputStream(doFileLock);
os.write(bytes);
os.flush();
os.close();
doFileLock.releaseLock();
os = null;
}
/**
* Detects change events in the the AwsItem object.<br>
可以从AwsItem或AwsItem的ChannelData对象触发属性更改 * * @param evt * / @覆盖 public void propertyChange(PropertyChangeEvent evt){
if (evt.getPropertyName() == AwsItem.PROP_CONFIG) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
saveConfig();
} catch (IOException ex) {
LOGGER.warn("Problem saving changes in AwsItem.", ex);
}
}
});
}
}
}
这是DataNode代码: 公共类ExperimentDataNode扩展了DataNode {
public static final String EXPERIMENT_NODE_ICON = "com/aws/experiment/resources/experiment.png";
private final ExperimentDataObject expDO;
private final Logger LOGGER = Logger.getLogger(this.getClass().getName());
public ExperimentDataNode(ExperimentDataObject expDO) {
super(expDO, Children.LEAF);
this.expDO = expDO;
}
@Override
public Action[] getActions(boolean context) {
return new Action[]{
SystemAction.get(OpenAction.class),
SystemAction.get(RenameAction.class),
SystemAction.get(DeleteAction.class),
};
}
public String getHtmlDisplayName() {
String result = this.getDataObject().getName();
if (result != null) return result;
else return "Experiment";
}
@Override
public boolean canRename() {
return true;
}
/**
* Renames the DataNode and the DataObject.<br>
* Also renames the object Experiment that DataObject represents.
* @param name
* @param renameDO
*/
@Override
public void setName(String name, boolean renameDO) {
super.setName(name, true);
Experiment exp = this.expDO.getLookup().lookup(Experiment.class);
exp.setName(name);
}
@Override
public boolean canDestroy() {
return true;
}
/**
* Deletes the DataObject and the data file associated to it.
* @throws IOException
*/
@Override
public void destroy() throws IOException {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
Mode editorMode = WindowManager.getDefault().findMode("editor");
TopComponent[] openTopComponentsInEditorMode = editorMode.getTopComponents();
for (TopComponent tc : openTopComponentsInEditorMode) {
if ( tc.getLookup().lookup(DataObject.class) == expDO) {
tc.close();
}
}
try {
Experiment experiment = expDO.getLookup().lookup(Experiment.class);
experiment.deleteChannelData();
expDO.delete();
fireNodeDestroyed();
} catch (IOException ex) {
LOGGER.warn("Problem deleting item experiment.", ex);
}
}
});
}
}
答案 0 :(得分:0)
import org.openide.cookies.EditorCookie;
EditorCookie ec = expDO.getLookup()。lookup(EditorCookie.class); ec.openDocument();
OR
import org.openide.cookies.OpenCookie;
OpenCookie ec = expDO.getLookup()。lookup(OpenCookie.class); ec.open();
如果OpenCookie为null,则在DataObject中,使用以下方法之一添加缺少的Cookie。
public class MyMultiDataObject extends MultiDataObject {
public MyMultiDataObject(FileObject fileObj, DataLoader loader)
throws DataObjectExistsException {
super(fileObj, loader);
getCookieSet().add(new MyOpenCookie());
}
private class MyOpenCookie implements OpenCookie {
public void open(){
//Open your desired TopCompnent; Call your current double click action that has the desired behavior
}
}
}
或者更好的是,只需在构造函数中调用MultiDataObject.regiserEditor(...)方法;
public class MyMultiDataObject extends MultiDataObject {
public MyMultiDataObject(FileObject fileObj, DataLoader loader)
throws DataObjectExistsException {
super(fileObj, loader);
registerEditor("text/experiment+xml", true);
}
}
取自MultiDataObject
/** Utility method to register editor for this {@link DataObject}.
* Call it from constructor with appropriate mimeType. The system will
* make sure that appropriate cookies ({@link Openable}, {@link Editable},
* {@link CloseCookie}, {@link EditorCookie}, {@link SaveAsCapable},
* {@link LineCookie} are registered into {@link #getCookieSet()}.
* <p>
* The selected editor is <a href="@org-netbeans-core-multiview@/org/netbeans/core/api/multiview/MultiViews.html">
* MultiView component</a>, if requested (this requires presence of
* the <a href="@org-netbeans-core-multiview@/overview-summary.html">MultiView API</a>
* in the system. Otherwise it is plain {@link CloneableEditor}.
*
* @param mimeType mime type to associate with
* @param useMultiview should the used component be multiview?
* @since 7.27
*/
protected final void registerEditor(final String mimeType, boolean useMultiview) {
MultiDOEditor.registerEditor(this, mimeType, useMultiview);
}