We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
原文:Write an Android Studio Plugin Part 3: Settings 作者:Marcos Holgado 译者:却把清梅嗅 《编写AndroidStudio插件》系列是 IntelliJ IDEA 官方推荐的学习IDE插件开发的博客专栏,希望对有需要的读者有所帮助。
在本系列的第二部分中,我们学习了如何使用Component对数据进行持久化,以及通过这些数据,在用户更新我们的插件后展示更新了哪些新功能。在今天的文章中,我们将看到如何使用持久化的数据来创建设置页面。
Component
请记住,您可以在GitHub上找到本系列的所有代码,还可以在对应的分支上查看每篇文章的相关代码,本文的代码在Part3分支中。
GitHub
Part3
https://github.com/marcosholgado/plugin-medium
本文的目的是为我们的插件创建一个 设置页面,这将是我们迈向将JIRA搬运过来的第一步。我们的设置页面上只会有一个用户名和密码字段,我们的插件将使用该用户名和密码字段与Jira API进行交互。我们还希望能够为 每个项目 分别配不同的设置,从而允许用户根据项目使用不同的Jira帐户(这可能很有用)。
JIRA
Jira API
Jira
在本系列的第二部分中,我们已经了解了什么是Component,并且还了解了存在三种不同类型的Component。 因为我们希望能够根据我们的Android Studio的各Project进行不同的设置,因此显而易见的选择是创建一个新的Project Component。
Android Studio
Project
Project Component
我们基本上是在复制和粘贴我们先前创建的Component,但是删除了所有不必要的方法并添加了两个新字段。这些字段将是public的,因为我们将在插件的其它部分中使用它们。
public
另一处不同是这次我们实现ProjectComponent接口并实现AbstractProjectComponent方法,当然,它的构造方法中也有一个project参数。最后,我们有一个companion object,通过一个project参数,以获取我们的JiraComponent的实例。这将使我们能够从插件中其他位置访问存储的数据。新的JiraComponent看起来像这样:
ProjectComponent
AbstractProjectComponent
project
companion object
JiraComponent
@State(name = "JiraConfiguration", storages = [Storage(value = "jiraConfiguration.xml")]) class JiraComponent(project: Project? = null) : AbstractProjectComponent(project), Serializable, PersistentStateComponent<JiraComponent> { var username: String = "" var password: String = "" override fun getState(): JiraComponent? = this override fun loadState(state: JiraComponent) = XmlSerializerUtil.copyBean(state, this) companion object { fun getInstance(project: Project): JiraComponent = project.getComponent(JiraComponent::class.java) } }
如我们在上文所做的一样,我们还必须在plugin.xml文件中注册Component:
plugin.xml
<project-components> <!-- Add your project components here --> <component> <implementation-class> components.JiraComponent </implementation-class> </component> </project-components>
在针对我们的设置页面进行下一步之前,我们需要了解如何通过使用Java Swing在IntelliJ上创建UI。IntelliJ有许多可以使用的Swing组件,以保证插件UI与IDE中其它插件保持一致。 但不要被名字中带有Java给欺骗了,因为您仍可将代码转换为Kotlin。
Java Swing
IntelliJ
UI
Swing
IDE
Java
Kotlin
创建新GUI(图形用户界面)的一种方法是,只需右键单击并转到New,然后单击GUI Form。该操作将创建一个名为YourName.form的新文件,该文件将链接到另一个名为YourName.java的文件。相比于按照IntelliJ给的编辑器模式进行开发,我更喜欢用我自己的方式,给一个提示:
GUI
New
GUI Form
YourName.form
YourName.java
我将会使用 Eclipse !(欢呼声)
我知道你在想什么,但老实说,它真的很棒。由于一些原因,IntelliJ的编辑器确实很难用,我无法获得预期的效果,但是,如果你对IntelliJ感到满意,请继续使用它!
译者注:我也并不喜欢IDEA官方的编辑器,但也没有很大必要去使用Eclipse,因为使用Eclipse只是对UI预览而已。
IDEA
Eclipse
回到Eclipse,您可以从这里下载它。 我目前有Oxygen.3a版本,该版本有些旧,但是对于我们要做的并不重要。只需创建一个新项目,然后右键单击New,Other,然后选择JPanel:
Oxygen.3a
Other
JPanel
下图是我们的设置页预览:
接下来我们只需将创建好的源代码从Eclipse复制过来就行了,然后就可以关闭Eclipse了。
回到我们的插件,我们现在将创建一个名为settings的新包和一个名为JiraSettings的新类。 在该类中,我们将创建一个名为createComponent()的新方法,最后我们可以在该方法中粘贴从Eclipse复制的源代码。然后是时候将代码转换为Kotlin,您应该也可以自动将其成功转换为Kotlin。
settings
JiraSettings
createComponent()
完成所有这些操作后,您可能会遇到一些错误,因此请修复它们。
我们需要解决的第一件事是我们的createComponent()方法必须返回一个JComponent,具体原因接下来我们会说到。
JComponent
因为Eclipse假定我们已经在JPanel中,所以您可以看到很多add方法或似乎并不存在的方法,原因是因为我们不在JPanel中。为解决该问题,我们必须创建一个新的JPanel并给它一些边界(您可以从在Eclipse中创建的JPanel中获取值),并且由于JPanel是JComponent的子类,因此我们将在我们的方法中将其返回。
add
最后,我们只需要进行一些调整就可以编译整个程序,最终效果应该如下:
class JiraSettings { private val passwordField = JPasswordField() private val txtUsername = JTextField() fun createComponent(): JComponent { val mainPanel = JPanel() mainPanel.setBounds(0, 0, 452, 120) mainPanel.layout = null val lblUsername = JLabel("Username") lblUsername.setBounds(30, 25, 83, 16) mainPanel.add(lblUsername) val lblPassword = JLabel("Password") lblPassword.setBounds(30, 74, 83, 16) mainPanel.add(lblPassword) passwordField.setBounds(125, 69, 291, 26) mainPanel.add(passwordField) txtUsername.setBounds(125, 20, 291, 26) mainPanel.add(txtUsername) txtUsername.columns = 10 return mainPanel } }
在继续开发设置页面前,我们必须讨论extensions和extension points。它们将允许您的插件与其他插件或与IDE本身进行交互。
extensions
extension points
因为我们要将设置页面添加到Android Studio的Preferences中,所以我们真正要做的是扩展Android Studio的功能,因此我们必须声明一个extensions。
Preferences
为此,我们必须实现Configurable,同时还必须重写一些方法。
Configurable
override
boolean
modified
false
isModified()
apply
getDisplayName()
Apply
Modify
最终展示效果如下:
class JiraSettings(private val project: Project): Configurable { private val passwordField = JPasswordField() private val txtUsername = JTextField() private var modified = false override fun isModified(): Boolean = modified override fun getDisplayName(): String = "MyPlugin Jira" override fun apply() { val config = JiraComponent.getInstance(project) config.username = txtUsername.text config.password = String(passwordField.password) modified = false } override fun createComponent(): JComponent { val mainPanel = JPanel() mainPanel.setBounds(0, 0, 452, 120) mainPanel.layout = null val lblUsername = JLabel("Username") lblUsername.setBounds(30, 25, 83, 16) mainPanel.add(lblUsername) val lblPassword = JLabel("Password") lblPassword.setBounds(30, 74, 83, 16) mainPanel.add(lblPassword) passwordField.setBounds(125, 69, 291, 26) mainPanel.add(passwordField) txtUsername.setBounds(125, 20, 291, 26) mainPanel.add(txtUsername) txtUsername.columns = 10 return mainPanel } }
我们几乎完成了,只剩下最后几个问题。
首先,我们要保存用户的偏好设置,但目前我们还未对其加载。UI是在createComponent()方法中创建的,因此我们只需要在返回之前添加以下代码,即可使用先前存储的值设置UI:
val config = JiraComponent.getInstance(project) txtUsername.text = config.username passwordField.text = config.password
接下来,我们将使用isModified()解决问题。 当用户修改设置页中的任何值时,我们需要以某种方式将值从false更改为true。一种非常简单的方法是实现 DocumentListener,该接口为我们提供了3种方法: changeUpdate ,insertUpdate 和 removeUpdate。
true
在这些方法中,我们唯一要做的就是简单地将Modify的值更改为true,最后将DocumentListener添加到我们的密码和用户名字段中。
DocumentListener
override fun changedUpdate(e: DocumentEvent?) { modified = true } override fun insertUpdate(e: DocumentEvent?) { modified = true } override fun removeUpdate(e: DocumentEvent?) { modified = true }
最终实现如下:
class JiraSettings(private val project: Project): Configurable, DocumentListener { private val passwordField = JPasswordField() private val txtUsername = JTextField() private var modified = false override fun isModified(): Boolean = modified override fun getDisplayName(): String = "MyPlugin Jira" override fun apply() { val config = JiraComponent.getInstance(project) config.username = txtUsername.text config.password = String(passwordField.password) modified = false } override fun changedUpdate(e: DocumentEvent?) { modified = true } override fun insertUpdate(e: DocumentEvent?) { modified = true } override fun removeUpdate(e: DocumentEvent?) { modified = true } override fun createComponent(): JComponent { val mainPanel = JPanel() mainPanel.setBounds(0, 0, 452, 120) mainPanel.layout = null val lblUsername = JLabel("Username") lblUsername.setBounds(30, 25, 83, 16) mainPanel.add(lblUsername) val lblPassword = JLabel("Password") lblPassword.setBounds(30, 74, 83, 16) mainPanel.add(lblPassword) passwordField.setBounds(125, 69, 291, 26) mainPanel.add(passwordField) txtUsername.setBounds(125, 20, 291, 26) mainPanel.add(txtUsername) txtUsername.columns = 10 val config = JiraComponent.getInstance(project) txtUsername.text = config.username passwordField.text = config.password passwordField.document?.addDocumentListener(this) txtUsername.document?.addDocumentListener(this) return mainPanel } }
与Component相同,我们还必须在plugin.xml文件中声明extension。
extension
<extensions defaultExtensionNs="com.intellij"> <defaultProjectTypeProvider type="Android"/> <projectConfigurable instance="settings.JiraSettings"> </projectConfigurable> </extensions>
大功告成!调试或安装插件时,您可以转到Android Studio中的Preferences/Other Settings,找到新的设置页。您也可以使用不同的Project进行测试,并且每个Project都会记住自身的设置。
Preferences/Other Settings
这就是第三部分的全部内容。在下一篇文章中,我们将看到如何使用这些设置来创建新的Action,将Jira相关功能迁移过来。同时,如果您有任何疑问,请访问Twitter或发表评论。
Action
Hello,我是 却把清梅嗅 ,如果您觉得文章对您有价值,欢迎 ❤️,也欢迎关注我的 博客 或者 GitHub。
如果您觉得文章还差了那么点东西,也请通过 关注 督促我写出更好的文章——万一哪天我进步了呢?
The text was updated successfully, but these errors were encountered:
No branches or pull requests
[译] 编写AndroidStudio插件(三):设置页
在本系列的第二部分中,我们学习了如何使用
Component
对数据进行持久化,以及通过这些数据,在用户更新我们的插件后展示更新了哪些新功能。在今天的文章中,我们将看到如何使用持久化的数据来创建设置页面。请记住,您可以在
GitHub
上找到本系列的所有代码,还可以在对应的分支上查看每篇文章的相关代码,本文的代码在Part3
分支中。我们要做什么?
本文的目的是为我们的插件创建一个 设置页面,这将是我们迈向将
JIRA
搬运过来的第一步。我们的设置页面上只会有一个用户名和密码字段,我们的插件将使用该用户名和密码字段与Jira API
进行交互。我们还希望能够为 每个项目 分别配不同的设置,从而允许用户根据项目使用不同的Jira
帐户(这可能很有用)。第一步:新建一个Project级别的Component
在本系列的第二部分中,我们已经了解了什么是
Component
,并且还了解了存在三种不同类型的Component
。 因为我们希望能够根据我们的Android Studio
的各Project
进行不同的设置,因此显而易见的选择是创建一个新的Project Component
。我们基本上是在复制和粘贴我们先前创建的
Component
,但是删除了所有不必要的方法并添加了两个新字段。这些字段将是public
的,因为我们将在插件的其它部分中使用它们。另一处不同是这次我们实现
ProjectComponent
接口并实现AbstractProjectComponent
方法,当然,它的构造方法中也有一个project
参数。最后,我们有一个companion object
,通过一个project
参数,以获取我们的JiraComponent
的实例。这将使我们能够从插件中其他位置访问存储的数据。新的JiraComponent
看起来像这样:如我们在上文所做的一样,我们还必须在
plugin.xml
文件中注册Component
:第二步:UI
在针对我们的设置页面进行下一步之前,我们需要了解如何通过使用
Java Swing
在IntelliJ
上创建UI
。IntelliJ
有许多可以使用的Swing
组件,以保证插件UI
与IDE
中其它插件保持一致。 但不要被名字中带有Java
给欺骗了,因为您仍可将代码转换为Kotlin
。创建新
GUI
(图形用户界面)的一种方法是,只需右键单击并转到New
,然后单击GUI Form
。该操作将创建一个名为YourName.form
的新文件,该文件将链接到另一个名为YourName.java
的文件。相比于按照IntelliJ
给的编辑器模式进行开发,我更喜欢用我自己的方式,给一个提示:我将会使用 Eclipse !(欢呼声)
我知道你在想什么,但老实说,它真的很棒。由于一些原因,
IntelliJ
的编辑器确实很难用,我无法获得预期的效果,但是,如果你对IntelliJ
感到满意,请继续使用它!回到
Eclipse
,您可以从这里下载它。 我目前有Oxygen.3a
版本,该版本有些旧,但是对于我们要做的并不重要。只需创建一个新项目,然后右键单击New
,Other
,然后选择JPanel
:下图是我们的设置页预览:
接下来我们只需将创建好的源代码从
Eclipse
复制过来就行了,然后就可以关闭Eclipse
了。回到我们的插件,我们现在将创建一个名为
settings
的新包和一个名为JiraSettings
的新类。 在该类中,我们将创建一个名为createComponent()
的新方法,最后我们可以在该方法中粘贴从Eclipse
复制的源代码。然后是时候将代码转换为Kotlin
,您应该也可以自动将其成功转换为Kotlin
。完成所有这些操作后,您可能会遇到一些错误,因此请修复它们。
我们需要解决的第一件事是我们的
createComponent()
方法必须返回一个JComponent
,具体原因接下来我们会说到。因为
Eclipse
假定我们已经在JPanel
中,所以您可以看到很多add
方法或似乎并不存在的方法,原因是因为我们不在JPanel
中。为解决该问题,我们必须创建一个新的JPanel
并给它一些边界(您可以从在Eclipse
中创建的JPanel
中获取值),并且由于JPanel
是JComponent
的子类,因此我们将在我们的方法中将其返回。最后,我们只需要进行一些调整就可以编译整个程序,最终效果应该如下:
第三步:Extensions 和 Extension points
在继续开发设置页面前,我们必须讨论
extensions
和extension points
。它们将允许您的插件与其他插件或与IDE
本身进行交互。IDE
的功能,则必须声明一个或多个extensions
。extension points
。因为我们要将设置页面添加到
Android Studio
的Preferences
中,所以我们真正要做的是扩展Android Studio
的功能,因此我们必须声明一个extensions
。为此,我们必须实现
Configurable
,同时还必须重写一些方法。createComponent()
方法,因此我们只需添加override
关键字就可以了。boolean
的modified
,其默认值为false
,并作为isModified()
的返回值。我们稍后会再讲到这一点,目前它代表了设置页面apply
按钮是否被启用。getDisplayName()
的返回值用于展示设置页的名字。apply
方法中,我们需要编写将在用户单击Apply
时执行的代码。很简单,我们为用户所在的Project
获取JiraComponent
的实例,然后将UI
中的值保存到Component
中。最后,我们将Modify
设置为false
,届时我们要禁用Apply
按钮。最终展示效果如下:
第四步:解决最后的问题
我们几乎完成了,只剩下最后几个问题。
首先,我们要保存用户的偏好设置,但目前我们还未对其加载。
UI
是在createComponent()
方法中创建的,因此我们只需要在返回之前添加以下代码,即可使用先前存储的值设置UI
:接下来,我们将使用
isModified()
解决问题。 当用户修改设置页中的任何值时,我们需要以某种方式将值从false
更改为true
。一种非常简单的方法是实现 DocumentListener,该接口为我们提供了3种方法: changeUpdate ,insertUpdate 和 removeUpdate。在这些方法中,我们唯一要做的就是简单地将
Modify
的值更改为true
,最后将DocumentListener
添加到我们的密码和用户名字段中。最终实现如下:
第五步:声明 extension
与
Component
相同,我们还必须在plugin.xml
文件中声明extension
。大功告成!调试或安装插件时,您可以转到
Android Studio
中的Preferences/Other Settings
,找到新的设置页。您也可以使用不同的Project
进行测试,并且每个Project
都会记住自身的设置。这就是第三部分的全部内容。在下一篇文章中,我们将看到如何使用这些设置来创建新的
Action
,将Jira
相关功能迁移过来。同时,如果您有任何疑问,请访问Twitter或发表评论。《编写AndroidStudio插件》译文系列
关于译者
Hello,我是 却把清梅嗅 ,如果您觉得文章对您有价值,欢迎 ❤️,也欢迎关注我的 博客 或者 GitHub。
如果您觉得文章还差了那么点东西,也请通过 关注 督促我写出更好的文章——万一哪天我进步了呢?
The text was updated successfully, but these errors were encountered: