mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
extract JavaFxHtml panel into platform
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.ui.javafx;
|
||||
|
||||
import com.intellij.util.FieldAccessor;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import com.sun.javafx.embed.EmbeddedSceneInterface;
|
||||
import com.sun.javafx.tk.TKScene;
|
||||
import javafx.application.Platform;
|
||||
import javafx.embed.swing.JFXPanel;
|
||||
import javafx.scene.Scene;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
public class JFXPanelWrapper extends JFXPanel {
|
||||
private static final FieldAccessor<JFXPanel, Integer> myScaleFactorAccessor = new FieldAccessor<>(JFXPanel.class, "scaleFactor");
|
||||
|
||||
public JFXPanelWrapper() {
|
||||
Platform.setImplicitExit(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* This override fixes the situation of using multiple JFXPanels
|
||||
* with jbtabs/splitters when some of them are not showing.
|
||||
* On getMinimumSize there is no layout manager nor peer so
|
||||
* the result could be #size() which is incorrect.
|
||||
* @return zero size
|
||||
*/
|
||||
@Override
|
||||
public Dimension getMinimumSize() {
|
||||
return new Dimension(0, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addNotify() {
|
||||
super.addNotify();
|
||||
if (UIUtil.isJreHiDPIEnabled()) {
|
||||
// JFXPanel is scaled asynchronously after first repaint, what may lead
|
||||
// to showing unscaled content. To work it around, set "scaleFactor" ahead.
|
||||
int scale = Math.round(JBUI.sysScale(this));
|
||||
myScaleFactorAccessor.set(this, scale);
|
||||
Scene scene = getScene();
|
||||
// If scene is null then it will be set later and super.setEmbeddedScene(..) will init its scale properly,
|
||||
// otherwise explicitly set scene scale to match JFXPanel.scaleFactor.
|
||||
if (scene != null) {
|
||||
TKScene tks = scene.impl_getPeer();
|
||||
if (tks instanceof EmbeddedSceneInterface) {
|
||||
((EmbeddedSceneInterface)tks).setPixelScaleFactor(scale);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.ui.javafx;
|
||||
|
||||
import com.intellij.ide.IdeEventQueue;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.ui.JBColor;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
import com.sun.javafx.application.PlatformImpl;
|
||||
import javafx.application.Platform;
|
||||
import javafx.embed.swing.JFXPanel;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.web.WebEngine;
|
||||
import javafx.scene.web.WebView;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class JavaFxHtmlPanel implements Disposable {
|
||||
@NotNull
|
||||
private final JPanel myPanelWrapper;
|
||||
@NotNull
|
||||
private final List<Runnable> myInitActions = new ArrayList<>();
|
||||
@Nullable
|
||||
private JFXPanel myPanel;
|
||||
@Nullable protected WebView myWebView;
|
||||
|
||||
public JavaFxHtmlPanel() {
|
||||
myPanelWrapper = new JPanel(new BorderLayout());
|
||||
myPanelWrapper.setBackground(JBColor.background());
|
||||
|
||||
ApplicationManager.getApplication().invokeLater(() -> runFX(() -> PlatformImpl.startup(() -> {
|
||||
myWebView = new WebView();
|
||||
myWebView.setContextMenuEnabled(false);
|
||||
myWebView.setZoom(JBUI.scale(1.f));
|
||||
|
||||
final WebEngine engine = myWebView.getEngine();
|
||||
registerListeners(engine);
|
||||
|
||||
final Scene scene = new Scene(myWebView);
|
||||
|
||||
ApplicationManager.getApplication().invokeLater(() -> runFX(() -> {
|
||||
myPanel = new JFXPanelWrapper();
|
||||
|
||||
Platform.runLater(() -> myPanel.setScene(scene));
|
||||
|
||||
setHtml("");
|
||||
for (Runnable action : myInitActions) {
|
||||
Platform.runLater(action);
|
||||
}
|
||||
myInitActions.clear();
|
||||
|
||||
myPanelWrapper.add(myPanel, BorderLayout.CENTER);
|
||||
myPanelWrapper.repaint();
|
||||
}));
|
||||
})));
|
||||
}
|
||||
|
||||
protected void registerListeners(@NotNull WebEngine engine) {
|
||||
}
|
||||
|
||||
private static void runFX(@NotNull Runnable r) {
|
||||
IdeEventQueue.unsafeNonblockingExecute(r);
|
||||
}
|
||||
|
||||
protected void runInPlatformWhenAvailable(@NotNull Runnable runnable) {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
if (myPanel == null) {
|
||||
myInitActions.add(runnable);
|
||||
}
|
||||
else {
|
||||
Platform.runLater(runnable);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JComponent getComponent() {
|
||||
return myPanelWrapper;
|
||||
}
|
||||
|
||||
public void setHtml(@NotNull String html) {
|
||||
final String htmlToRender = prepareHtml(html);
|
||||
runInPlatformWhenAvailable(() -> getWebViewGuaranteed().getEngine().loadContent(htmlToRender));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected String prepareHtml(@NotNull String html) {
|
||||
return html;
|
||||
}
|
||||
|
||||
public void render() {
|
||||
runInPlatformWhenAvailable(() -> {
|
||||
getWebViewGuaranteed().getEngine().reload();
|
||||
ApplicationManager.getApplication().invokeLater(myPanelWrapper::repaint);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected WebView getWebViewGuaranteed() {
|
||||
if (myWebView == null) {
|
||||
throw new IllegalStateException("WebView should be initialized by now. Check the caller thread");
|
||||
}
|
||||
return myWebView;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user