diff --git a/platform/lang-impl/src/com/intellij/refactoring/introduce/inplace/AbstractInplaceVariableIntroducer.java b/platform/lang-impl/src/com/intellij/refactoring/introduce/inplace/AbstractInplaceVariableIntroducer.java index 7aa610497b73..1d8bc3b3652a 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/introduce/inplace/AbstractInplaceVariableIntroducer.java +++ b/platform/lang-impl/src/com/intellij/refactoring/introduce/inplace/AbstractInplaceVariableIntroducer.java @@ -127,15 +127,7 @@ public abstract class AbstractInplaceVariableIntroducer ex final JComponent component = getComponent(); if (component == null) return; if (ApplicationManager.getApplication().isHeadlessEnvironment()) return; - final BalloonBuilder balloonBuilder = JBPopupFactory.getInstance().createBalloonBuilder(component); - balloonBuilder.setFadeoutTime(0) - .setFillColor(UIManager.getColor("Panel.background")) - .setAnimationCycle(100) - .setHideOnClickOutside(false) - .setHideOnKeyOutside(false) - .setHideOnAction(false) - .setCloseButtonEnabled(true); - + final BalloonBuilder balloonBuilder = JBPopupFactory.getInstance().createDialogBalloonBuilder(component, null); final RelativePoint target = JBPopupFactory.getInstance().guessBestPopupLocation(myEditor); final Point screenPoint = target.getScreenPoint(); myBalloon = balloonBuilder.createBalloon(); diff --git a/platform/platform-api/src/com/intellij/openapi/ui/popup/BalloonBuilder.java b/platform/platform-api/src/com/intellij/openapi/ui/popup/BalloonBuilder.java index 06cef34d2c57..45674e3c1224 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/popup/BalloonBuilder.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/popup/BalloonBuilder.java @@ -81,4 +81,10 @@ public interface BalloonBuilder { @NotNull BalloonBuilder setTitle(@Nullable String title); + + @NotNull + BalloonBuilder setContentInsets(Insets insets); + + @NotNull + BalloonBuilder setShadow(boolean shadow); } \ No newline at end of file diff --git a/platform/platform-api/src/com/intellij/openapi/ui/popup/JBPopupFactory.java b/platform/platform-api/src/com/intellij/openapi/ui/popup/JBPopupFactory.java index 36563d57e6cb..158360e16389 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/popup/JBPopupFactory.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/popup/JBPopupFactory.java @@ -256,6 +256,7 @@ public abstract class JBPopupFactory { public abstract BalloonBuilder createBalloonBuilder(@NotNull JComponent content); + public abstract BalloonBuilder createDialogBalloonBuilder(@NotNull JComponent content, String title); public abstract BalloonBuilder createHtmlTextBalloonBuilder(@NotNull String htmlContent, @Nullable Icon icon, Color fillColor, @Nullable HyperlinkListener listener); diff --git a/platform/platform-api/src/com/intellij/ui/components/JBLabel.java b/platform/platform-api/src/com/intellij/ui/components/JBLabel.java index 2e011f67c195..dae48251e83e 100644 --- a/platform/platform-api/src/com/intellij/ui/components/JBLabel.java +++ b/platform/platform-api/src/com/intellij/ui/components/JBLabel.java @@ -15,23 +15,19 @@ */ package com.intellij.ui.components; -import com.intellij.openapi.util.SystemInfo; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; -import java.awt.*; public class JBLabel extends JLabel { - private Style myStyle = Style.REGULAR; - - public enum Style {REGULAR, SMALL} + private UIUtil.Style myStyle = UIUtil.Style.REGULAR; public JBLabel() { } - public JBLabel(@NotNull Style style) { + public JBLabel(@NotNull UIUtil.Style style) { setStyle(style); } @@ -43,7 +39,7 @@ public class JBLabel extends JLabel { super(text); } - public JBLabel(@NotNull String text, @NotNull Style style) { + public JBLabel(@NotNull String text, @NotNull UIUtil.Style style) { super(text); setStyle(style); } @@ -60,22 +56,12 @@ public class JBLabel extends JLabel { super(text, icon, horizontalAlignment); } - public void setStyle(@NotNull Style style) { + public void setStyle(@NotNull UIUtil.Style style) { myStyle = style; - - if (SystemInfo.isMac) { - putClientProperty("JComponent.sizeVariant", style == Style.REGULAR ? "regular" : "small"); - } - else { - setFont(UIUtil.getFont(style == Style.SMALL ? UIUtil.FontSize.SMALL : UIUtil.FontSize.NORMAL, getFont())); - } - Container p = getParent(); - if (p != null) { - SwingUtilities.updateComponentTreeUI(p); - } + UIUtil.applyStyle(style, this); } - public Style getStyle() { + public UIUtil.Style getStyle() { return myStyle; } } diff --git a/platform/platform-impl/platform-impl.iml b/platform/platform-impl/platform-impl.iml index 0f93972c1b30..df4448cb35f4 100644 --- a/platform/platform-impl/platform-impl.iml +++ b/platform/platform-impl/platform-impl.iml @@ -29,6 +29,7 @@ + diff --git a/platform/platform-impl/src/com/intellij/openapi/ui/impl/ShadowBorderPainter.java b/platform/platform-impl/src/com/intellij/openapi/ui/impl/ShadowBorderPainter.java index 128835529b9a..8741f56dcfff 100644 --- a/platform/platform-impl/src/com/intellij/openapi/ui/impl/ShadowBorderPainter.java +++ b/platform/platform-impl/src/com/intellij/openapi/ui/impl/ShadowBorderPainter.java @@ -16,6 +16,8 @@ package com.intellij.openapi.ui.impl; import com.intellij.openapi.util.IconLoader; +import org.jdesktop.swingx.graphics.GraphicsUtilities; +import org.jdesktop.swingx.graphics.ShadowRenderer; import javax.swing.*; import java.awt.*; @@ -104,4 +106,56 @@ public class ShadowBorderPainter { public static BufferedImage createPopupShadow(final JComponent c, final int width, final int height) { return createShadow(c, width, height, true); } + + public static Shadow createShadow(Image source, int x, int y, boolean paintSource, int shadowSize) { + int size = shadowSize; + final float w = source.getWidth(null); + final float h = source.getHeight(null); + float ratio = w /h; + float deltaX = size; + float deltaY = size / ratio; + + final Image scaled = source.getScaledInstance((int)(w + deltaX), (int)(h + deltaY), Image.SCALE_SMOOTH); + + final BufferedImage s = + GraphicsUtilities.createCompatibleTranslucentImage(scaled.getWidth(null), scaled.getHeight(null)); + final Graphics2D graphics = (Graphics2D)s.getGraphics(); + graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + graphics.drawImage(scaled, 0, 0, null); + + final BufferedImage shadow = new ShadowRenderer(size, .25f, Color.black).createShadow(s); + if (paintSource) { + final Graphics imgG = shadow.getGraphics(); + final double d = size * 0.5; + imgG.drawImage(source, (int)(size + d), (int)(size + d / ratio), null); + } + + return new Shadow(shadow, x - size - 5, y - size + 2); + } + + + public static class Shadow { + int x; + int y; + Image image; + + public Shadow(Image image, int x, int y) { + this.x = x; + this.y = y; + this.image = image; + } + + public int getX() { + return x; + } + + public int getY() { + return y; + } + + public Image getImage() { + return image; + } + } + } diff --git a/platform/platform-impl/src/com/intellij/ui/BalloonImpl.java b/platform/platform-impl/src/com/intellij/ui/BalloonImpl.java index eb80961119fa..b6328677a111 100644 --- a/platform/platform-impl/src/com/intellij/ui/BalloonImpl.java +++ b/platform/platform-impl/src/com/intellij/ui/BalloonImpl.java @@ -25,6 +25,7 @@ import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.ex.AnActionListener; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.ui.MessageType; +import com.intellij.openapi.ui.impl.ShadowBorderPainter; import com.intellij.openapi.ui.popup.Balloon; import com.intellij.openapi.ui.popup.JBPopupListener; import com.intellij.openapi.ui.popup.LightweightWindow; @@ -77,7 +78,7 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi private final Color myBorderColor; private final Color myFillColor; - private final Insets myContainerInsets = new Insets(2, 2, 2, 2); + private final Insets myContainerInsets; private boolean myLastMoveWasInsideBalloon; @@ -153,6 +154,7 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi private JLabel myTitleLabel; private boolean myAnimationEnabled = true; + private boolean myShadow = false; public boolean isInsideBalloon(MouseEvent me) { return isInside(new RelativePoint(me)); @@ -206,7 +208,9 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi int positioChangeXShfit, int positionChangeYShift, boolean dialogMode, - String title) { + String title, + Insets contentInsets, + boolean shadow) { myBorderColor = borderColor; myFillColor = fillColor; myContent = content; @@ -246,8 +250,21 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi }; } + myShadow = shadow; + myContainerInsets = contentInsets; + myFadeoutTime = fadeoutTime; myAnimationCycle = animationCycle; + + if (myDialogMode) { + new AwtVisitor(myContent) { + @Override + public boolean visit(Component component) { + UIUtil.applyStyle(UIUtil.Style.SMALL, component); + return false; + } + }; + } } public void show(final RelativePoint target, final Balloon.Position position) { @@ -407,7 +424,7 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi myComp.validate(); - Rectangle rec = myComp.getBounds(); + Rectangle rec = myComp.getContentBounds(); if (myShowPointer && !myPosition.isOkToHavePointer(myTargetPoint, rec, getPointerLength(myPosition), getPointerWidth(myPosition), getArc(), getNormalInset())) { myShowPointer = false; @@ -492,6 +509,8 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi myComp.clear(); myComp.myAlpha = 0f; + final int borderSize = getShadowBorderSize(); + myComp.setBorder(new EmptyBorder(borderSize, borderSize, borderSize, borderSize)); myLayeredPane.add(myComp, JLayeredPane.POPUP_LAYER); myPosition.updateBounds(this); @@ -511,6 +530,10 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi } } + private int getShadowBorderSize() { + return myShadow && Registry.is("ide.balloon.shadowEnabled") ? Registry.intValue("ide.balloon.shadow.size") : 0; + } + public void show(JLayeredPane pane) { show(pane, null); } @@ -583,23 +606,35 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi int getArc() { - return 3; + return myDialogMode ? 6 : 3; } int getPointerWidth(AbstractPosition position) { - return position.isTopBottomPointer() ? 14 : 11; + if (myDialogMode) { + return position.isTopBottomPointer() ? 24 : 17; + } else { + return position.isTopBottomPointer() ? 14 : 11; + } } public static int getNormalInset() { return 3; } - static int getPointerLength(AbstractPosition position) { - return position.isTopBottomPointer() ? 10 : 8; + int getPointerLength(AbstractPosition position) { + return getPointerLength(position, myDialogMode); } - public static int getPointerLength(Position position) { - return getPointerLength((getAbstractPositionFor(position))); + static int getPointerLength(AbstractPosition position, boolean dialogMode) { + if (dialogMode) { + return position.isTopBottomPointer() ? 16 : 14; + } else { + return position.isTopBottomPointer() ? 10 : 8; + } + } + + public static int getPointerLength(Position position, boolean dialogMode) { + return getPointerLength(getAbstractPositionFor(position), dialogMode); } @@ -683,13 +718,13 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi abstract int getChangeShift(AbstractPosition original, int xShift, int yShift); public void updateBounds(final BalloonImpl balloon) { - balloon.myComp._setBounds(getUpdatedBounds(balloon.myLayeredPane.getSize(), - balloon.myForcedBounds, - balloon.myComp.getPreferredSize(), - balloon.myShowPointer, - balloon.myTargetPoint, - balloon.myContainerInsets, - balloon.myCalloutshift)); + final Rectangle bounds = + getUpdatedBounds(balloon.myLayeredPane.getSize(), balloon.myForcedBounds, balloon.myComp.getPreferredSize(), balloon.myShowPointer, + balloon.myTargetPoint, balloon.myContainerInsets, balloon.myCalloutshift); + + final Point point = getShiftedPoint(bounds.getLocation(), -balloon.getShadowBorderSize()); + bounds.setLocation(point); + balloon.myComp._setBounds(bounds); } public Rectangle getUpdatedBounds(Dimension layeredPaneSize, @@ -718,6 +753,7 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi final GraphicsConfig cfg = new GraphicsConfig(g); cfg.setAntialiasing(true); + Shape shape; if (balloon.myShowPointer) { shape = getPointingShape(bounds, g, pointTarget, balloon); @@ -733,7 +769,8 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi if (balloon.myTitleLabel != null) { Rectangle titleBounds = balloon.myTitleLabel.getBounds(); - Insets inset = getTitleInsets(balloon.getNormalInset() - 1, getPointerLength(this) + 50); + final int shadow = balloon.getShadowBorderSize(); + Insets inset = getTitleInsets(balloon.getNormalInset() - 1 + shadow, balloon.getPointerLength(this) + 50 + shadow); titleBounds.x -= inset.left + 1; titleBounds.width += (inset.left + inset.right + 50); @@ -891,7 +928,7 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi @Override public Point getShiftedPoint(Point targetPoint, int shift) { - return new Point(targetPoint.x, targetPoint.y + shift); + return new Point(targetPoint.x, targetPoint.y - shift); } @Override @@ -1120,6 +1157,7 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi private final BalloonImpl myBalloon; private final JComponent myContent; + private ShadowBorderPainter.Shadow myShadow; private MyComponent(JComponent content, BalloonImpl balloon, EmptyBorder shapeBorder) { setOpaque(false); @@ -1147,6 +1185,16 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi myCloseRec = new CloseButton(); } + public Rectangle getContentBounds() { + final Rectangle bounds = super.getBounds(); + final int shadow = myBalloon.getShadowBorderSize(); + bounds.x += shadow; + bounds.width -= shadow * 2; + bounds.y += shadow; + bounds.height -= shadow * 2; + return bounds; + } + public void clear() { myImage = null; myAlpha = -1; @@ -1188,13 +1236,20 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi final Graphics2D g2d = (Graphics2D)g; - final Point pointTarget = SwingUtilities.convertPoint(myLayeredPane, myBalloon.myTargetPoint, this); + Point pointTarget = SwingUtilities.convertPoint(myLayeredPane, myBalloon.myTargetPoint, this); Rectangle shapeBounds = myContent.getBounds(); + final int shadowSize = myBalloon.getShadowBorderSize(); + if (shadowSize > 0) { + if (myShadow == null) { + initComponentImage(pointTarget, shapeBounds); + myShadow = ShadowBorderPainter.createShadow(myImage, 0, 0, false, shadowSize / 2); + } + } + if (myImage == null && myAlpha != -1) { - myImage = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB); - myBalloon.myPosition.paintComponent(myBalloon, shapeBounds, (Graphics2D)myImage.getGraphics(), pointTarget, this); + initComponentImage(pointTarget, shapeBounds); } if (myImage != null && myAlpha != -1) { @@ -1203,10 +1258,20 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi g2d.drawImage(myImage, 0, 0, null); } else { + if (myShadow != null) { + g.drawImage(myShadow.getImage(), myShadow.getX(), myShadow.getY(), null); + } myBalloon.myPosition.paintComponent(myBalloon, shapeBounds, (Graphics2D)g, pointTarget, this); } } + private void initComponentImage(Point pointTarget, Rectangle shapeBounds) { + if (myImage != null) return; + + myImage = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB); + myBalloon.myPosition.paintComponent(myBalloon, shapeBounds, (Graphics2D)myImage.getGraphics(), pointTarget, this); + } + @Override public void removeNotify() { @@ -1245,6 +1310,8 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi int iconHeight = myBalloon.myCloseButton.getIconHeight(); Rectangle r = new Rectangle(lpBounds.x + lpBounds.width - iconWidth + (int)(iconWidth * 0.3), lpBounds.y - (int)(iconHeight * 0.3), iconWidth, iconHeight); + r.y += getShadowBorderSize(); + r.x -= getShadowBorderSize(); myCloseRec.setBounds(r); } @@ -1376,7 +1443,8 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi //pane.setBorder(new LineBorder(Color.blue)); - balloon.set(new BalloonImpl(new JLabel("FUCK"), Color.black, MessageType.ERROR.getPopupBackground(), true, true, true, true, true, 0, true, null, false, 500, 5, 0, 0, false, "This is the title")); + balloon.set(new BalloonImpl(new JLabel("FUCK"), Color.black, MessageType.ERROR.getPopupBackground(), true, true, true, true, true, 0, true, null, false, 500, 5, 0, 0, false, "This is the title", + new Insets(2, 2, 2, 2), true)); balloon.get().setShowPointer(true); if (e.isShiftDown()) { diff --git a/platform/platform-impl/src/com/intellij/ui/LightweightHint.java b/platform/platform-impl/src/com/intellij/ui/LightweightHint.java index cf9826a05007..e4fa89d19036 100644 --- a/platform/platform-impl/src/com/intellij/ui/LightweightHint.java +++ b/platform/platform-impl/src/com/intellij/ui/LightweightHint.java @@ -228,7 +228,7 @@ public class LightweightHint extends UserDataHolderBase implements Hint { Dimension size = myComponent.getPreferredSize(); Balloon.Position position = myHintHint.getPreferredPosition(); - int shift = BalloonImpl.getPointerLength(position); + int shift = BalloonImpl.getPointerLength(position, false); switch (position) { case below: actualPoint.y += shift; @@ -260,7 +260,7 @@ public class LightweightHint extends UserDataHolderBase implements Hint { Point target = desiredLocation.getPointOn(pane).getPoint(); Balloon.Position pos = hintHint.getPreferredPosition(); - int pointer = BalloonImpl.getPointerLength(pos) + BalloonImpl.getNormalInset(); + int pointer = BalloonImpl.getPointerLength(pos, false) + BalloonImpl.getNormalInset(); if (pos == Balloon.Position.above || pos == Balloon.Position.below) { boolean heightFit = target.y - size.height - pointer > 0 || target.y + size.height + pointer < paneSize.height; return heightFit && size.width + pointer < paneSize.width; diff --git a/platform/platform-impl/src/com/intellij/ui/popup/BalloonPopupBuilderImpl.java b/platform/platform-impl/src/com/intellij/ui/popup/BalloonPopupBuilderImpl.java index 9d4e620eb73e..1ddaf04b7e5e 100644 --- a/platform/platform-impl/src/com/intellij/ui/popup/BalloonPopupBuilderImpl.java +++ b/platform/platform-impl/src/com/intellij/ui/popup/BalloonPopupBuilderImpl.java @@ -50,6 +50,8 @@ public class BalloonPopupBuilderImpl implements BalloonBuilder { private boolean myHideOnAction = true; private boolean myDialogMode; private String myTitle; + private Insets myContentInsets = new Insets(2, 2, 2, 2); + private boolean myShadow = false; public BalloonPopupBuilderImpl(@NotNull final JComponent content) { myContent = content; @@ -146,7 +148,7 @@ public class BalloonPopupBuilderImpl implements BalloonBuilder { @NotNull public Balloon createBalloon() { return new BalloonImpl(myContent, myBorder, myFill, myHideOnMouseOutside, myHideOnKeyOutside, myHideOnAction, myShowCalllout, myCloseButtonEnabled, myFadeoutTime, myHideOnFrameResize, myClickHandler, myCloseOnClick, myAnimationCycle, - myCalloutShift, myPositionChangeXShift, myPositionChangeYShift, myDialogMode, myTitle); + myCalloutShift, myPositionChangeXShift, myPositionChangeYShift, myDialogMode, myTitle, myContentInsets, myShadow); } @NotNull @@ -175,4 +177,18 @@ public class BalloonPopupBuilderImpl implements BalloonBuilder { myTitle = title; return this; } + + @NotNull + @Override + public BalloonBuilder setContentInsets(Insets insets) { + myContentInsets = insets; + return this; + } + + @NotNull + @Override + public BalloonBuilder setShadow(boolean shadow) { + myShadow = shadow; + return this; + } } diff --git a/platform/platform-impl/src/com/intellij/ui/popup/PopupFactoryImpl.java b/platform/platform-impl/src/com/intellij/ui/popup/PopupFactoryImpl.java index 701feb2e7132..0cb304ff689b 100644 --- a/platform/platform-impl/src/com/intellij/ui/popup/PopupFactoryImpl.java +++ b/platform/platform-impl/src/com/intellij/ui/popup/PopupFactoryImpl.java @@ -746,6 +746,27 @@ public class PopupFactoryImpl extends JBPopupFactory { return new BalloonPopupBuilderImpl(content); } + @Override + public BalloonBuilder createDialogBalloonBuilder(@NotNull JComponent content, String title) { + final BalloonPopupBuilderImpl builder = new BalloonPopupBuilderImpl(content); + final Color bg = UIManager.getColor("Panel.background"); + final Color borderOriginal = Color.darkGray; + final Color border = new Color(borderOriginal.getRed(), borderOriginal.getGreen(), borderOriginal.getBlue(), 75); + builder + .setDialogMode(true) + .setTitle(title) + .setAnimationCycle(200) + .setFillColor(bg) + .setBorderColor(border) + .setHideOnClickOutside(false) + .setHideOnKeyOutside(false) + .setHideOnAction(false) + .setCloseButtonEnabled(true) + .setShadow(true); + + return builder; + } + public BalloonBuilder createHtmlTextBalloonBuilder(@NotNull final String htmlContent, @Nullable final Icon icon, final Color fillColor, @Nullable final HyperlinkListener listener) { diff --git a/platform/platform-resources-en/src/misc/registry.properties b/platform/platform-resources-en/src/misc/registry.properties index 230cc2e7acc3..f96e9464299d 100644 --- a/platform/platform-resources-en/src/misc/registry.properties +++ b/platform/platform-resources-en/src/misc/registry.properties @@ -79,6 +79,9 @@ ide.tooltip.reshowDelay=500 ide.tooltip.dismissDelay=4000 ide.tooltip.initialReshowDelay=300 ide.tooltip.autoDismissDeadZone=300 +ide.balloon.shadowEnabled=true +ide.balloon.shadow.size=15 + editor.balloonHints=true editor.mouseSelectionStateResetTimeout=1000 diff --git a/platform/util/src/com/intellij/util/ui/UIUtil.java b/platform/util/src/com/intellij/util/ui/UIUtil.java index db7b3013a5aa..f5643cd9b83a 100644 --- a/platform/util/src/com/intellij/util/ui/UIUtil.java +++ b/platform/util/src/com/intellij/util/ui/UIUtil.java @@ -68,6 +68,23 @@ public class UIUtil { private static final String TABLE_DECORATION_KEY = "TABLE_DECORATION_KEY"; private static final Color DECORATED_ROW_BG_COLOR = new Color(242, 245, 249); + public static void applyStyle(@NotNull Style style, @NotNull Component comp) { + if (!(comp instanceof JComponent)) return; + + JComponent c = (JComponent)comp; + + if (SystemInfo.isMac) { + c.putClientProperty("JComponent.sizeVariant", style == Style.REGULAR ? "regular" : "small"); + } + else { + c.setFont(getFont(style == Style.SMALL ? FontSize.SMALL : FontSize.NORMAL, c.getFont())); + } + Container p = c.getParent(); + if (p != null) { + SwingUtilities.updateComponentTreeUI(p); + } + } + public enum FontSize { NORMAL, SMALL } public static final char MNEMONIC = 0x1B; @@ -2369,5 +2386,6 @@ public class UIUtil { && property instanceof Boolean && ((Boolean)property).booleanValue(); } + public enum Style {REGULAR, SMALL} }