preface

Recently, MY work is relatively idle. I am thinking about something by myself. On a whim, I want to make an IDEA plug-in for fun, maybe I can sell it for money.

Version Tool Description

  • JDK1.8
  • IDEA2020.1
  • The plug-in project is built on Gradle.
  • Knowledge Background: Swing

To what end?

This example implements an Idea plug-in, pops up a form Dialog, and then clicks the button to get the input content in the form, and then prints the content on the top of the form. Follow the public number Ape Tech column to GET more postures.

Finished drawing display:

Project initialization

Create a new Gradle project and modify its build.gradle file:

Plugins {id 'Java' id 'org.jetbrains. Intellij 'version '0.4.14'} group 'org.example' version SourceCompatibility = 1.8 // Restrict the JDK version number to 8, < span style = "box-sizing: border-box! Important; word-wrap: break-word! Important;" 'junit', name: 'junit', version: '4.12' intellij {} / / See https://github.com/JetBrains/gradle-intellij-plugin/ / / here refers to the plug-in package with a idea what version of the dependent package / / For example, if your plugin implementation source code contains dependencies or classes that do not exist in 2019.3, Version "2019.3"} patchPluginXml {// See Figure 14 changeNotes version 1.0. Version 1.0: SinceBuild =191 (sinceBuild=191) sinceBuild=191 (sinceBuild=191) sinceBuild=191 (sinceBuild=191) sinceBuild=191 (sinceBuild=191) An incompatible error will be thrown if the version is lower than this one. https://intellij-support.jetbrains.com/hc/en-us/community/posts/360003338799-Build-compatible-plugin sinceBuild "191" }Copy the code

Then the right hand bar of Idea gradle will have intellij option:

RunIde is used to debug plugins. Running it will again launch an Idea, which will automatically install the plugin package you are currently defining for debugging.

The new plugin. XML

This file is very important. It can specify where the plug-in you define should appear in IDEA, specify specific processing logic, and define plug-in names, child names, and so on. Pay attention to the public number ape technical column, reply to interview treasure book, free access to back-end bull interview information.

This file is located under mate-INF:

The configuration is as follows:

<idea-plugin>
    <! -- The id of the plugin. Do not duplicate it with other plugins. This id is globally unique and as complex as possible.
    <id>plugin.test</id>
    <! -- Plugin name -->
    <name>PluginTest</name>
    <vendor email="[email protected]" url="http://www.bilibili.com">The name of your company</vendor>

    <! -- The description of the plugin, which supports HTML, is shown in Figure 14-->
    <description><! [CDATA[Plugin Test<br> Said is just a test (low  ̄ (エ) -vice  ̄) < br > < a href = "https://www.bilibili.com" > you guess which website is this? < / a > < em > v1.0 > < / em >]]</description>
    
    <extensions defaultExtensionNs="com.intellij">
        <! -- Add your extensions here -->
    </extensions>

    <! SinceBuild (sinceBuild, build.gradle) sinceBuild (sinceBuild, build.gradle)
    <idea-version since-build="191"/>

    <actions>
        <! -- The following group is a group, the group needs to have a unique ID identification, text is used to control the text presented when the group appears in IDEA, description is the description, will not be displayed, simply describe the group is ok -->
        <group id="PluginTest" text="Plug-in Test Group" description="Plug-in Test Description">
            <! --add-to-group controls adding the group to IDEA, group-id is used to describe where to add it, MainMenu means adding it to the MainMenu bar above IDEA, anchor means order, last means last, so the following configuration can be described as: Add the plugin to the last bit of the main menu bar above IDEA -->
            <add-to-group group-id="MainMenu" anchor="last"/>
            <! -- This is used to specify a group trigger action, also requires an ID, custom; Class is the logic class used to handle this action. The specific plugin logic is written to the corresponding action class. Text is used to control the text, and description is used to describe.
            <action id="Plugin.Test.Action"
                    class="plugin.test.FromAction"
                    text="Form tests" description="Form test Description"/>
        </group>
    </actions>
</idea-plugin>
Copy the code

Then define AnAction class, call it FormAction, inherit AnAction, and implement its abstract actionPerformed method:

public class FromAction extends AnAction {
    @Override
    public void actionPerformed(@NotNull AnActionEvent e) {
        //TODO puts the plugin logic here}}Copy the code

Start the

Now double-click runIde to bring up another IDEA interface with the plugin installed, and you can see the results for debugging. RunIde also supports debug mode, but at runtime right click to select:

See the interface running effect of debugging IDEA:

Define the Action

1. Define the session box class

After the previous three steps, the basic style of the plug-in has been shown, but clicking on the action under “Form Test” doesn’t help because it doesn’t have any meaningful implementation in its binding FormAction class. Now to achieve the initial goal, click “Form test”, a custom form dialog box will pop up, then click the button, get the form content and print it in the dialog box.

Dialog needs to define a subclass of DialogWrapper abstract class from IDEA. This subclass is the custom Dialog implementation. All style definitions and function trigger are put into this subclass.

public class FormTestDialog extends DialogWrapper {
 
    private String projectName; // If you need to get the project name, put it in as an attribute of the class
 
    // DialogWrapper doesn't have a default no-argument constructor, so you need to override the constructor, which provides a lot of overloaded constructors,
    // The project object can be used to obtain some properties of the project opened in the current IDEA.
    // Project name, project path, etc
    public FormTestDialog(@Nullable Project project) {
        super(project);
        setTitle("Form test ~~"); // Set the dialog box title
        this.projectName = project.getName();
    }
 
    // Override the following method to return a custom Swing style that will be displayed at the top of the session box
    @Override
    protected JComponent createNorthPanel(a) {
        return null;
    }
 
    // Override the following method to return a custom Swing style that is displayed at the bottom of the session box
    @Override
    protected JComponent createSouthPanel(a) {
        return null;
    }
 
    // Override the following method to return a custom Swing style that is displayed in the center of the session box
    @Override
    protected JComponent createCenterPanel(a) {
        return null; }}Copy the code

2. Compare the dialog box module with the class element

Take an actual session box as an example. The elements in the session box controlled by the above methods are as follows:

3. Redefine the session box method

For the purposes of this article, the custom form body can be placed in the createCenterPanel, then the form header can be placed in the createNorthPanel, and the submit button can be placed in the createSouthPanel.

public class FormTestDialog extends DialogWrapper {
 
    private String projectName;
     
    // Swing style classes defined in 4.3.2
    private FormTestSwing formTestSwing = new FormTestSwing();
 
    public FormTestDialog(@Nullable Project project) {
        super(true);
        setTitle("Form test ~~"); // Set the dialog box title
        this.projectName = project.getName(); // Get the name of the current project
        init(); // Trigger the init method, otherwise Swing styles will not be displayed in the session box
    }
 
    @Override
    protected JComponent createNorthPanel(a) {
        return formTestSwing.initNorth(); // Return the Swing style at the north location of the session box
    }
 
    // Special note: There is no need to display SouthPanel to override to return NULL, otherwise IDEA will display the default "Cancel" and "OK" buttons
    @Override
    protected JComponent createSouthPanel(a) {
        return formTestSwing.initSouth();
    }
 
    @Override
    protected JComponent createCenterPanel(a) {
        // Define the topic of the form and place it in the center of the IDEA dialog box
        returnformTestSwing.initCenter(); }}Copy the code

4. Customize Swing styles

Here are the classes to place swing styles:

public class FormTestSwing {
 
    private JPanel north = new JPanel();
 
    private JPanel center = new JPanel();
 
    private JPanel south = new JPanel();
 
    // Make the form component a class property so that the button at the bottom can get the component content
    private JLabel r1 = new JLabel("Output:");
    private JLabel r2 = new JLabel("NULL");
 
    private JLabel name = new JLabel("Name:");
    private JTextField nameContent = new JTextField();
 
    private JLabel age = new JLabel("Age:");
    private JTextField ageContent = new JTextField();
 
    public JPanel initNorth(a) {
 
        // Define the title section of the form and place it at the top of the IDEA session box
 
        JLabel title = new JLabel("Form title");
        title.setFont(new Font(Microsoft Yahei, Font.PLAIN, 26)); // Font style
        title.setHorizontalAlignment(SwingConstants.CENTER); // Horizontal center
        title.setVerticalAlignment(SwingConstants.CENTER); // Vertical center
        north.add(title);
 
        return north;
    }
 
    public JPanel initCenter(a) {
 
        // Define the body of the form and place it in the center of the IDEA dialog box
 
        // A simple table layout with 3 rows and 2 columns
        center.setLayout(new GridLayout(3.2));
 
        //row1: Print the result here after the button event is triggered
        r1.setForeground(new Color(255.47.93)); // Set the font color
        center.add(r1);
        r2.setForeground(new Color(139.181.20)); // Set the font color
        center.add(r2);
 
        //row2: name + text box
        center.add(name);
        center.add(nameContent);
 
        Row3: Age + text box
        center.add(age);
        center.add(ageContent);
 
        return center;
    }
 
    public JPanel initSouth(a) {
 
        // Define the submit button for the form and place it at the bottom of the IDEA session box
 
        JButton submit = new JButton("Submit");
        submit.setHorizontalAlignment(SwingConstants.CENTER); // Horizontal center
        submit.setVerticalAlignment(SwingConstants.CENTER); // Vertical center
        south.add(submit);
 
        returnsouth; }}Copy the code

Now click on the runIde button, again, in the debug IDE click on “Form Test”, and the following form box will pop up:

It is recommended that you do not add any Swing styles unless there are special circumstances that require a custom Swing style, so that the custom Swing interface ADAPTS to the theme of the IDEA. For example, in Figure 7, the debug IDE theme is set to Darcula, and the custom form ADAPTS to a black background:

5. Event binding

With the styling defined, now bind an event to the “submit” button. Now rewrite the formTestSwing.initSouth method:

public JPanel initSouth(a) {
 
    // Define the submit button for the form and place it at the bottom of the IDEA session box
 
    JButton submit = new JButton("Submit");
    submit.setHorizontalAlignment(SwingConstants.CENTER); // Horizontal center
    submit.setVerticalAlignment(SwingConstants.CENTER); // Vertical center
    south.add(submit);
 
    // Button event binding
    submit.addActionListener(e -> {
        // Get name and age
        String name = nameContent.getText();
        String age = ageContent.getText();
        // Refresh the r2 TAB, replacing name and age
        r2.setText(String.format("name:%s, age:%s", name, age));
    });
 
    return south;
}
Copy the code

Now click the “Submit” button again to output the form contents:

6. Plugin binding class: FormAction

As mentioned earlier, this class is the entry to the plugin. In combination with the form Dialog defined above, let’s see how it looks:

public class FromAction extends AnAction {
    @Override
    public void actionPerformed(@NotNull AnActionEvent e) {
        FormTestDialog formTestDialog = new FormTestDialog(e.getProject());
        formTestDialog.setResizable(true); // Whether to allow the user to drag and drop the size of your form box, I define true to allowformTestDialog.show(); }}Copy the code

7. Packaging and installation of plug-ins

By the end of step 4, you can only view the effect in the debug IDE. If a plug-in needs to be installed in the actual IDEA after development, you need to use the package option to package your plug-in. Click the following option to build the plug-in:

After the build is complete, check the Build directory and the zip package can be installed directly into your IDEA:

Then select the plugins option under the Preferences of IDEA, and the following box will pop up. Select the ZIP package and install it according to the instructions in the picture:

After the installation is complete, restart IDEA:

Refer to the following figure for the source of configuration in the plug-in project corresponding to each display module:

After the restart, the same menu bar as in debugging IDEA appears. After selected, it runs successfully:

conclusion

At this point, the development, debugging, and installation of a plug-in is complete, and it is theoretically possible to achieve some practical functionality through this simple example, as it completely demonstrates the entire process from data input to data retrieval.

Because I need to write a code generator in my work, I want to provide the service as an IDEA plug-in, so I make a record here, so as to avoid using it from scratch again in the future.

You have to have some swing background, and when I was developing code generators, the swing background was so bad that layout took a lot of time.

More details please look at the IDEA of the official document: plugins.jetbrains.com/docs/intell…

Reference documentation

  • www.jetbrains.org/intellij/sd…

  • www.jetbrains.org/intellij/sd…

  • www.jetbrains.org/intellij/sd…

  • Intellij-support.jetbrains.com/hc/en-us/co…