diff --git a/python/ipnb/src/org/jetbrains/plugins/ipnb/IpnbJfxUtils.java b/python/ipnb/src/org/jetbrains/plugins/ipnb/IpnbJfxUtils.java index 7cd2e2d3aed5..6d878b525e39 100644 --- a/python/ipnb/src/org/jetbrains/plugins/ipnb/IpnbJfxUtils.java +++ b/python/ipnb/src/org/jetbrains/plugins/ipnb/IpnbJfxUtils.java @@ -17,11 +17,10 @@ import javafx.application.Platform; import javafx.concurrent.Worker; import javafx.embed.swing.JFXPanel; import javafx.scene.Scene; -import javafx.scene.layout.BorderPane; import javafx.scene.web.WebEngine; import javafx.scene.web.WebView; import org.jetbrains.annotations.NotNull; -import org.jetbrains.plugins.ipnb.editor.IpnbEditorUtil; +import org.jetbrains.plugins.ipnb.editor.panels.IpnbFilePanel; import org.markdown4j.*; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -68,7 +67,7 @@ public class IpnbJfxUtils { private static final String ourPostfix = ""; private static URL ourStyleUrl; - public static JComponent createHtmlPanel(@NotNull final String source, int width) { + public static JComponent createHtmlPanel(@NotNull final String source, int width, IpnbFilePanel parent) { final JFXPanel javafxPanel = new JFXPanel() { @Override @@ -78,8 +77,6 @@ public class IpnbJfxUtils { parent.dispatchEvent(parentEvent); } }; - javafxPanel.setBackground(IpnbEditorUtil.getBackground()); - Platform.runLater(() -> { final WebView webView = new WebView(); webView.setContextMenuEnabled(false); @@ -90,16 +87,20 @@ public class IpnbJfxUtils { final boolean hasMath = source.contains("$"); if (hasMath) { - engine.setOnStatusChanged(event -> adjustHeight(webView, javafxPanel, source)); + engine.setOnStatusChanged(event -> { + final String data = event.getData(); + if (data != null && data.isEmpty()) { + adjustHeight(webView, javafxPanel, source, parent); + } + }); } else { engine.getLoadWorker().stateProperty().addListener((observable, oldValue, newValue) -> { if (newValue == Worker.State.SUCCEEDED) { - adjustHeight(webView, javafxPanel, source); + adjustHeight(webView, javafxPanel, source, parent); } }); } - final BorderPane pane = new BorderPane(webView); final String prefix; if (hasMath) { prefix = String.format(ourMathJaxPrefix, width - 500, EditorColorsManager.getInstance().getGlobalScheme().getEditorFontSize(), @@ -111,7 +112,7 @@ public class IpnbJfxUtils { final String content = prefix + convertToHtml(source) + ourPostfix; engine.loadContent(content); - final Scene scene = new Scene(pane, 0, 0); + final Scene scene = new Scene(webView, 0, 0); javafxPanel.setScene(scene); updateLaf(LafManager.getInstance().getCurrentLookAndFeel() instanceof DarculaLookAndFeelInfo, @@ -231,7 +232,7 @@ public class IpnbJfxUtils { } } - private static void adjustHeight(final WebView webView, final JFXPanel javafxPanel, String source) { + private static void adjustHeight(final WebView webView, final JFXPanel javafxPanel, String source, IpnbFilePanel parent) { final WebEngine engine = webView.getEngine(); final Document document = engine.getDocument(); if (document != null) { @@ -272,13 +273,13 @@ public class IpnbJfxUtils { source = source.substring(source.indexOf("$$") + 2); } - int finalHeight = height + count * EditorColorsManager.getInstance().getGlobalScheme().getEditorFontSize(); - int finalWidth = width; + final Dimension size = new Dimension( + width, height + count * EditorColorsManager.getInstance().getGlobalScheme().getEditorFontSize()); UIUtil.invokeLaterIfNeeded(() -> { - final Dimension size = new Dimension(finalWidth, finalHeight); javafxPanel.setPreferredSize(size); javafxPanel.setMinimumSize(size); - javafxPanel.revalidate(); + javafxPanel.invalidate(); + parent.revalidateAndRepaint(); }); } } diff --git a/python/ipnb/src/org/jetbrains/plugins/ipnb/IpnbUtils.java b/python/ipnb/src/org/jetbrains/plugins/ipnb/IpnbUtils.java index 396664b79be0..5134f75ce16e 100644 --- a/python/ipnb/src/org/jetbrains/plugins/ipnb/IpnbUtils.java +++ b/python/ipnb/src/org/jetbrains/plugins/ipnb/IpnbUtils.java @@ -10,6 +10,7 @@ import javafx.application.Platform; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.ipnb.editor.IpnbEditorUtil; +import org.jetbrains.plugins.ipnb.editor.panels.IpnbFilePanel; import javax.swing.*; import java.awt.*; @@ -23,8 +24,8 @@ public class IpnbUtils { private static final Logger LOG = Logger.getInstance(IpnbUtils.class); private static int hasFx = 0; - public static JComponent createLatexPane(@NotNull final String source, int width) { - final JComponent panel = createHtmlPanel(source, width); + public static JComponent createLatexPane(@NotNull final String source, int width, IpnbFilePanel parent) { + final JComponent panel = createHtmlPanel(source, width, parent); panel.addMouseListener(new MouseAdapter() { @Override @@ -52,9 +53,9 @@ public class IpnbUtils { return hasFx == 1; } - public static JComponent createHtmlPanel(@NotNull final String source, int width) { + public static JComponent createHtmlPanel(@NotNull final String source, int width, IpnbFilePanel parent) { if (hasFx()) { - return IpnbJfxUtils.createHtmlPanel(source, width); + return IpnbJfxUtils.createHtmlPanel(source, width, parent); } return createNonJfxPanel(source); } diff --git a/python/ipnb/src/org/jetbrains/plugins/ipnb/editor/IpnbFileEditor.java b/python/ipnb/src/org/jetbrains/plugins/ipnb/editor/IpnbFileEditor.java index 983d46401005..7a03e919db28 100644 --- a/python/ipnb/src/org/jetbrains/plugins/ipnb/editor/IpnbFileEditor.java +++ b/python/ipnb/src/org/jetbrains/plugins/ipnb/editor/IpnbFileEditor.java @@ -15,6 +15,7 @@ import com.intellij.openapi.util.UserDataHolderBase; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.JBColor; import com.intellij.ui.ScrollPaneFactory; +import com.intellij.ui.components.JBLoadingPanel; import icons.PythonIcons; import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.ipnb.editor.actions.*; @@ -43,7 +44,7 @@ public class IpnbFileEditor extends UserDataHolderBase implements FileEditor { private final String myName; - private final JComponent myEditorPanel; + private final JBLoadingPanel myEditorPanel; private final IpnbFilePanel myIpnbFilePanel; private final Document myDocument; @@ -78,7 +79,8 @@ public class IpnbFileEditor extends UserDataHolderBase implements FileEditor { myName = vFile.getName(); - myEditorPanel = new JPanel(new BorderLayout()); + myEditorPanel = new JBLoadingPanel(new BorderLayout(), this); + myEditorPanel.startLoading(); myEditorPanel.setBackground(IpnbEditorUtil.getBackground()); myIpnbFilePanel = createIpnbEditorPanel(project, vFile); @@ -92,6 +94,10 @@ public class IpnbFileEditor extends UserDataHolderBase implements FileEditor { registerHeadingActions(); } + public void loaded() { + myEditorPanel.stopLoading(); + } + public Document getDocument() { return myDocument; } diff --git a/python/ipnb/src/org/jetbrains/plugins/ipnb/editor/panels/IpnbFilePanel.java b/python/ipnb/src/org/jetbrains/plugins/ipnb/editor/panels/IpnbFilePanel.java index c3cf662a2e68..325150413f68 100644 --- a/python/ipnb/src/org/jetbrains/plugins/ipnb/editor/panels/IpnbFilePanel.java +++ b/python/ipnb/src/org/jetbrains/plugins/ipnb/editor/panels/IpnbFilePanel.java @@ -26,6 +26,8 @@ import com.intellij.util.Alarm; import com.intellij.util.PlatformUtils; import com.intellij.util.messages.MessageBusConnection; import com.intellij.util.ui.UIUtil; +import com.intellij.util.ui.update.MergingUpdateQueue; +import com.intellij.util.ui.update.Update; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.ipnb.IpnbUtils; @@ -51,6 +53,8 @@ import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; +import static com.intellij.util.ui.update.Update.HIGH_PRIORITY; + public class IpnbFilePanel extends JPanel implements Scrollable, DataProvider, Disposable { private static final Logger LOG = Logger.getInstance(IpnbFilePanel.class); private final DocumentListener myDocumentListener; @@ -69,10 +73,13 @@ public class IpnbFilePanel extends JPanel implements Scrollable, DataProvider, D private int myInitialSelection = 0; private boolean mySynchronize; private static final String ourHelpID = "IPython_Notebook_Support"; + private MergingUpdateQueue myQueue; public IpnbFilePanel(@NotNull final Project project, @NotNull final IpnbFileEditor parent, @NotNull final VirtualFile vFile, @NotNull final IpnbFileEditor.CellSelectionListener listener) { super(new VerticalFlowLayout(VerticalFlowLayout.TOP, 100, 5, true, false)); + myQueue = new MergingUpdateQueue("Jupyter", 100, true, this, this, + null, true); myProject = project; myParent = parent; myVirtualFile = vFile; @@ -102,7 +109,11 @@ public class IpnbFilePanel extends JPanel implements Scrollable, DataProvider, D }); setFocusable(true); }, 10, ModalityState.stateForComponent(this)); - + alarm.addRequest(() -> { + revalidate(); + repaint(); + myParent.loaded(); + }, 100); UIUtil.requestFocus(this); myBusConnection = ApplicationManager.getApplication().getMessageBus().connect(); myBusConnection.subscribe(ProjectEx.ProjectSaved.TOPIC, @@ -700,8 +711,13 @@ public class IpnbFilePanel extends JPanel implements Scrollable, DataProvider, D } public void revalidateAndRepaint() { - revalidate(); - repaint(); + myQueue.queue(new Update("Jupyter.Repaint", HIGH_PRIORITY) { + @Override + public void run() { + revalidate(); + repaint(); + } + }); } @Nullable diff --git a/python/ipnb/src/org/jetbrains/plugins/ipnb/editor/panels/IpnbMarkdownPanel.java b/python/ipnb/src/org/jetbrains/plugins/ipnb/editor/panels/IpnbMarkdownPanel.java index c462a6a2b24b..115bd95461b5 100644 --- a/python/ipnb/src/org/jetbrains/plugins/ipnb/editor/panels/IpnbMarkdownPanel.java +++ b/python/ipnb/src/org/jetbrains/plugins/ipnb/editor/panels/IpnbMarkdownPanel.java @@ -24,7 +24,7 @@ public class IpnbMarkdownPanel extends IpnbEditablePanel { @Override protected JComponent createViewPanel() { final int width = myParent.getWidth(); - return IpnbUtils.createLatexPane(StringUtil.join(myCell.getHtmls(), ""), width); + return IpnbUtils.createLatexPane(StringUtil.join(myCell.getHtmls(), ""), width, myParent); } } diff --git a/python/ipnb/src/org/jetbrains/plugins/ipnb/editor/panels/code/IpnbLatexPanel.java b/python/ipnb/src/org/jetbrains/plugins/ipnb/editor/panels/code/IpnbLatexPanel.java index ddecc70018c2..cca08303b575 100644 --- a/python/ipnb/src/org/jetbrains/plugins/ipnb/editor/panels/code/IpnbLatexPanel.java +++ b/python/ipnb/src/org/jetbrains/plugins/ipnb/editor/panels/code/IpnbLatexPanel.java @@ -23,6 +23,6 @@ public class IpnbLatexPanel extends IpnbCodeOutputPanel { @Override protected JComponent createViewPanel() { final int width = myParent.getWidth(); - return IpnbUtils.createLatexPane(StringUtil.join(myCell.getLatex(), ""), width); + return IpnbUtils.createLatexPane(StringUtil.join(myCell.getLatex(), ""), width, myParent); } }