2023年了,是時候該知道JetBrains在JDK中內置了一個Chromium了

語言: CN / TW / HK

theme: smartblue

開篇

對於 JetBrains ,大家肯定人人都知道。但是有沒有注意到,JetBrains 有它自己的 JDK 與 JRE 呢?這裏就有必要介紹下了。

它叫做 JetBrains Runtime (即 JetBrains 運行時,簡稱 JBR ),是一個運行時環境,用於在 Windows,Mac OS X 和Linux 上運行 IntelliJ 平台的各種產品。JetBrains Runtime 基於 OpenJDK 項目,並進行了一些修改。這些修改包括:抗鋸齒, Linux 上增強的字體渲染, HiDPI 支持,連字,一些官方版本中未提供的針對產品崩潰的修復程序以及其他小的增強功能。

不過 JetBrains Runtime 不是 OpenJDK 的認證版本。請自己承擔風險使用。

我們可通過 IDE 的 Help About 在彈出的對話框中看到 JetBrains Runtime 的版本:

png

png

什麼是 JCEF

既然本文講講 JetBrains 在 JDK 中內置了一個 Chromium ,那麼這裏就有必要説説 JCEF 了。

chromiumembedded / java-cef — Bitbucket

Java Chromium Embedded Framework (JCEF). A simple framework for embedding Chromium-based browsers in other applications using the Java programming language.

這是 JCEF 項目地址中的一段原話。簡單把它翻譯下:

Java Chromium 嵌入式框架(JCEF)。 一個簡單的框架,用於使用 Java 編程語言在其他應用程序中嵌入基於Chromium 的瀏覽器。

它的作用是什麼呢?就是字面意思。你可以在 Java Swing 桌面端開發中,在你的程序中嵌入基於 Chromium 的瀏覽器。這有點類似於 Electron ,相當於你在開發桌面端程序的時候,用 Java 做個殼,裏面直接跑 H5 頁面。

JetBrains 直接將此插件集成到了它自家的 JDK 中,在使用 JetBrains Runtime 時就無需手動引入 JCEF 以及編譯和配置 Native 庫了

為什麼要這麼做

很簡單,JetBrains 基本上所產品都是基於 Java Swing 開發的。比如 IDEA 、WebStorm 等等,都是使用 Java 開發的桌面端程序。

在 Web 技術火熱發展的現在, JetBrains 肯定也意識到了相比於 QT 、 WinForm 這些,再或是 Java 自身的桌面端開發技術 Swing 、 SWT 、 JavaFX , 直接藉助瀏覽器外殼,利用眾多流行的 Web UI 框架去做界面無疑是最快的,這可以讓我們有更多的時間去實現業務邏輯,而不用被那些該死的 UI 控件折磨。想一想,原先做個表格,一整套界面做完大半天過去了,現在,引入 Web 技術 一瞬間做出一個高大上的界面,效率不言而喻。

當然 JetBrains 並不是説要把自家產品全部推翻,像 VS Code 那樣使用 Web 技術去重構自家產品。其實 JetBrains 在 JDK 中內置一個 Chromium ,就是為了方便大家開發插件用的。

如何獲取

來看看我們如何獲取帶有 JCEF 的 JetBrains Runtime 吧!

這是 JetBrains Runtime 的 git 地址,我直接給 Releases 頁面,方便大家直接點進去下載。

Releases · JetBrains/JetBrainsRuntime (github.com)

Binaries for developers 這一欄中下載 JBR with JCEF ,文件名以 jbrsdk_jcef 開頭的,這個就是 JDK 了。

Binaries for launching IntelliJ IDEA 這一欄就是 JRE 了。同樣也是字面意思,用於啟動 IDEA ,不是面向於開發者的,當然就是 JRE 了。

png

簡單使用

將此 JDK 作為開發環境,我們簡單地調用它。

簡單起見我就直接用 eclipse 創建一個 Java SE 項目。畢竟作為老一輩的 Java 程序員,儘管我現在更多地是使用 IDEA ,但是拿 eclipse 做個小 demo 還是更方便的。

創建項目,並給項目配置為 JetBrains 的 JDK:

png

創建兩個文件,用於簡單實現一個瀏覽器界面。

png

Application.java

```java package jcef;

import jcef.ui.MainFrame;

public class Application {

public static void main(String[] args) {
    MainFrame.getIstance();
}

} ```

MainFrame.java

```java package jcef.ui;

import java.awt.Dimension; import java.awt.Toolkit; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent;

import javax.swing.JFrame;

import org.cef.CefApp; import org.cef.CefClient; import org.cef.browser.CefBrowser; import org.cef.browser.CefRendering;

import com.jetbrains.cef.JCefAppConfig; import java.awt.BorderLayout;

public class MainFrame extends JFrame {

private static final long serialVersionUID = 2541887783679247552L;

private static volatile MainFrame instance;

private String url = "https://map.baidu.com/";

private CefApp app = null;
private CefClient client = null;
private CefBrowser browser = null;

public MainFrame() {

    var args = JCefAppConfig.getInstance().getAppArgs();
    var settings = JCefAppConfig.getInstance().getCefSettings();
    settings.cache_path = System.getProperty("user.dir") + "/context";
    // 獲取CefApp實例
    CefApp.startup(args);
    app = CefApp.getInstance(args, settings);
    // 創建客户端實例
    client = app.createClient();
    // 創建瀏覽器實例
    browser = client.createBrowser(url, CefRendering.DEFAULT, true);

    this.getContentPane().setLayout(new BorderLayout(0, 0));
    this.getContentPane().add(browser.getUIComponent(), BorderLayout.CENTER);

    this.setTitle("JetBrains Runtime - JCEF");
    this.setSize(new Dimension(1280, 720));
    this.setMinimumSize(new Dimension(1150, 650));
    this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    this.setLocation((Toolkit.getDefaultToolkit().getScreenSize().width - this.getWidth()) / 2,
            (Toolkit.getDefaultToolkit().getScreenSize().height - this.getHeight()) / 2);
    this.setVisible(true);
    this.setResizable(true);
    this.addWindowListener(new WindowAdapter() {
        @Override
        public void windowClosing(WindowEvent e) {
            app.dispose();
            System.exit(0);
        }
    });

}

public static MainFrame getIstance() {
    if (instance == null) {
        synchronized (MainFrame.class) {
            if (instance == null) {
                instance = new MainFrame();
            }
        }
    }
    return instance;
}

} ```

可以看到,我在上述代碼中聲明瞭百度地圖的地址:

java private String url = "https://map.baidu.com/";

運行該項目,我們就可以看到如下界面:

png

你看,一個瀏覽器界面順利地通過 Java 顯示出來了。

我們換個地址再來看看:

java private String url = "https://cn.vuejs.org/";

png

同樣也能正確顯示頁面。

於是我用它寫了個瀏覽器

前段時間我用 JetBrains Runtime 簡單做了一個瀏覽器,它長這樣:

png

gif

分享給大家,有興趣可以在git上拉下來玩玩:

DLand-Team/java-browser: 使用Java開發的瀏覽器,基於Chromium (github.com)