IDEA Web渲染插件開發(一)— 使用JCEF


目前網上已經有了很多關於IDEA(IntelliJ平台)的插件開發教程了,本人覺得簡書上這位作者秋水畏寒 的關於插件開發的文章很不錯,在我進行插件開發的過程中指導了我很多。但是綜合下來看,在IDEA上加載網頁的插件的教程還不是特別多,官方文檔也不是那么的完整。本系列將會從這個角度出發,探討如何編寫加載Web頁面的插件。

前言

為什么會有想到開發處理Web網頁的插件呢?實際上因為在IDEA中,我們可以打開markdown文件,並且IDEA具有markdown實時渲染的能力:

因為之前,本人使用過JCEF進行開發。看到這個渲染,心里大概猜測,應該用了瀏覽器內核。打開任務管理器:

果然,熟悉的JCEF。然后進入JetBrains的官網,在插件開發的文檔中找到了:JCEF - Java Chromium Embedded Framework | IntelliJ Platform Plugin SDK (jetbrains.com)

那么,接下來我們從零開始,編寫一款屬於自己的插件,這款插件能夠加載Web頁面。

環境准備

  • JDK 11
  • Gradle
  • 良好的網絡環境

我們先創建一個IntelliJ Platform Plugin,名為:intellij-jcef-plugin

然后進行這個Gradle項目的配置工作,完成整個項目搭建。本項目會在最后提交到github供讀者下載。

代碼編寫

首先說明我們的目的,就是希望能夠類似於gradle、maven插件一樣,能夠在IDEA的側邊有一個顯示我們Web頁面的地方:

通過閱讀官方的文檔我們可以知道,我們需要編寫的是ToolWindow(Tool Windows | IntelliJ Platform Plugin SDK (jetbrains.com))這樣一個頁面窗體。

基礎ToolWindow開發

在開發之前,我們需要明確一點,盡管這一節的標題寫着"空白ToolWindow開發",似乎在暗示我們,接下來我們會開發一個所謂的ToolWindow的實現類。實際上,ToolWindow是插件框架本身提供的,我們只需要做的是創建UI組件(例如JPanel),然后調用ToolWindow實例通過相關的API幫我們把UI組件設置到ToolWindow內部,具體的步驟如下:

實現ToolWindowFactory

創建一個ToolWindowFactory的實現類,這里我們取名MyToolWindowFactory,然后重寫createToolWindowContent方法。

public class MyToolWindowFactory implements ToolWindowFactory {
    @Override
    public void createToolWindowContent(
            @NotNull Project project,
            @NotNull ToolWindow toolWindow) {
        // 此處方法將會在點擊ToolWindow的時候觸發
        // 獲取ContentManager
        ContentManager contentManager = toolWindow.getContentManager();
        Content labelContent =
                contentManager.getFactory() // 內容管理器獲取工廠類
                        .createContent( // 創建Content(組件類實例、顯示名稱、是否可以鎖定)
                                new JLabel("hello, world"),
                                "MyTab",
                                false
                        );
        // 利用ContentManager添加Content
        contentManager.addContent(labelContent);
    }
}

在重寫的createToolWindowContent方法中,插件框架會為我們傳入兩個對象:Project以及ToolWindow對象。其中,Project對象是當前項目的內容抽象,而ToolWindow這個對象就是插件框架本身內部構造的,抽象了我們需求所說的,點擊側邊欄時候彈出的頁面。

在該方法實現中,主要有以下步驟:

  1. 使用ContentFactory(ContentManager.getFactory()獲取)的createContentAPI創建Content對象。這個創建時候,需要swing組件對象(JPanel、JLabel等等)。
  2. 使用ContentManager的addContentAPI添加步驟1的Content對象。

注冊插件

接下來,我們將我們實現的MyToolWindowFactory通過plugin.xml進行注冊,alt+enter,IDEA幫助我們快速完成填寫xml配置到plugin.xml中:

進行上述操作后,IDEA自動為我們在plugin.xml文件的extensions節點中,添加了toolWindow節點的內容,但是我們還需要填寫必備的屬性id

<!-- plugin.xml文件 -->
    <extensions defaultextensionns="com.intellij">
        <!-- Add your extensions here -->
        <!-- id是必須的屬性,我們進行添加 -->
        <!-- anchor錨點非必須,但是為了像Gradle插件一樣默認顯示在右邊,我們設置為right -->
        <toolwindow id="myToolWindowFactory" anchor="right" factoryclass="com.compilemind.demo.ui.MyToolWindowFactory">
    </toolwindow></extensions>

解決調試環境問題

目前為止,我們實現了ToolWindowFactory以及將我們的實現類注冊到plugin.xml中。現在,我們先什么內容都不編寫,開始調試我們的插件:

不過開始調試后,會有很多的情況發生,這里我做了一些遇到的問題的總結。

Gradle亂碼

此時進行Debug調試,在我的機器上會出現亂碼:

解決方案為,在build.gradle中添加如下的語句:

tasks.withType(JavaCompile) {
    options.encoding = "UTF-8"
}

Gradle報錯不知道這樣的主機(Unknown host)

如果出現了類似於Unknown host 'xxxxx.cloudfront.net'. You may need to adjust the proxy settings in Gradle.這樣的報錯,一般是當前網絡的連通問題,導致無法下載cloudfront.net一些jar文件。此時掛代理是最好的辦法。

rumIde:Download JCEF

如果使用調試模式,intellij插件開發的Gradle插件會下載jcef的運行時,這個過程會比較漫長,目前解決辦法是使用好的網絡等待下載:

在本人機器上,第一次調試的時候主要就是遇到上面的三種情況。

驗證基礎ToolWindow

解決完上述的幾個問題之后,界面彈出了我們的調試下的社區版的IDEA(ideaIC),並且,查看Plugins頁簽,會發現我們編寫的插件已經被這個ideaIC安裝了:

我們使用這個IDEA創建一個簡單的空項目,然后可以看到右側有我們提供的ToolWindow:

可以看到,此時的ToolWindow中的內容顯示為我們上面設置的new JLabel("hello, world"),該ToolWindow上方有我們設置的"My Tab"標題。截至目前的代碼,包含在這個github上這個提交:

simple ToolWindow Content · w4ngzhen/intellij-jcef-plugin@bf2ca8e (github.com)

Web頁面ToolWindow開發

通過上面一些系列的環境搭建,以及ToolWindow開發練習,我們已經了解了如何開發一款用於IDEA側邊欄展示內容的插件。當然,我們一開始的需求是要在ToolWindow中展示網頁,並且也知道了,JetBrains已經將JCEF引入到了IntelliJ插件平台。接下來,我們使用JCef以及JBCef相關API創建一個用於展示Web的UI組件,再通過上述的方式,添加到ToolWindow。

創建MyWebToolWindowContent

package com.compilemind.demo.ui;

import com.intellij.ui.jcef.JBCefApp;
import com.intellij.ui.jcef.JBCefBrowser;

import javax.swing.*;
import java.awt.*;

public class MyWebToolWindowContent {

    private final JPanel content;

    /**
     * 構造函數
     */
    public MyWebToolWindowContent() {
        this.content = new JPanel(new BorderLayout());
        // 判斷所處的IDEA環境是否支持JCEF
        if (!JBCefApp.isSupported()) {
            this.content.add(new JLabel("當前環境不支持JCEF", SwingConstants.CENTER));
            return;
        }
        // 創建 JBCefBrowser
        JBCefBrowser jbCefBrowser = new JBCefBrowser();
        // 將 JBCefBrowser 的UI控件設置到Panel中
        this.content.add(jbCefBrowser.getComponent(), BorderLayout.CENTER);
        // 加載URL
        jbCefBrowser.loadURL("https://cnblogs.com/w4ngzhen");
    }

    /**
     * 返回創建的JPanel
     * @return JPanel
     */
    public JPanel getContent() {
        return content;
    }
}

修改MyToolWindowFactory

這里,我們將創建MyWebToolWindowContent實例,然后返回其Panel,按同樣的方式設置到ToolWindow中。

驗證Web渲染ToolWindow

上述代碼完成開發后,我們再次運行Debug模式,可以看到此時的界面顯示了相關的網頁:

附錄

本次代碼本人放在了Github上,地址為:w4ngzhen/intellij-jcef-plugin (github.com)

上面基礎ToolWindow開發以及web頁面ToolWindow開發兩節的內容,按如下提交對應:

基礎ToolWindow開發 :simple ToolWindow Content · w4ngzhen/intellij-jcef-plugin@bf2ca8e (github.com)

web頁面ToolWindow開發:web ToolWindow Content · w4ngzhen/intellij-jcef-plugin@45604d3 (github.com)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM