【问题标题】:Retrieving and setting split window settings for IntelliJ IDEA plugin development检索和设置 IntelliJ IDEA 插件开发的拆分窗口设置
【发布时间】:2013-11-01 14:12:03
【问题描述】:

我正在编写一个 IntelliJ IDEA 插件,用于保存名为 Tab Session 的打开选项卡的会话。这个问题是IntelliJ IDEA Plugin Development: Save groups of tabs, save them persistently and reload a set of tabs if requested by the user的后续问题。

目前不支持拆分窗口。因此我想做两件事:

  1. 检索有关作为编辑器选项卡容器的所有拆分或未拆分窗口的信息。我需要它们的位置和分割方向(水平或垂直)。
  2. 保存此信息并需要加载选项卡会话时,我需要完全按照以前的方式重建拆分的窗格及其选项卡。

由于缺乏文档,我目前是 browsing through the source code 并找到了这段很有前途的代码:

private EditorsSplitters getSplittersFromFocus() {
  return FileEditorManagerEx.getInstanceEx(myProject).getSplitters();
}

它允许我使用EditorWindow[] windows = getSplittersFromFocus.getOrderedWindows() 遍历分割的窗口集。它们包含编辑器选项卡以及有关其宽度和高度的信息。但是我没有找到任何关于分割方向以及如何像以前一样重建分割窗口的信息。

谁能帮忙?

【问题讨论】:

  • 你试过Open API and Plugin Development论坛吗?我在那里回答了一些关于插件开发的问题。在我的一篇文章之后,Dmitry Jemerov 更新了核心 IDEA API 以帮助我继续开发。
  • 是的,我做到了:devnet.jetbrains.com/thread/451243?tstart=0 - 我完全错过了这个答案!谢谢你提醒我
  • 和你的问题有点无关,但是你的插件和IntelliJ Context在哪些方面有区别呢?
  • IntelliJ 上下文是什么意思?
  • 期待答案...

标签: java intellij-idea intellij-plugin


【解决方案1】:

这是未经测试的代码,但由于它与 EditorsSplitters writeExternalwritePanel 函数中的过程非常相似,所以我很肯定这会起作用。

提出了两种方法:

  • writeExternal 的访问输出 -> 应该是更稳定的 API,并且更容易访问文件信息
  • 访问拆分器的组件 -> 这样writeExternal 创建它的信息;遗憾的是,至少有一个受保护的字段没有涉及 getter(window.myPanelfindWindowWith
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.impl.EditorsSplitters;
import com.intellij.openapi.fileEditor.impl.FileEditorManagerImpl;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Splitter;
import org.jdom.Element;

import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;

public class SplitterAction extends AnAction {

    public SplitterAction() {
        super("Splitter _Action");
    }

    private static class Info {

    }

    private static class SplitInfo extends Info {
        public Info    first;
        public Info    second;
        public boolean vertical;
        public float   proportions;
    }

    private static class FileInfo extends Info {
        public String[] fileNames;
    }

    @Override
    public void actionPerformed(AnActionEvent anActionEvent) {
        final Project project = anActionEvent.getProject();
        final FileEditorManagerImpl fileEditorManager = (FileEditorManagerImpl) FileEditorManager.getInstance(project);
        EditorsSplitters splitters = fileEditorManager.getSplitters();
        // com.intellij.openapi.fileEditor.impl.EditorsSplitters.writeExternal() and
        // com.intellij.openapi.fileEditor.impl.EditorsSplitters#writePanel inspired this
        final Component component = splitters.getComponent(0);
        final SplitInfo infos = splitterVisitor(component);

        // or you could use this
        Element root = new Element("root");
        splitters.writeExternal(root);

        elementVisitor(root);

        // to restore from writeExternal the following should suffice
        splitters.readExternal(root);
        splitters.openFiles();
    }

    /**
     * Reads writeExternal output
     */
    private Info elementVisitor(Element root) {
        final Element splitter = root.getChild("splitter");
        if (splitter != null) {
            // see com.intellij.openapi.fileEditor.impl.EditorsSplitters#writePanel
            final SplitInfo splitInfo = new SplitInfo();
            // "vertical" or "horizontal"
            splitInfo.vertical = "vertical".equals(splitter.getAttributeValue("split-orientation"));
            splitInfo.proportions = Float.parseFloat(splitter.getAttributeValue("split-proportion"));
            Element first = splitter.getChild("split-first");
            if (first != null) {
                splitInfo.first = elementVisitor(first);
            }
            Element second = splitter.getChild("split-second");
            if (second != null) {
                splitInfo.second = elementVisitor(second);
            }
            return splitInfo;
        }
        final Element leaf = root.getChild("leaf");
        if (leaf != null) {
            final ArrayList<String> fileNames = new ArrayList<String>();
            for (Element file : leaf.getChildren("file")) {
                final String fileName = file.getAttributeValue("leaf-file-name");
                fileNames.add(fileName);
                // further attributes see com.intellij.openapi.fileEditor.impl.EditorsSplitters#writeComposite
            }
            final FileInfo fileInfo = new FileInfo();
            fileInfo.fileNames = fileNames.toArray(new String[fileNames.size()]);
            return fileInfo;
        }
        return null;
    }

    /**
     * Acts directly upon Component
     */
    private SplitInfo splitterVisitor(Component component) {
        if (component instanceof JPanel && ((JPanel) component).getComponentCount() > 0) {
            final Component child = ((JPanel) component).getComponent(0);
            if (child instanceof Splitter) {
                final Splitter splitter = (Splitter) child;
                final SplitInfo splitInfos = new SplitInfo();
                splitInfos.vertical = splitter.isVertical();
                splitInfos.proportions = splitter.getProportion();
                splitInfos.first = splitterVisitor(splitter.getFirstComponent());
                splitInfos.second = splitterVisitor(splitter.getSecondComponent());
                return splitInfos;
            }
            // TODO: retrieve file information
        }
        return null;
    }
}

【讨论】:

  • 多么糟糕的插件开发 API。 2020. 不过,谢谢,firstvisitor 仍然有效。您碰巧知道如何更改拆分器的大小吗?我得到了大小比例,但没有设置方法......它应该在窗口上,但它在哪里。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-02-04
  • 1970-01-01
  • 2023-03-21
  • 2012-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多