Settings tutorial: Change the implementation to follow the recommended approach (a separate state class)

Also:
- remove unnecessary screenshot
- change labels to follow UX guidelines
This commit is contained in:
Karol Lewandowski 2024-06-20 12:42:04 +02:00
parent 90553c0511
commit 5a256a5e9a
6 changed files with 73 additions and 63 deletions

View File

@ -4,8 +4,8 @@
## Quickstart ## Quickstart
This project illustrates a custom Application-level Settings through the implementation of: This project illustrates a custom Application-level Settings through the implementation of:
- `AppSettingsConfigurable` is analogous to a Controller in the MVC model - it interacts with the other two Settings classes and the IntelliJ Platform, - `AppSettingsConfigurable` is analogous to a Controller in the MVC model it interacts with the other two Settings classes and the IntelliJ Platform,
- `AppSettingsState` is like a Model because it stores the Settings persistently, - `AppSettings` is like a Model because it stores the Settings persistently,
- `AppSettingsComponent` is similar to a View because it displays and captures edits to the values of the Settings. - `AppSettingsComponent` is similar to a View because it displays and captures edits to the values of the Settings.
### Extension Points ### Extension Points
@ -13,7 +13,7 @@ This project illustrates a custom Application-level Settings through the impleme
| Name | Implementation | Extension Point Class | | Name | Implementation | Extension Point Class |
|----------------------------------------|---------------------------------------------------------|----------------------------| |----------------------------------------|---------------------------------------------------------|----------------------------|
| `com.intellij.applicationConfigurable` | [AppSettingsConfigurable][file:AppSettingsConfigurable] | `Configurable` | | `com.intellij.applicationConfigurable` | [AppSettingsConfigurable][file:AppSettingsConfigurable] | `Configurable` |
| `com.intellij.applicationService` | [AppSettingsState][file:AppSettingsState] | `PersistentStateComponent` | | `com.intellij.applicationService` | [AppSettings][file:AppSettings] | `PersistentStateComponent` |
*Reference: [Plugin Extension Points in IntelliJ SDK Docs][docs:ep]* *Reference: [Plugin Extension Points in IntelliJ SDK Docs][docs:ep]*
@ -23,5 +23,4 @@ This project illustrates a custom Application-level Settings through the impleme
[docs:ep]: https://plugins.jetbrains.com/docs/intellij/plugin-extensions.html [docs:ep]: https://plugins.jetbrains.com/docs/intellij/plugin-extensions.html
[file:AppSettingsConfigurable]: ./src/main/java/org/intellij/sdk/settings/AppSettingsConfigurable.java [file:AppSettingsConfigurable]: ./src/main/java/org/intellij/sdk/settings/AppSettingsConfigurable.java
[file:AppSettingsState]: ./src/main/java/org/intellij/sdk/settings/AppSettingsState.java [file:AppSettings]: ./src/main/java/org/intellij/sdk/settings/AppSettings.java

View File

@ -0,0 +1,49 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.intellij.sdk.settings;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.openapi.components.State;
import com.intellij.openapi.components.Storage;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
/*
* Supports storing the application settings in a persistent way.
* The {@link com.intellij.openapi.components.State State} and {@link Storage}
* annotations define the name of the data and the filename where these persistent
* application settings are stored.
*/
@State(
name = "org.intellij.sdk.settings.AppSettings",
storages = @Storage("SdkSettingsPlugin.xml")
)
final class AppSettings
implements PersistentStateComponent<AppSettings.State> {
static class State {
@NonNls
public String userId = "John Smith";
public boolean ideaStatus = false;
}
private State myState = new State();
static AppSettings getInstance() {
return ApplicationManager.getApplication()
.getService(AppSettings.class);
}
@Override
public State getState() {
return myState;
}
@Override
public void loadState(@NotNull State state) {
myState = state;
}
}

View File

@ -1,4 +1,4 @@
// Copyright 2000-2022 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. // Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.intellij.sdk.settings; package org.intellij.sdk.settings;
@ -17,11 +17,11 @@ public class AppSettingsComponent {
private final JPanel myMainPanel; private final JPanel myMainPanel;
private final JBTextField myUserNameText = new JBTextField(); private final JBTextField myUserNameText = new JBTextField();
private final JBCheckBox myIdeaUserStatus = new JBCheckBox("Do you use IntelliJ IDEA? "); private final JBCheckBox myIdeaUserStatus = new JBCheckBox("IntelliJ IDEA user");
public AppSettingsComponent() { public AppSettingsComponent() {
myMainPanel = FormBuilder.createFormBuilder() myMainPanel = FormBuilder.createFormBuilder()
.addLabeledComponent(new JBLabel("Enter user name: "), myUserNameText, 1, false) .addLabeledComponent(new JBLabel("User name:"), myUserNameText, 1, false)
.addComponent(myIdeaUserStatus, 1) .addComponent(myIdeaUserStatus, 1)
.addComponentFillVertically(new JPanel(), 0) .addComponentFillVertically(new JPanel(), 0)
.getPanel(); .getPanel();

View File

@ -6,6 +6,7 @@ import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import javax.swing.*; import javax.swing.*;
import java.util.Objects;
/** /**
* Provides controller functionality for application settings. * Provides controller functionality for application settings.
@ -14,8 +15,8 @@ final class AppSettingsConfigurable implements Configurable {
private AppSettingsComponent mySettingsComponent; private AppSettingsComponent mySettingsComponent;
// A default constructor with no arguments is required because this implementation // A default constructor with no arguments is required because
// is registered in an applicationConfigurable EP // this implementation is registered as an applicationConfigurable
@Nls(capitalization = Nls.Capitalization.Title) @Nls(capitalization = Nls.Capitalization.Title)
@Override @Override
@ -37,24 +38,26 @@ final class AppSettingsConfigurable implements Configurable {
@Override @Override
public boolean isModified() { public boolean isModified() {
AppSettingsState settings = AppSettingsState.getInstance(); AppSettings.State state =
boolean modified = !mySettingsComponent.getUserNameText().equals(settings.userId); Objects.requireNonNull(AppSettings.getInstance().getState());
modified |= mySettingsComponent.getIdeaUserStatus() != settings.ideaStatus; return !mySettingsComponent.getUserNameText().equals(state.userId) ||
return modified; mySettingsComponent.getIdeaUserStatus() != state.ideaStatus;
} }
@Override @Override
public void apply() { public void apply() {
AppSettingsState settings = AppSettingsState.getInstance(); AppSettings.State state =
settings.userId = mySettingsComponent.getUserNameText(); Objects.requireNonNull(AppSettings.getInstance().getState());
settings.ideaStatus = mySettingsComponent.getIdeaUserStatus(); state.userId = mySettingsComponent.getUserNameText();
state.ideaStatus = mySettingsComponent.getIdeaUserStatus();
} }
@Override @Override
public void reset() { public void reset() {
AppSettingsState settings = AppSettingsState.getInstance(); AppSettings.State state =
mySettingsComponent.setUserNameText(settings.userId); Objects.requireNonNull(AppSettings.getInstance().getState());
mySettingsComponent.setIdeaUserStatus(settings.ideaStatus); mySettingsComponent.setUserNameText(state.userId);
mySettingsComponent.setIdeaUserStatus(state.ideaStatus);
} }
@Override @Override

View File

@ -1,40 +0,0 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.intellij.sdk.settings;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.openapi.components.State;
import com.intellij.openapi.components.Storage;
import com.intellij.util.xmlb.XmlSerializerUtil;
import org.jetbrains.annotations.NotNull;
/**
* 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.
*/
@State(
name = "org.intellij.sdk.settings.AppSettingsState",
storages = @Storage("SdkSettingsPlugin.xml")
)
final class AppSettingsState implements PersistentStateComponent<AppSettingsState> {
public String userId = "John Q. Public";
public boolean ideaStatus = false;
static AppSettingsState getInstance() {
return ApplicationManager.getApplication().getService(AppSettingsState.class);
}
@Override
public AppSettingsState getState() {
return this;
}
@Override
public void loadState(@NotNull AppSettingsState state) {
XmlSerializerUtil.copyBean(state, this);
}
}

View File

@ -1,5 +1,4 @@
<!-- Copyright 2000-2023 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. --> <!-- Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -->
<!-- Plugin Configuration File. Read more: https://plugins.jetbrains.com/docs/intellij/plugin-configuration-file.html -->
<idea-plugin> <idea-plugin>
@ -35,7 +34,7 @@
<applicationConfigurable parentId="tools" instance="org.intellij.sdk.settings.AppSettingsConfigurable" <applicationConfigurable parentId="tools" instance="org.intellij.sdk.settings.AppSettingsConfigurable"
id="org.intellij.sdk.settings.AppSettingsConfigurable" id="org.intellij.sdk.settings.AppSettingsConfigurable"
displayName="SDK: Application Settings Example"/> displayName="SDK: Application Settings Example"/>
<applicationService serviceImplementation="org.intellij.sdk.settings.AppSettingsState"/> <applicationService serviceImplementation="org.intellij.sdk.settings.AppSettings"/>
</extensions> </extensions>
</idea-plugin> </idea-plugin>