以编程方式打开TopComponent

时间:2016-05-13 10:15:25

标签: java netbeans

执行操作后,我使用此代码打开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);
            }
        }
    });
}
}

1 个答案:

答案 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);
    }