新建设置教程

走着路睡觉大约 4 分钟

新建设置教程

概述

这个教程介绍如何一步一步地创建一个应用级的(Application-level)设置项。很多设置项用的类比较少。但是为了便于理解,在示例settingsopen in new window 中使用了以下3个类:

  • AppSettingsConfigurable 相当于MVC 模式中的Controller,它控制着下面2个类于IntelliJ Platform 进行交互

  • AppSettingsState 持久化数据模型

  • AppSettingsComponent 相当于MVC模式中的View, 它负责显示和对设置项表单进行编辑。

应用级的(Application-level)设置项和项目级的(Project-level)设置项实现基本一样,只在 Configurable实现类 构造器和 扩展点配置 上有一些小区别

提示

如果使用 Kotlin语言开发,可以参考 MarkdownSettingsopen in new windowMarkdownSettingsConfigurableopen in new window

AppSettingsState

AppSettingsState类是持久化数据类,它基于持久化组件数据

创建AppSettingsState类

持久化数据类需要实现 PersistentStateComponent 接口。详情查询持久化数据相关文档:持久化组件数据

/**
 * Supports storing the application settings in a persistent way.
 * The {@link State} and {@link Storage} annotations define the name of the data and the file name where
 * these persistent application settings are stored.
 */
 //该注解定义了持久化文件的存储地址,详情查询持久化数据相关文档:[持久化组件数据](/idea-docs/Part%20II%20—%20Base%20Platform/Persistence/Persisting%20State%20of%20Components.md)
@State(
        name = "org.intellij.sdk.settings.AppSettingsState",
        storages = @Storage("SdkSettingsPlugin.xml")
)
public class AppSettingsState implements PersistentStateComponent<AppSettingsState> {

  public String userId = "John Q. Public";
  public boolean ideaStatus = false;

  public static AppSettingsState getInstance() {
    return ApplicationManager.getApplication().getService(AppSettingsState.class);
  }

  @Nullable
  @Override
  //定义自己为持久化数据类
  public AppSettingsState getState() {
    return this;
  }

  @Override
  public void loadState(@NotNull AppSettingsState state) {
    XmlSerializerUtil.copyBean(state, this);
  }

}

持久化文件存储地址:

运行插件后上述的持久化文件存储地址如下:

成员变量持久化

public 成员变量和annotatedopen in new window 中的注解标记的 private 成员变量(其它请查看 自定义持久化数据的Xml格式 )自动序列化到 xml文件 里来持久化。

如果某一个public成员变量或某些属性不需要持久化,可以使用 @com.intellij.util.xmlb.annotations.Transient 来标记成员变量或成员变量的 getter 方法。

AppSettingState方法介绍

加载组件时调用 PersistentStateComponent.loadState() 方法,保存数据的时候会调用 PersistentStateComponent.getState()

注册AppSettingsState类

这个示例是应用级的设置项,所以持久化数据类AppSettingsState 需要在plugin.xml 里注册为应用级的服务 ,注意:不能使用轻服务

<extensions defaultExtensionNs="com.intellij">
  <applicationService
      serviceImplementation="org.intellij.sdk.settings.AppSettingsState"/>
</extensions>

AppSettingsComponent

AppSettingsComponentopen in new window 提供设置项的配置表单

创建AppSettingsComponent

下面AppSettingsComponent 示例定义了包含文本框和checkbox的表单,并映射到了上文中的 AppSettingsState

/**
 * Supports creating and managing a {@link JPanel} for the Settings Dialog.
 */
public class AppSettingsComponent {

  private final JPanel myMainPanel;
  private final JBTextField myUserNameText = new JBTextField();
  private final JBCheckBox myIdeaUserStatus = new JBCheckBox("Do you use IntelliJ IDEA? ");

  public AppSettingsComponent() {
    myMainPanel = FormBuilder.createFormBuilder()
            .addLabeledComponent(new JBLabel("Enter user name: "), myUserNameText, 1, false)
            .addComponent(myIdeaUserStatus, 1)
            .addComponentFillVertically(new JPanel(), 0)
            .getPanel();
  }

  public JPanel getPanel() {
    return myMainPanel;
  }

  public JComponent getPreferredFocusedComponent() {
    return myUserNameText;
  }

  @NotNull
  public String getUserNameText() {
    return myUserNameText.getText();
  }

  public void setUserNameText(@NotNull String newText) {
    myUserNameText.setText(newText);
  }

  public boolean getIdeaUserStatus() {
    return myIdeaUserStatus.isSelected();
  }

  public void setIdeaUserStatus(boolean newStatus) {
    myIdeaUserStatus.setSelected(newStatus);
  }

}

AppSettingsConfigurable

IntelliJ Platform 调用 AppSettingsConfigurableAppSettingsConfigurable 负责与 AppSettingsComponentAppSettingState 交互。

创建AppSettingsConfigurable

实现了 Configurable 接口,定义了 AppSettingsComponent 成员变量来获取表单:

/**
 * Provides controller functionality for application settings.
 */
public class AppSettingsConfigurable implements Configurable {

  private AppSettingsComponent mySettingsComponent;

  // A default constructor with no arguments is required because this implementation
  // is registered as an applicationConfigurable EP

  @Nls(capitalization = Nls.Capitalization.Title)
  @Override
  public String getDisplayName() {
    return "SDK: Application Settings Example";
  }

  @Override
  public JComponent getPreferredFocusedComponent() {
    return mySettingsComponent.getPreferredFocusedComponent();
  }

  @Nullable
  @Override
  public JComponent createComponent() {
    mySettingsComponent = new AppSettingsComponent();
    return mySettingsComponent.getPanel();
  }

  @Override
  public boolean isModified() {
    AppSettingsState settings = AppSettingsState.getInstance();
    boolean modified = !mySettingsComponent.getUserNameText().equals(settings.userId);
    modified |= mySettingsComponent.getIdeaUserStatus() != settings.ideaStatus;
    return modified;
  }

  @Override
  public void apply() {
    AppSettingsState settings = AppSettingsState.getInstance();
    settings.userId = mySettingsComponent.getUserNameText();
    settings.ideaStatus = mySettingsComponent.getIdeaUserStatus();
  }

  @Override
  public void reset() {
    AppSettingsState settings = AppSettingsState.getInstance();
    mySettingsComponent.setUserNameText(settings.userId);
    mySettingsComponent.setIdeaUserStatus(settings.ideaStatus);
  }

  @Override
  public void disposeUIResources() {
    mySettingsComponent = null;
  }

}

方法描述

开发者可以查看 Configurable 接口的文档来了解详情,也可以查看设置指南 中的 IntelliJ Platform和Configurable接口交互 部分

注册AppSettingsConfigurable

plugin.xml 里注册 AppSettingsConfigurable

<extensions defaultExtensionNs="com.intellij">
  <applicationConfigurable
      parentId="tools"
      instance="org.intellij.sdk.settings.AppSettingsConfigurable"
      id="org.intellij.sdk.settings.AppSettingsConfigurable"
      displayName="SDK: Application Settings Example"/>
</extensions>

测试

运行插件后,在 Settings/Preferences | Tools 出现 SDK: Application Settings Example 配置项,如下图:

settings_defaults.png

code_samples/settings/build/idea-sandbox/config/options/ 文件夹中查看插件持久化文件 SdkSettingsPlugin.xml ,如下图:

settings_persisted.png

上次编辑于:
贡献者: zhaojingbo
Loading...