私はアクションを実行した後に、このコードでのDataObjectのためにトップコンポーネントをopenningています:Openningプログラム的にトップコンポーネント
TopComponent tc = MultiViews.createMultiView("text/experiment+xml", expDO);
tc.open();
tc.requestActive();
これは正常に動作しますが、私はDataObjectのノードの中でダブルクリックすると、新しいトップコンポーネントは、 TopComponentがそのために開かれているにもかかわらず、開いています。
しかし、ダブルクリックでTopComponetを開くだけでは、常に1つの唯一のTopComponentがDataObjectに対して開かれます。
この現象は、上記のコードでTopComponentを開いた場合にのみ発生します。 TopComponentがTopComponent.registryに登録されていないと思われますが、これを実現する方法はわかりません。
何か助けていただければ幸いです。
編集: これはDataObjectの実装(Iは、MIMEタイプとアクションの登録注釈を避けました)です:
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 */ @Override公共ボイドの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);
}
}
});
}
}
}
これはデータノード・コードである: パブリッククラスExperimentDataNodeはデータノード{
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);
}
}
});
}
}
独自のマルチビューを作成し、代わりにDataObjectのOpenCookieがあなたのためにトップコンポーネントを開いていません。これは、DataNodeをダブルクリックしたときに実行されます。 – sproger
参照:http://wiki.netbeans.org/DevFaqDataObject – sproger
しかし、このメソッドは、DataObjectにOpenSupportやOpenCookieのようなインタフェースや抽象クラスを実装することを意味しますか?実際に私のDataObjectクラスはMultiDataObjectを拡張しており、ダブルクリックすると開くために何も実装する必要はありません。あなたが提案するようにしたら、open()メソッドを実装する必要があります。どのように抽象的なOpenCookieまたはOpenSupportを配置できますか? – pacobm