简体   繁体   English

检索并设置IntelliJ IDEA插件开发的拆分窗口设置

[英]Retrieving and setting split window settings for IntelliJ IDEA plugin development

I am writing an IntelliJ IDEA plugin for saving sessions of open tabs called Tab Session . 我正在编写一个IntelliJ IDEA插件,用于保存名为Tab Session的打开选项卡的会话 This question is a follow-up of IntelliJ IDEA Plugin Development: Save groups of tabs, save them persistently and reload a set of tabs if requested by the user . 这个问题是IntelliJ IDEA插件开发的后续工作:保存选项卡组,持久保存它们,并在用户请求时重新加载一组选项卡

Currently, splitted windows are not supported. 目前,不支持分割窗口。 Therefore i want to do two things: 因此我想做两件事:

  1. Retrieve information about all splitted or unsplitted windows that are containers for editor tabs. 检索有关作为编辑器选项卡容器的所有拆分或未拆分窗口的信息。 I need their position and split direction (horizontal or vertical). 我需要它们的位置和分割方向(水平或垂直)。
  2. When this information is saved and a tab session needs to be loaded, i need to reconstruct the splitted panes and their tabs exactly as they were before. 保存此信息并需要加载选项卡会话时,我需要完全按照以前的方式重建拆分的窗格及其选项卡。

Due to the lack of documentation i am currently browsing through the source code and found this promising piece of code: 由于缺乏文档,我目前正在浏览源代码并找到了这段有用的代码:

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

It allows me to iterate through the set of splitted windows by using EditorWindow[] windows = getSplittersFromFocus.getOrderedWindows() . 它允许我使用EditorWindow[] windows = getSplittersFromFocus.getOrderedWindows()遍历分割窗口集。 They contain the editor tabs and information about their width and height. 它们包含编辑器选项卡以及有关其宽度和高度的信息。 But i did not find any information about the split direction and how to reconstruct the splitted windows as they were before. 但我没有找到任何有关分割方向的信息以及如何重建分割窗口,就像以前一样。

Can anyone help? 有人可以帮忙吗?

This is untested code, but as it closely resmbles the procedures inside EditorsSplitters writeExternal and writePanel functions I am positive this will work. 这是未经测试的代码,但由于它紧密地重新编写EditorsSplitters writeExternalwritePanel函数内部的程序,我很肯定这将有效。

Presented are two methods: 提出了两种方法:

  • access output of writeExternal -> should be the more stable API and offers easier access to file information 访问writeExternal输出 - >应该是更稳定的API,并提供更容易的文件信息访问
  • access components of splitter -> this way writeExternal creates it's information; 访问分割器的组件 - >这样writeExternal创建它的信息; sadly there is at least one protected field without getter involved ( window.myPanel inside findWindowWith ) 遗憾的是,至少有一个没有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;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM