diff --git a/platform/diff-impl/intellij.platform.diff.impl.iml b/platform/diff-impl/intellij.platform.diff.impl.iml
index bb81c3207db3..ad6cd7573d70 100644
--- a/platform/diff-impl/intellij.platform.diff.impl.iml
+++ b/platform/diff-impl/intellij.platform.diff.impl.iml
@@ -16,7 +16,6 @@
-
diff --git a/platform/diff-impl/src/com/intellij/diff/tools/util/side/DiffContentPanel.java b/platform/diff-impl/src/com/intellij/diff/tools/util/side/DiffContentPanel.java
index b9a29658547a..6b5accef623a 100644
--- a/platform/diff-impl/src/com/intellij/diff/tools/util/side/DiffContentPanel.java
+++ b/platform/diff-impl/src/com/intellij/diff/tools/util/side/DiffContentPanel.java
@@ -21,13 +21,13 @@ import com.intellij.diff.util.DiffUtil;
import com.intellij.diff.util.InvisibleWrapper;
import com.intellij.ui.components.panels.Wrapper;
import com.intellij.util.containers.ContainerUtil;
-import net.miginfocom.layout.CC;
-import net.miginfocom.layout.LC;
-import net.miginfocom.swing.MigLayout;
+import com.intellij.util.ui.AbstractLayoutManager;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
+import java.awt.*;
+import java.util.Arrays;
import java.util.List;
class DiffContentPanel extends JPanel {
@@ -71,15 +71,11 @@ class DiffContentPanel extends JPanel {
@NotNull JComponent content,
@NotNull JComponent bottomBreadcrumbs) {
contentPanel.removeAll();
-
- MigLayout mgr = new MigLayout(new LC().flowY().fill().hideMode(3)
- .insets("0").gridGapY("0"));
- contentPanel.setLayout(mgr);
-
- contentPanel.add(title, new CC().growX().minWidth("0").gapY("0", String.valueOf(DiffUtil.TITLE_GAP)));
- contentPanel.add(topBreadcrumbs, new CC().growX().minWidth("0"));
- contentPanel.add(content, new CC().grow().push());
- contentPanel.add(bottomBreadcrumbs, new CC().growX().minWidth("0"));
+ contentPanel.setLayout(new DiffContentLayout(title, topBreadcrumbs, content, bottomBreadcrumbs));
+ contentPanel.add(title);
+ contentPanel.add(topBreadcrumbs);
+ contentPanel.add(content);
+ contentPanel.add(bottomBreadcrumbs);
}
public static void syncTitleHeights(@NotNull List panels) {
@@ -96,4 +92,69 @@ class DiffContentPanel extends JPanel {
initLayout(contentPanel, title, topBreadcrumb, contentPanel.myContent, contentPanel.myBottomBreadcrumbs);
}
}
+
+ private static class DiffContentLayout extends AbstractLayoutManager {
+ @NotNull private final JComponent myTitle;
+ @NotNull private final JComponent myTopBreadcrumbs;
+ @NotNull private final JComponent myContent;
+ @NotNull private final JComponent myBottomBreadcrumbs;
+
+ DiffContentLayout(@NotNull JComponent title,
+ @NotNull JComponent topBreadcrumbs,
+ @NotNull JComponent content,
+ @NotNull JComponent bottomBreadcrumbs) {
+ myTitle = title;
+ myTopBreadcrumbs = topBreadcrumbs;
+ myContent = content;
+ myBottomBreadcrumbs = bottomBreadcrumbs;
+ }
+
+ @Override
+ public Dimension preferredLayoutSize(Container parent) {
+ int totalWidth = 0;
+ int totalHeight = 0;
+
+ for (JComponent component : Arrays.asList(myTitle, myTopBreadcrumbs, myContent, myBottomBreadcrumbs)) {
+ Dimension size = getPreferredSize(component);
+
+ totalWidth = Math.max(size.width, totalWidth);
+ totalHeight += size.height;
+
+ if (component == myTitle && size.height != 0) {
+ totalHeight += DiffUtil.TITLE_GAP;
+ }
+ }
+
+ return new Dimension(totalWidth, totalHeight);
+ }
+
+ @Override
+ public void layoutContainer(@NotNull Container parent) {
+ int y = 0;
+
+ int width = parent.getWidth();
+ int totalHeight = parent.getHeight();
+
+ Dimension titleSize = getPreferredSize(myTitle);
+ Dimension topSize = getPreferredSize(myTopBreadcrumbs);
+ Dimension bottomSize = getPreferredSize(myBottomBreadcrumbs);
+ int bottomY = totalHeight - bottomSize.height;
+
+ myTitle.setBounds(0, y, width, titleSize.height);
+ y += titleSize.height;
+ if (titleSize.height != 0) y += DiffUtil.TITLE_GAP;
+
+ myTopBreadcrumbs.setBounds(0, y, width, topSize.height);
+ y += topSize.height;
+
+ myContent.setBounds(0, y, width, Math.max(0, bottomY - y));
+
+ myBottomBreadcrumbs.setBounds(0, bottomY, width, bottomSize.height);
+ }
+
+ @NotNull
+ private static Dimension getPreferredSize(@NotNull JComponent component) {
+ return component.isVisible() ? component.getPreferredSize() : new Dimension();
+ }
+ }
}
diff --git a/platform/diff-impl/src/com/intellij/diff/util/DiffUtil.java b/platform/diff-impl/src/com/intellij/diff/util/DiffUtil.java
index 0cabdc3cf5c7..3257599f5622 100644
--- a/platform/diff-impl/src/com/intellij/diff/util/DiffUtil.java
+++ b/platform/diff-impl/src/com/intellij/diff/util/DiffUtil.java
@@ -565,21 +565,20 @@ public final class DiffUtil {
private static JComponent createTitleWithNotifications(@Nullable DiffViewer viewer,
@Nullable JComponent title,
@NotNull DiffContent content) {
- List notifications = new ArrayList<>(createCustomNotifications(viewer, content));
+ List components = new ArrayList<>();
+ if (title != null) components.add(title);
+
+ components.addAll(createCustomNotifications(viewer, content));
if (content instanceof DocumentContent) {
Document document = ((DocumentContent)content).getDocument();
if (FileDocumentManager.getInstance().isPartialPreviewOfALargeFile(document)) {
- notifications.add(DiffNotifications.createNotification(DiffBundle.message("error.file.is.too.large.only.preview.is.loaded")));
+ components.add(DiffNotifications.createNotification(DiffBundle.message("error.file.is.too.large.only.preview.is.loaded")));
}
}
- if (notifications.isEmpty()) return title;
-
- JPanel panel = new JPanel(new BorderLayout(0, TITLE_GAP));
- if (title != null) panel.add(title, BorderLayout.NORTH);
- panel.add(createStackedComponents(notifications, TITLE_GAP), BorderLayout.SOUTH);
- return panel;
+ if (components.isEmpty()) return null;
+ return createStackedComponents(components, TITLE_GAP);
}
@Nullable
@@ -689,21 +688,18 @@ public final class DiffUtil {
if (!ContainerUtil.exists(components, Conditions.notNull())) return components;
List result = new ArrayList<>();
for (int i = 0; i < components.size(); i++) {
- result.add(new SyncHeightComponent(components, i));
+ JComponent component = components.get(i);
+ result.add(new SyncHeightComponent(components, component));
}
return result;
}
@NotNull
- public static JComponent createStackedComponents(@NotNull List extends JComponent> components, int gap) {
- JPanel panel = new JPanel();
- panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
-
- for (int i = 0; i < components.size(); i++) {
- if (i != 0) panel.add(Box.createVerticalStrut(JBUIScale.scale(gap)));
- panel.add(components.get(i));
+ public static JComponent createStackedComponents(@NotNull List extends JComponent> components, int vGap) {
+ JPanel panel = new JPanel(new VerticalStackLayout(vGap));
+ for (JComponent component : components) {
+ panel.add(component);
}
-
return panel;
}
diff --git a/platform/diff-impl/src/com/intellij/diff/util/SyncHeightComponent.java b/platform/diff-impl/src/com/intellij/diff/util/SyncHeightComponent.java
index 721dbaf78f94..0b47d6bdddd2 100644
--- a/platform/diff-impl/src/com/intellij/diff/util/SyncHeightComponent.java
+++ b/platform/diff-impl/src/com/intellij/diff/util/SyncHeightComponent.java
@@ -1,8 +1,9 @@
// Copyright 2000-2020 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.diff.util;
-import com.intellij.util.Function;
+import com.intellij.util.ui.AbstractLayoutManager;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
@@ -11,35 +12,11 @@ import java.util.List;
public class SyncHeightComponent extends JPanel {
@NotNull private final List extends JComponent> myComponents;
- SyncHeightComponent(@NotNull List extends JComponent> components, int index) {
- super(new BorderLayout());
- myComponents = components;
- JComponent delegate = components.get(index);
- if (delegate != null) add(delegate, BorderLayout.CENTER);
- }
+ SyncHeightComponent(@NotNull List extends JComponent> syncComponents, @Nullable JComponent component) {
+ super(new SyncHeightLayout(syncComponents, component));
+ myComponents = syncComponents;
- @Override
- public Dimension getMinimumSize() {
- Dimension size = super.getMinimumSize();
- size.height = getMaximumHeight(JComponent::getPreferredSize);
- return size;
- }
-
- @Override
- public Dimension getPreferredSize() {
- Dimension size = super.getPreferredSize();
- size.height = getMaximumHeight(JComponent::getPreferredSize);
- return size;
- }
-
- private int getMaximumHeight(@NotNull Function super JComponent, ? extends Dimension> getter) {
- int height = 0;
- for (JComponent component : myComponents) {
- if (component != null) {
- height = Math.max(height, getter.fun(component).height);
- }
- }
- return height;
+ if (component != null) add(component);
}
public void revalidateAll() {
@@ -47,4 +24,44 @@ public class SyncHeightComponent extends JPanel {
if (component != null) component.revalidate();
}
}
+
+ private static class SyncHeightLayout extends AbstractLayoutManager {
+ @NotNull private final List extends JComponent> mySyncComponents;
+ @Nullable private final JComponent myComponent;
+
+ SyncHeightLayout(@NotNull List extends JComponent> syncComponents, @Nullable JComponent component) {
+ mySyncComponents = syncComponents;
+ myComponent = component;
+ }
+
+ @Override
+ public Dimension preferredLayoutSize(Container parent) {
+ int totalHeight = 0;
+
+ for (JComponent component : mySyncComponents) {
+ Dimension size = getPreferredSize(component);
+ totalHeight = Math.max(size.height, totalHeight);
+ }
+
+ int width = getPreferredSize(myComponent).width;
+
+ return new Dimension(width, totalHeight);
+ }
+
+ @Override
+ public void layoutContainer(@NotNull Container parent) {
+ int width = parent.getWidth();
+ int height = parent.getHeight();
+
+ if (myComponent == null) return;
+
+ Dimension size = getPreferredSize(myComponent);
+ myComponent.setBounds(0, 0, width, Math.min(height, size.height));
+ }
+
+ @NotNull
+ private static Dimension getPreferredSize(@Nullable Component component) {
+ return component != null && component.isVisible() ? component.getPreferredSize() : new Dimension();
+ }
+ }
}
diff --git a/platform/diff-impl/src/com/intellij/diff/util/VerticalStackLayout.java b/platform/diff-impl/src/com/intellij/diff/util/VerticalStackLayout.java
new file mode 100644
index 000000000000..f814ab0d1c1a
--- /dev/null
+++ b/platform/diff-impl/src/com/intellij/diff/util/VerticalStackLayout.java
@@ -0,0 +1,52 @@
+// Copyright 2000-2021 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.diff.util;
+
+import com.intellij.util.ui.AbstractLayoutManager;
+import com.intellij.util.ui.JBUI;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import java.awt.*;
+
+class VerticalStackLayout extends AbstractLayoutManager {
+ private final int myVGap;
+
+ VerticalStackLayout(int vGap) {
+ myVGap = vGap;
+ }
+
+ @Override
+ public Dimension preferredLayoutSize(Container parent) {
+ int totalWidth = 0;
+ int totalHeight = 0;
+
+ for (Component component : parent.getComponents()) {
+ Dimension size = getPreferredSize(component);
+
+ totalWidth = Math.max(size.width, totalWidth);
+ if (size.height != 0 && totalHeight != 0) totalHeight += myVGap;
+ totalHeight += size.height;
+ }
+
+ return new Dimension(totalWidth, totalHeight);
+ }
+
+ @Override
+ public void layoutContainer(@NotNull Container parent) {
+ int width = parent.getWidth();
+
+ int y = 0;
+ for (Component component : parent.getComponents()) {
+ Dimension size = getPreferredSize(component);
+
+ component.setBounds(0, y, width, size.height);
+ if (size.height != 0) y += myVGap;
+ y += size.height;
+ }
+ }
+
+ @NotNull
+ private static Dimension getPreferredSize(@NotNull Component component) {
+ return component.isVisible() ? component.getPreferredSize() : new Dimension();
+ }
+}