Write an Android Studio Plugin Part 3: Settings

Marcos Holgado
ProAndroidDev
Published in
7 min readDec 7, 2018

--

In the second part of this series we learnt how to persist data using components and also how to use that data to trigger a notification when users updated our plugin to show them what’s new. In today’s article we will see how we can use the data that we are persisting to create a settings screen.

Remember that you can find all the code for this series on GitHub and you can also see the relevant code for each article on its own branch, this article’s code is in the branch Part3.

https://github.com/marcosholgado/plugin-medium

What are we going to do?

The goal of today’s article is to create a settings screen for our plugin. This is going to be our first step towards creating an action to move tickets on Jira. Our settings screen will just have a username and a password field that our plugin will use to interact with the Jira APIs. We also want to be able to have different settings per project allowing the users to have different Jira accounts depending on the project (this may be useful).

Step 1: Create a new project component

In the second part of the series we already learnt what a component is and we also learnt that there are three different types of components. Because we want to be able to have different settings depending on our Android Studio projects the obvious choice is to create a new project component.

We are basically copying and pasting the component that we created previously but removing all the unnecessary methods and adding our two new fields. These fields are going to be public since we will use them in another part of our plugin. The other difference is that we are now extending from AbstractProjectComponent which implements the ProjectComponent interface and, of course, it also needs a project. Finally, we have a companion object which, given a project, will provide the instance of our JiraComponent. This will allow us to access the data that we are storing from other places within our plugin. Our new JiraComponent looks like this:

Like we did in the previous article we also have to register the component in our plugin.xml file

<project-components>
<!-- Add your project components here -->
<component>
<implementation-class>
components.JiraComponent
</implementation-class>
</component>
</project-components>

Step 2: UI

Before we can continue with our settings screen we need to understand how the UI works on IntelliJ which is by using Java Swing Forms. IntelliJ has a lot of Swing components that you can use so the UI of your plugin is kept consistent with the rest of the IDE. But don’t let the Java name fool you because you can still convert that code to Kotlin.

One way of creating a new GUI (graphical user interface) is by simply right clicking and going to New and then GUI Form. That will create a new file call YourName.form which will be linked to another one call YourName.java. If you want to have a go with the IntelliJ designer, be my guest, but we are going to do something different that I prefer over using IntelliJ. I’ll give you a hint.

Photo by Jongsun Lee on Unsplash

We are going to use Eclipse! Yay!

I know what you are thinking, but I have to be honest, it just works really well for me. For some reason the IntelliJ designer is really annoying and I can’t get the results that I want but, if you are happy with IntelliJ by any means keep using it!

Back to Eclipse, you can just download it from here. I currently have Oxygen.3a Release (4.7.3a) which is a bit old but it doesn’t really matter for what we want to do. Just create a new project and then right click, New, Other and select JPanel.

And after playing around with the designer this is how our settings look like in Eclipse.

The last thing we will do in Eclipse is going to the source code of the UI we just created and copy it. You can now close eclipse, it wasn’t that bad wasn’t it?

Back to our plugin, we are now going to create a new package called settings and a new class called JiraSettings. In that class we will create a new method called createComponent() and finally we can now paste inside that method the source code that we copied from Eclipse. This is also the time to convert that code to Kotlin, you can do it automatically and it should be fine.

After doing all this you will probably have a few errors so let’s fix them.

The first thing we need to fix is that our createComponent() method has to return a JComponent, we will see why later.

Because Eclipse assumes we are already in a JPanel you can see a lot of add methods or methods that doesn’t seem to exist, the reason is because we are not in a JPanel. To sort that out we have to create a new JPanel and give it some bounds (you can get the values from the JPanel we created in Eclipse) and since JPanel extends from JComponent we will return it in our method.

Finally we just need some tweaking around to make the whole thing compile. You should end up with something like this:

Step 3: Extensions and extension points

Before we can move on with our settings screen we have to talk about extensions and extension points. These are going to allow your plugin to interact with other plugins or with the IDE itself.

  • If you want to extend the functionality of other plugins or the IDE you have to declare one or several extensions.
  • If you want your plugin to allow other plugins to extend its functionality, then you must declare one or several extension points.

Because we want to add our settings screen into the Android Studio preferences, what we are really doing is extending the functionality of Android Studio, so we are going to have to declare an extension.

To do that we have to implement Configurable and when doing that we will also have to override a few methods.

  • Luckily we already had a createComponent() method so we can just add the keyword override and be done with it.
  • We are going to create a new modified boolean which we’ll give false as a value and return that on the isModified method. We will come back to this later, for now suffice to say this is what enables or disables the apply button in the settings screen.
  • We will give our settings page a name on getDisplayName().
  • In the apply method we need to write the code that will be executed when the user clicks on Apply. Quite simple really, we just get the instance of our JiraComponent for the specific project the user is in and we save the values from the UI to the component. Finally we set modified to false because at that point we want to disable the apply button.

The end result should look like this:

Step 4: Fixing the last issues

We are almost done, just a few more issues to fix.

To begin with, we are saving the user preferences but we are not really loading them. The UI is created in the createComponent() method so we just need to add the following code before the return to set the UI with the previously stored values.

val config = JiraComponent.getInstance(project)
txtUsername.text = config.username
passwordField.text = config.password

Next we are going to fix our problem with isModified(). Somehow we need to change that value from false to true when the user modifies any of the inputs in our settings. A really simple way to that is by implementing DocumentListener. This interface provides us with 3 methods: changeUpdate, insertUpdate and removeUpdate.

The only thing we have to do in those methods is simply changing the value of modified to true and finally add the DocumentListener to our password and username fields.

override fun changedUpdate(e: DocumentEvent?) {
modified = true
}

override fun insertUpdate(e: DocumentEvent?) {
modified = true
}

override fun removeUpdate(e: DocumentEvent?) {
modified = true
}

The final class looks like this:

Step 5: Declaring the extension

Same as we did with our components we also have to declare our extension in the plugin.xml file.

<extensions defaultExtensionNs="com.intellij">
<defaultProjectTypeProvider type="Android"/>
<projectConfigurable
instance="settings.JiraSettings">
</projectConfigurable>
</extensions>

And that’s it, we are done! When you debug or install your plugin you will find your new settings screen by going to Preferences/Other Settings in Android Studio. You can also test them using different projects and each project should remember its own settings.

Our brand new settings screen

--

--

Senior Android Developer at DuckDuckGo. Speaker, Kotlin lover and I also fly planes. www.marcosholgado.com