From 022b18ae6d0c74e6506f81a7871f7b1b150eb283 Mon Sep 17 00:00:00 2001 From: "Leo.Qin" Date: Tue, 19 Dec 2023 19:47:10 +0800 Subject: [PATCH 1/5] =?UTF-8?q?REPORT-107973=20=E4=B8=BB=E9=A1=B5=E5=8F=8A?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E8=A7=86=E8=A7=89=E6=A0=B7=E5=BC=8F=E7=BF=BB?= =?UTF-8?q?=E6=96=B0=20=E3=80=90=E9=97=AE=E9=A2=98=E5=8E=9F=E5=9B=A0?= =?UTF-8?q?=E3=80=91rt=20=E3=80=90=E6=94=B9=E5=8A=A8=E6=80=9D=E8=B7=AF?= =?UTF-8?q?=E3=80=91=E7=BF=BB=E6=96=B0=E5=B8=A6=E6=A0=87=E7=AD=BE=E5=B8=A6?= =?UTF-8?q?=E6=BB=91=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/fine/theme/light/ui/FineSliderUI.java | 344 ++++++++++++++++++ .../fr/design/mainframe/JFormSliderPane.java | 7 +- .../theme/light/ui/laf/FineLaf.properties | 5 +- .../light/ui/laf/FineLightLaf.properties | 11 +- .../components/SliderStoryBoard.java | 20 +- 5 files changed, 375 insertions(+), 12 deletions(-) create mode 100644 designer-base/src/main/java/com/fine/theme/light/ui/FineSliderUI.java diff --git a/designer-base/src/main/java/com/fine/theme/light/ui/FineSliderUI.java b/designer-base/src/main/java/com/fine/theme/light/ui/FineSliderUI.java new file mode 100644 index 000000000..6917f66c9 --- /dev/null +++ b/designer-base/src/main/java/com/fine/theme/light/ui/FineSliderUI.java @@ -0,0 +1,344 @@ +package com.fine.theme.light.ui; + +import com.fine.theme.utils.FineUIUtils; +import com.formdev.flatlaf.ui.FlatSliderUI; +import com.formdev.flatlaf.ui.FlatUIUtils; +import com.formdev.flatlaf.util.HiDPIUtils; +import com.formdev.flatlaf.util.UIScale; +import com.fr.stable.AssistUtils; + +import javax.swing.JComponent; +import javax.swing.JSlider; +import javax.swing.UIManager; +import javax.swing.plaf.ComponentUI; +import java.awt.Color; +import java.awt.Component; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.Shape; +import java.awt.geom.Ellipse2D; +import java.awt.geom.Path2D; +import java.awt.geom.RoundRectangle2D; +import java.util.Dictionary; +import java.util.Enumeration; + +/** + * 滑块slider UI类 + * + * @author Leo.Qin + * @since 11.0 + * Created on 2023/12/15 + */ +public class FineSliderUI extends FlatSliderUI { + + private final int DEFAULT_LABEL_HEIGHT = 13; + private Color defaultForeground; + private int defaultLabelHeight; + + /** + * 创建UI + */ + public static ComponentUI createUI(JComponent c) { + return new FineSliderUI(); + } + + @Override + protected void installDefaults(JSlider slider) { + super.installDefaults(slider); + defaultForeground = UIManager.getColor("Slider.foreground"); + defaultLabelHeight = FineUIUtils.getAndScaleInt("Slider.labelHeight", DEFAULT_LABEL_HEIGHT); + } + + @Override + protected void calculateLabelRect() { + + if (slider.getPaintLabels()) { + calLabelRectWhenPaint(); + } else { + calLabelRectWhenNotPaint(); + } + } + + private void calLabelRectWhenPaint() { + labelRect.y = 0; + + if (slider.getOrientation() == JSlider.HORIZONTAL) { + labelRect.x = tickRect.x - trackBuffer; + labelRect.width = tickRect.width + (trackBuffer * 2); + labelRect.height = getHeightOfTallestLabel(); + } else { + if (isLeftToRight(slider)) { + labelRect.x = tickRect.x + tickRect.width; + labelRect.width = getWidthOfWidestLabel(); + } else { + labelRect.width = getWidthOfWidestLabel(); + labelRect.x = tickRect.x - labelRect.width; + } + labelRect.height = tickRect.height + (trackBuffer * 2); + } + } + + private void calLabelRectWhenNotPaint() { + labelRect.y = 0; + + if (slider.getOrientation() == JSlider.HORIZONTAL) { + labelRect.x = tickRect.x; + labelRect.width = tickRect.width; + labelRect.height = 0; + } else { + if (isLeftToRight(slider)) { + labelRect.x = tickRect.x + tickRect.width; + } else { + labelRect.x = tickRect.x; + } + labelRect.width = 0; + labelRect.height = tickRect.height; + } + } + + @Override + protected void calculateTrackRect() { + if (slider.getOrientation() == JSlider.HORIZONTAL) { + calHorizontalTrackRect(); + } else { + calVerticalTrackRect(); + } + } + + private void calVerticalTrackRect() { + int centerSpacing; + centerSpacing = thumbRect.width; + if (isLeftToRight(slider)) { + if (slider.getPaintTicks()) { + centerSpacing += getTickLength(); + } + if (slider.getPaintLabels()) { + centerSpacing += getWidthOfWidestLabel(); + } + } else { + if (slider.getPaintTicks()) { + centerSpacing -= getTickLength(); + } + if (slider.getPaintLabels()) { + centerSpacing -= getWidthOfWidestLabel(); + } + } + trackRect.x = contentRect.x + getWidthOfWidestLabel() + (contentRect.width - centerSpacing - 1) / 2; + trackRect.y = contentRect.y + trackBuffer; + trackRect.width = thumbRect.width; + trackRect.height = contentRect.height - (trackBuffer * 2); + } + + private void calHorizontalTrackRect() { + int centerSpacing; + centerSpacing = thumbRect.height; + if (slider.getPaintTicks()) { + centerSpacing += getTickLength(); + } + + if (slider.getPaintLabels()) { + centerSpacing += getHeightOfTallestLabel(); + } + trackRect.x = contentRect.x + trackBuffer; + trackRect.y = contentRect.y + getHeightOfTallestLabel() + (contentRect.height - centerSpacing - 1) / 2; + trackRect.width = contentRect.width - (trackBuffer * 2); + trackRect.height = thumbRect.height; + } + + @Override + protected int getHeightOfTallestLabel() { + Dictionary dictionary = slider.getLabelTable(); + int tallest = 0; + if (dictionary != null) { + Enumeration keys = dictionary.keys(); + while (keys.hasMoreElements()) { + JComponent label = (JComponent) dictionary.get(keys.nextElement()); + tallest = Math.max(label.getPreferredSize().height, tallest); + } + } + return Math.min(tallest, defaultLabelHeight); + } + + @Override + protected int getWidthOfWidestLabel() { + Dictionary dictionary = slider.getLabelTable(); + int widest = 0; + if (dictionary != null) { + Enumeration keys = dictionary.keys(); + while (keys.hasMoreElements()) { + JComponent label = (JComponent) dictionary.get(keys.nextElement()); + widest = Math.max(label.getPreferredSize().width, widest); + } + } + return Math.min(widest, defaultLabelHeight); + } + + /** + * Convenience function for determining ComponentOrientation. Helps us + * avoid having Munge directives throughout the code. + */ + static boolean isLeftToRight(Component c) { + return c.getComponentOrientation().isLeftToRight(); + } + + @Override + public void paintThumb(Graphics g) { + Color thumbColor = getThumbColor(); + Color color = stateColor(slider, thumbHover, thumbPressed, thumbColor, disabledThumbColor, null, hoverThumbColor, pressedThumbColor); + color = FlatUIUtils.deriveColor(color, thumbColor); + + Color foreground = slider.getForeground(); + Color borderColor = (thumbBorderColor != null && foreground == defaultForeground) ? stateColor(slider, false, false, thumbBorderColor, disabledThumbBorderColor, focusedThumbBorderColor, null, null) : null; + + Color focusedColor = FlatUIUtils.deriveColor(this.focusedColor, (foreground != defaultForeground) ? foreground : focusBaseColor); + + paintThumb(g, slider, thumbRect, isRoundThumb(), color, borderColor, focusedColor, thumbBorderWidth, focusWidth); + } + + /** + * Paints the thumb. + * + * @param g the graphics context + * @param slider the slider + * @param thumbRect the thumb rectangle + * @param roundThumb whether the thumb should be round + * @param thumbColor the thumb color + * @param thumbBorderColor the thumb border color + * @param focusedColor the focused color + * @param thumbBorderWidth the thumb border width + * @param focusWidth the focus width + */ + public static void paintThumb(Graphics g, JSlider slider, Rectangle thumbRect, boolean roundThumb, Color thumbColor, Color thumbBorderColor, Color focusedColor, float thumbBorderWidth, int focusWidth) { + double systemScaleFactor = UIScale.getSystemScaleFactor((Graphics2D) g); + int scaleFactor2 = 2; + if (systemScaleFactor != 1 && systemScaleFactor != scaleFactor2) { + // paint at scale 1x to avoid clipping on right and bottom edges at 125%, 150% or 175% + HiDPIUtils.paintAtScale1x((Graphics2D) g, thumbRect.x, thumbRect.y, thumbRect.width, thumbRect.height, (g2d, x2, y2, width2, height2, scaleFactor) -> { + paintThumbImpl(g, slider, x2, y2, width2, height2, roundThumb, thumbColor, thumbBorderColor, focusedColor, (float) (thumbBorderWidth * scaleFactor), (float) (focusWidth * scaleFactor)); + }); + return; + } + + paintThumbImpl(g, slider, thumbRect.x, thumbRect.y, thumbRect.width, thumbRect.height, roundThumb, thumbColor, thumbBorderColor, focusedColor, thumbBorderWidth, focusWidth); + + } + + private static void paintThumbImpl(Graphics g, JSlider slider, int x, int y, int width, int height, boolean roundThumb, Color thumbColor, Color thumbBorderColor, Color focusedColor, float thumbBorderWidth, float focusWidth) { + int fw = Math.round(UIScale.scale(focusWidth)); + int tx = x + fw; + int ty = y + fw; + int tw = width - fw - fw; + int th = height - fw - fw; + boolean focused = FlatUIUtils.isPermanentFocusOwner(slider); + + if (roundThumb) { + paintRoundThumb(g, x, y, width, height, thumbColor, thumbBorderColor, focusedColor, thumbBorderWidth, focused, tx, ty, tw, th); + } else { + paintDirectionalThumb(g, slider, x, y, width, height, thumbColor, thumbBorderColor, focusedColor, thumbBorderWidth, tw, th, focused, fw); + } + } + + private static void paintDirectionalThumb(Graphics g, JSlider slider, int x, int y, int width, int height, Color thumbColor, Color thumbBorderColor, Color focusedColor, float thumbBorderWidth, int tw, int th, boolean focused, int fw) { + Graphics2D g2 = (Graphics2D) g.create(); + try { + g2.translate(x, y); + if (slider.getOrientation() == JSlider.VERTICAL) { + if (slider.getComponentOrientation().isLeftToRight()) { + g2.translate(0, height); + g2.rotate(Math.toRadians(270)); + } else { + g2.translate(width, 0); + g2.rotate(Math.toRadians(90)); + } + + // rotate thumb width/height + int temp = tw; + tw = th; + th = temp; + } + + paintDirectionalThumbImpl(thumbColor, thumbBorderColor, focusedColor, thumbBorderWidth, tw, th, focused, fw, g2); + } finally { + g2.dispose(); + } + } + + private static void paintDirectionalThumbImpl(Color thumbColor, Color thumbBorderColor, Color focusedColor, float thumbBorderWidth, int tw, int th, boolean focused, int fw, Graphics2D g2) { + // paint thumb focus border + if (focused) { + g2.setColor(focusedColor); + g2.fill(createDirectionalThumbShape(0, 0, tw + fw + fw, th + fw + fw + (fw * 0.4142f), fw)); + } + + if (thumbBorderColor != null) { + // paint thumb border + g2.setColor(thumbBorderColor); + g2.fill(createDirectionalThumbShape(fw, fw, tw, th, 0)); + + // paint thumb background + float lw = UIScale.scale(thumbBorderWidth); + g2.setColor(thumbColor); + g2.fill(createDirectionalThumbShape(fw + lw, fw + lw, tw - lw - lw, th - lw - lw - (lw * 0.4142f), 0)); + } else { + // paint thumb background + g2.setColor(thumbColor); + g2.fill(createDirectionalThumbShape(fw, fw, tw, th, 0)); + } + } + + private static void paintRoundThumb(Graphics g, int x, int y, int width, int height, Color thumbColor, Color thumbBorderColor, Color focusedColor, float thumbBorderWidth, boolean focused, int tx, int ty, int tw, int th) { + // paint thumb focus border + if (focused) { + g.setColor(focusedColor); + ((Graphics2D) g).fill(createRoundThumbShape(x, y, width, height)); + } + + if (thumbBorderColor != null) { + // paint thumb border + g.setColor(thumbBorderColor); + ((Graphics2D) g).fill(createRoundThumbShape(tx, ty, tw, th)); + + // paint thumb background + float lw = UIScale.scale(thumbBorderWidth); + g.setColor(thumbColor); + ((Graphics2D) g).fill(createRoundThumbShape(tx + lw, ty + lw, tw - lw - lw, th - lw - lw)); + } else { + // paint thumb background + g.setColor(thumbColor); + ((Graphics2D) g).fill(createRoundThumbShape(tx, ty, tw, th)); + } + } + + /** + * 无标签下创建圆形Thumb形状 + */ + public static Shape createRoundThumbShape(float x, float y, float w, float h) { + if (AssistUtils.equals(w, h)) { + return new Ellipse2D.Float(x, y, w, h); + } else { + float arc = Math.min(w, h); + return new RoundRectangle2D.Float(x, y, w, h, arc, arc); + } + } + + /** + * 有标签下创建Thumb形状 + */ + public static Shape createDirectionalThumbShape(float x, float y, float w, float h, float arc) { + + float wh = w / 2; + Path2D path = new Path2D.Float(Path2D.WIND_NON_ZERO, 9); + path.moveTo(x + wh, y); // 移到反转后的位置 + path.lineTo(x, y + wh); // 线到反转后的位置 + path.lineTo(x, y + h - arc); // 线到反转后的位置 + path.quadTo(x, y + h, x + arc, y + h); // 贝塞尔曲线到反转后的位置 + path.lineTo(x + (w - arc), y + h); // 线到反转后的位置 + path.quadTo(x + w, y + h, x + w, y + h - arc); // 贝塞尔曲线到反转后的位置 + path.lineTo(x + w, y + wh); // 线到反转后的位置 + path.closePath(); // 关闭路径 + + return path; + } + +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/JFormSliderPane.java b/designer-base/src/main/java/com/fr/design/mainframe/JFormSliderPane.java index 4629b6068..ec87157ca 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/JFormSliderPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/JFormSliderPane.java @@ -1,6 +1,7 @@ package com.fr.design.mainframe; import com.fine.theme.icon.LazyIcon; +import com.fine.theme.utils.FineUIScale; import com.formdev.flatlaf.FlatDarculaLaf; import com.fr.base.BaseUtils; import com.fr.design.gui.ibutton.UIButton; @@ -48,8 +49,6 @@ public class JFormSliderPane extends JPanel { private static final int HUNDRED = 100; private static final int TWO_HUNDRED = 200; private static final int FOUR_HUNDRED = 400; - private static final int SHOWVALBUTTON_WIDTH = 40; - private static final int SHOWVALBUTTON_HEIGHTH = 20; private static final String SUFFIX = "%"; private static final int TOOLTIP_Y = 30; private static final Color BACK_COLOR = new Color(245, 245, 247); @@ -93,7 +92,6 @@ public class JFormSliderPane extends JPanel { }; slider.setValue(HALF_HUNDRED); slider.addChangeListener(listener); - slider.setPreferredSize(new Dimension(220, 20)); //去掉虚线框 slider.setFocusable(false); slider.setToolTipText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Scale_Slider")); @@ -124,7 +122,8 @@ public class JFormSliderPane extends JPanel { private void initShowValField() { showValField = new UINumberField(); showValField.setValue(showValue); - showValField.setPreferredSize(new Dimension(SHOWVALBUTTON_WIDTH, SHOWVALBUTTON_HEIGHTH)); + Dimension dimension = new Dimension(UIManager.getInt("FormSliderPane.showValueWidth"), UIManager.getInt("FormSliderPane.showValueHeight")); + showValField.setPreferredSize(FineUIScale.scale(dimension)); showValField.addKeyListener(new KeyListener() { @Override public void keyTyped(KeyEvent e) { diff --git a/designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLaf.properties b/designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLaf.properties index ed39afd70..32e958fa3 100644 --- a/designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLaf.properties +++ b/designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLaf.properties @@ -28,7 +28,7 @@ RootPaneUI=com.formdev.flatlaf.ui.FlatRootPaneUI ScrollBarUI=com.formdev.flatlaf.ui.FlatScrollBarUI ScrollPaneUI=com.formdev.flatlaf.ui.FlatScrollPaneUI SeparatorUI=com.formdev.flatlaf.ui.FlatSeparatorUI -SliderUI=com.formdev.flatlaf.ui.FlatSliderUI +SliderUI=com.fine.theme.light.ui.FineSliderUI SpinnerUI=com.formdev.flatlaf.ui.FlatSpinnerUI SplitPaneUI=com.formdev.flatlaf.ui.FlatSplitPaneUI TabbedPaneUI=com.formdev.flatlaf.ui.FlatTabbedPaneUI @@ -45,5 +45,4 @@ TreeUI=com.fine.theme.light.ui.UIFlatTreeUI ViewportUI=com.formdev.flatlaf.ui.FlatViewportUI HeadGroupUI=com.fine.theme.light.ui.FineHeadGroupUI ButtonGroupUI= com.fine.theme.light.ui.FineButtonGroupUI -SelectBoxUI= com.fine.theme.light.ui.FineSelectBoxUI - +SelectBoxUI= com.fine.theme.light.ui.FineSelectBoxUI \ No newline at end of file diff --git a/designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLightLaf.properties b/designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLightLaf.properties index 59cc81afe..e1a2c1965 100644 --- a/designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLightLaf.properties +++ b/designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLightLaf.properties @@ -688,17 +688,24 @@ Separator.foreground = shade(@background,15%) Slider.focusInsets = 0,0,0,0 Slider.trackWidth = 2 Slider.thumbSize = 12,12 -Slider.focusWidth = 4 +Slider.focusWidth=0 Slider.trackValueColor=$brand.normal Slider.trackColor=$border.divider Slider.thumbColor=$fill.normal Slider.thumbBorderColor=$border.divider Slider.tickColor = @disabledForeground -Slider.focusedColor = fade(changeLightness($Component.focusColor,75%,derived),50%,derived) +Slider.focusedColor=$border.divider +Slider.focusedThumbBorderColor=$border.divider Slider.hoverThumbColor=$fill.hover Slider.pressedThumbColor=$fill.hover Slider.disabledTrackColor = darken(@background,13%) Slider.disabledThumbColor = $Slider.disabledTrackColor +Slider.labelHeight=13 +#---- FormSliderPane ---- +FormSliderPane.showValueWidth=40 +FormSliderPane.showValueHeight=20 +FormSliderPane.sliderWidth=220 +FormSliderPane.sliderHeight=20 #---- Spinner ---- diff --git a/designer-base/src/test/java/com/fr/design/gui/storybook/components/SliderStoryBoard.java b/designer-base/src/test/java/com/fr/design/gui/storybook/components/SliderStoryBoard.java index 8238ff83e..26a86fdd1 100644 --- a/designer-base/src/test/java/com/fr/design/gui/storybook/components/SliderStoryBoard.java +++ b/designer-base/src/test/java/com/fr/design/gui/storybook/components/SliderStoryBoard.java @@ -1,8 +1,9 @@ package com.fr.design.gui.storybook.components; import com.fr.design.gui.ilable.UILabel; +import com.fr.design.gui.islider.UISlider; +import com.fr.design.gui.storybook.Story; import com.fr.design.gui.storybook.StoryBoard; -import com.fr.design.mainframe.JFormSliderPane; import static com.fine.swing.ui.layout.Layouts.*; @@ -13,12 +14,25 @@ import static com.fine.swing.ui.layout.Layouts.*; * @since 11.0 * Created on 2023/12/14 */ +@Story public class SliderStoryBoard extends StoryBoard { public SliderStoryBoard() { super("滑块"); add( - cell(new UILabel("面板缩放滑块")).with(this::h3), - row(cell(new JFormSliderPane())) + cell(new UILabel("无标签滑块")).with(this::h3), + row(cell(new UISlider()).with(it -> { + it.setValue(50); + it.setMaximum(100); + it.setMinimum(0); + })), + cell(new UILabel("带标签滑块")).with(this::h3), + row(cell(new UISlider()).with(it -> { + it.setPaintLabels(true); + it.setMajorTickSpacing(90); + it.setValue(40); + it.setMaximum(90); + it.setMinimum(-90); + })) ); } } From 2cd30a5684f595284f717463c86c8eb210a724dd Mon Sep 17 00:00:00 2001 From: "Leo.Qin" Date: Mon, 25 Dec 2023 16:22:13 +0800 Subject: [PATCH 2/5] =?UTF-8?q?REPORT-107973=20=E5=BC=B9=E7=AA=97=E6=A0=B7?= =?UTF-8?q?=E5=BC=8F=E7=BF=BB=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../theme/light/ui/FinePopupMenuBorder.java | 19 +++++++ .../fine/theme/light/ui/FinePopupMenuUI.java | 57 +++++++++++++++++++ .../fine/theme/light/ui/FineTooltipUI.java | 9 +-- .../com/fine/theme/light/ui/laf/FineLaf.java | 8 +++ .../design/gui/imenu/UIPopupEastAttrMenu.java | 17 ------ .../com/fr/design/gui/imenu/UIPopupMenu.java | 31 ---------- .../theme/light/ui/laf/FineLaf.properties | 2 +- .../light/ui/laf/FineLightLaf.properties | 10 ++-- .../mainframe/share/ui/local/GroupPane.java | 1 - 9 files changed, 95 insertions(+), 59 deletions(-) create mode 100644 designer-base/src/main/java/com/fine/theme/light/ui/FinePopupMenuBorder.java create mode 100644 designer-base/src/main/java/com/fine/theme/light/ui/FinePopupMenuUI.java diff --git a/designer-base/src/main/java/com/fine/theme/light/ui/FinePopupMenuBorder.java b/designer-base/src/main/java/com/fine/theme/light/ui/FinePopupMenuBorder.java new file mode 100644 index 000000000..63bf5e88e --- /dev/null +++ b/designer-base/src/main/java/com/fine/theme/light/ui/FinePopupMenuBorder.java @@ -0,0 +1,19 @@ +package com.fine.theme.light.ui; + +import com.fine.theme.utils.FineUIUtils; +import com.formdev.flatlaf.ui.FlatPopupMenuBorder; + +/** + * PopupMenu Border类 + * + * @author Leo.Qin + * @since 11.0 + * Created on 2023/12/25 + */ +public class FinePopupMenuBorder extends FlatPopupMenuBorder { + + @Override + public int getArc() { + return FineUIUtils.getAndScaleInt("PopupMenu.arc", 5); + } +} diff --git a/designer-base/src/main/java/com/fine/theme/light/ui/FinePopupMenuUI.java b/designer-base/src/main/java/com/fine/theme/light/ui/FinePopupMenuUI.java new file mode 100644 index 000000000..402734a77 --- /dev/null +++ b/designer-base/src/main/java/com/fine/theme/light/ui/FinePopupMenuUI.java @@ -0,0 +1,57 @@ +package com.fine.theme.light.ui; + +import com.fine.theme.utils.FineUIUtils; +import com.formdev.flatlaf.ui.FlatPopupMenuUI; + +import javax.swing.JComponent; +import javax.swing.plaf.ComponentUI; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.geom.RoundRectangle2D; + +/** + * PopupMenu UI类 + * + * @author Leo.Qin + * @since 11.0 + * Created on 2023/12/25 + */ +public class FinePopupMenuUI extends FlatPopupMenuUI { + private int arc; + private final int DEFAULT_ARC = 5; + + /** + * 创建UI + * + * @param c 组件 + * @return UI + */ + public static ComponentUI createUI(JComponent c) { + return new FinePopupMenuUI(); + } + + @Override + public void installDefaults() { + super.installDefaults(); + arc = FineUIUtils.getAndScaleInt("PopupMenu.arc", DEFAULT_ARC); + } + + @Override + public void paint(Graphics g, JComponent c) { + // 绘制圆角矩形作为弹窗背景 + Graphics2D g2d = (Graphics2D) g; + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + RoundRectangle2D roundRect = new RoundRectangle2D.Double(0, 0, c.getWidth(), c.getHeight(), arc, arc); + g2d.setColor(c.getBackground()); + g2d.fill(roundRect); + + // 绘制组件内容 + super.paint(g, c); + } + + @Override + public void update(Graphics g, JComponent c) { + paint(g, c); + } +} diff --git a/designer-base/src/main/java/com/fine/theme/light/ui/FineTooltipUI.java b/designer-base/src/main/java/com/fine/theme/light/ui/FineTooltipUI.java index a82d0477a..87b029529 100644 --- a/designer-base/src/main/java/com/fine/theme/light/ui/FineTooltipUI.java +++ b/designer-base/src/main/java/com/fine/theme/light/ui/FineTooltipUI.java @@ -9,13 +9,13 @@ import com.fr.stable.Constants; import javax.swing.JComponent; import javax.swing.JToolTip; import javax.swing.SwingUtilities; -import javax.swing.UIManager; import javax.swing.plaf.ComponentUI; import java.awt.Dimension; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Insets; +import java.awt.RenderingHints; import java.util.List; /** @@ -39,9 +39,11 @@ public class FineTooltipUI extends FlatToolTipUI { @Override public void paint(Graphics g, JComponent c) { + Graphics2D g2d = (Graphics2D) g; + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - g.setColor(c.getBackground()); - g.fillRoundRect(0, 0, c.getWidth(), c.getHeight(), arc, arc); + g2d.setColor(c.getBackground()); + g2d.fillRoundRect(0, 0, c.getWidth(), c.getHeight(), arc, arc); String text = ((JToolTip) c).getTipText(); if (text == null || text.isEmpty()) { @@ -49,7 +51,6 @@ public class FineTooltipUI extends FlatToolTipUI { } Insets insets = c.getInsets(); - Graphics2D g2d = (Graphics2D) g; FontMetrics fm = g2d.getFontMetrics(); int x = insets.left; diff --git a/designer-base/src/main/java/com/fine/theme/light/ui/laf/FineLaf.java b/designer-base/src/main/java/com/fine/theme/light/ui/laf/FineLaf.java index 568310df5..079d013d6 100644 --- a/designer-base/src/main/java/com/fine/theme/light/ui/laf/FineLaf.java +++ b/designer-base/src/main/java/com/fine/theme/light/ui/laf/FineLaf.java @@ -2,6 +2,8 @@ package com.fine.theme.light.ui.laf; import com.formdev.flatlaf.FlatLaf; +import javax.swing.PopupFactory; + /** * Fine designer new look and feel * FineLaf.properties 定义公共属性,如UI等, @@ -25,4 +27,10 @@ public abstract class FineLaf extends FlatLaf { public String getDescription() { return "Fine New Look and Feel"; } + + @Override + public void initialize() { + super.initialize(); + PopupFactory.setSharedInstance(new PopupFactory()); + } } diff --git a/designer-base/src/main/java/com/fr/design/gui/imenu/UIPopupEastAttrMenu.java b/designer-base/src/main/java/com/fr/design/gui/imenu/UIPopupEastAttrMenu.java index 42b04e03a..a7d7144e1 100644 --- a/designer-base/src/main/java/com/fr/design/gui/imenu/UIPopupEastAttrMenu.java +++ b/designer-base/src/main/java/com/fr/design/gui/imenu/UIPopupEastAttrMenu.java @@ -1,28 +1,11 @@ package com.fr.design.gui.imenu; -import java.awt.Graphics; -import java.awt.Insets; - import javax.swing.JPopupMenu; -import com.fr.design.constants.UIConstants; - public class UIPopupEastAttrMenu extends JPopupMenu { public UIPopupEastAttrMenu() { super(); - setBackground(UIConstants.NORMAL_BACKGROUND); - } - - @Override - protected void paintBorder(Graphics g) { - g.setColor(UIConstants.POP_DIALOG_BORDER); - g.drawRect(0, 0, getWidth() - 1, getHeight() - 1); - } - - @Override - public Insets getInsets() { - return new Insets(0, 1, 1, 1); } } \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/gui/imenu/UIPopupMenu.java b/designer-base/src/main/java/com/fr/design/gui/imenu/UIPopupMenu.java index e2a2546b2..b09989f95 100644 --- a/designer-base/src/main/java/com/fr/design/gui/imenu/UIPopupMenu.java +++ b/designer-base/src/main/java/com/fr/design/gui/imenu/UIPopupMenu.java @@ -1,11 +1,6 @@ package com.fr.design.gui.imenu; -import com.fr.design.constants.UIConstants; - import javax.swing.JPopupMenu; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.Insets; public class UIPopupMenu extends JPopupMenu{ private static final float DEFAULT_REC = 8f; @@ -15,32 +10,6 @@ public class UIPopupMenu extends JPopupMenu{ public static UIPopupMenu EMPTY = new UIPopupMenu(); public UIPopupMenu() { super(); -// setBackground(UIConstants.NORMAL_BACKGROUND); - } - - @Override - protected void paintComponent(Graphics g) { -// Graphics2D g2d = (Graphics2D) g; -// Shape shape = new RoundRectangle2D.Double(0, 0, getWidth(), getHeight(), rec, rec); -// g2d.setClip(shape); -// g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - super.paintComponent(g); - } - - @Override - protected void paintBorder(Graphics g) { - Graphics2D g2d = (Graphics2D) g; - g2d.setColor(UIConstants.UIPOPUPMENU_LINE_COLOR); -// g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - g2d.drawRoundRect(0, 0, getWidth() - 1, getHeight() - 1, (int) rec, (int) rec); - } - - @Override - public Insets getInsets() { - if(onlyText) { - return super.getInsets(); - } - return new Insets(10, 2, 10, 10); } public void setOnlyText(boolean onlyText) { diff --git a/designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLaf.properties b/designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLaf.properties index 32e958fa3..e176263d9 100644 --- a/designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLaf.properties +++ b/designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLaf.properties @@ -19,7 +19,7 @@ MenuItemUI=com.formdev.flatlaf.ui.FlatMenuItemUI OptionPaneUI=com.formdev.flatlaf.ui.FlatOptionPaneUI PanelUI=com.formdev.flatlaf.ui.FlatPanelUI PasswordFieldUI=com.formdev.flatlaf.ui.FlatPasswordFieldUI -PopupMenuUI=com.formdev.flatlaf.ui.FlatPopupMenuUI +PopupMenuUI=com.fine.theme.light.ui.FinePopupMenuUI PopupMenuSeparatorUI=com.formdev.flatlaf.ui.FlatPopupMenuSeparatorUI ProgressBarUI=com.formdev.flatlaf.ui.FlatProgressBarUI RadioButtonUI=com.formdev.flatlaf.ui.FlatRadioButtonUI diff --git a/designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLightLaf.properties b/designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLightLaf.properties index e1a2c1965..e23f80bd9 100644 --- a/designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLightLaf.properties +++ b/designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLightLaf.properties @@ -547,14 +547,14 @@ PopupToolPane.height=34 PopupToolPane.borderInsets=0, 10, 0, 10 #---- PopupMenu ---- - -PopupMenu.border = com.formdev.flatlaf.ui.FlatPopupMenuBorder -PopupMenu.borderInsets = 4,1,4,1 +PopupMenu.border=com.fine.theme.light.ui.FinePopupMenuBorder +PopupMenu.borderInsets=10,0,10,0 PopupMenu.borderCornerRadius = $Popup.borderCornerRadius -PopupMenu.background = @menuBackground +PopupMenu.background=$background.normal PopupMenu.scrollArrowColor = @buttonArrowColor -PopupMenu.borderColor = shade(@background,28%) +PopupMenu.borderColor=$border.divider PopupMenu.hoverScrollArrowBackground = darken(@background,5%) +PopupMenu.arc=$Component.arc #---- PopupMenuSeparator ---- diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/GroupPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/GroupPane.java index 0a4aacfc9..429269a1c 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/GroupPane.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/GroupPane.java @@ -289,7 +289,6 @@ public class GroupPane extends JPanel { public void mouseClicked(MouseEvent e) { UIPopupMenu popupMenu = new UIPopupMenu(); popupMenu.setOnlyText(true); - popupMenu.setBackground(UIConstants.DEFAULT_BG_RULER); popupMenu.add(new PopupMenuItem(new RenameAction())); popupMenu.add(new PopupMenuItem(new RemoveAction())); From 9da10a9a6ddee5c47d0fba051fa6a43d730410e0 Mon Sep 17 00:00:00 2001 From: "Leo.Qin" Date: Wed, 27 Dec 2023 09:56:02 +0800 Subject: [PATCH 3/5] =?UTF-8?q?REPORT-107973=20=E4=B8=BB=E9=A1=B5=E5=8F=8A?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E8=A7=86=E8=A7=89=E6=A0=B7=E5=BC=8F=E7=BF=BB?= =?UTF-8?q?=E6=96=B0=20=E3=80=90=E9=97=AE=E9=A2=98=E5=8E=9F=E5=9B=A0?= =?UTF-8?q?=E3=80=91rt=20=E3=80=90=E6=94=B9=E5=8A=A8=E6=80=9D=E8=B7=AF?= =?UTF-8?q?=E3=80=91=E7=BF=BB=E6=96=B0=E6=B8=90=E5=8F=98=E8=89=B2=E6=BB=91?= =?UTF-8?q?=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../theme/light/ui/FineGradientBarUI.java | 294 ++++++++++++++++++ .../com/fine/theme/light/ui/FineSliderUI.java | 6 +- .../background/gradient/FixedGradientBar.java | 6 +- .../background/gradient/GradientBar.java | 127 +++----- .../gradient/SelectColorPointBtn.java | 43 ++- .../theme/light/ui/laf/FineLaf.properties | 3 +- .../light/ui/laf/FineLightLaf.properties | 10 + .../components/SliderStoryBoard.java | 7 +- 8 files changed, 394 insertions(+), 102 deletions(-) create mode 100644 designer-base/src/main/java/com/fine/theme/light/ui/FineGradientBarUI.java diff --git a/designer-base/src/main/java/com/fine/theme/light/ui/FineGradientBarUI.java b/designer-base/src/main/java/com/fine/theme/light/ui/FineGradientBarUI.java new file mode 100644 index 000000000..fdf4a7f60 --- /dev/null +++ b/designer-base/src/main/java/com/fine/theme/light/ui/FineGradientBarUI.java @@ -0,0 +1,294 @@ +package com.fine.theme.light.ui; + +import com.fine.theme.utils.FineUIUtils; +import com.fr.design.style.background.gradient.GradientBar; +import com.fr.design.style.background.gradient.SelectColorPointBtn; +import com.fr.stable.AssistUtils; +import com.fr.stable.os.OperatingSystem; + +import javax.swing.JComponent; +import javax.swing.UIManager; +import javax.swing.plaf.ComponentUI; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.LinearGradientPaint; +import java.awt.RenderingHints; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionAdapter; +import java.awt.geom.Path2D; +import java.awt.geom.Point2D; +import java.util.Collections; +import java.util.List; + +/** + * 渐变色滑块 UI类 + * + * @author Leo.Qin + * @since 11.0 + * Created on 2023/12/19 + */ +public class FineGradientBarUI extends ComponentUI { + + private int directionalShapeSize; + private int recHeight; + private int width; + private int height; + private int borderWidth; + private Color borderColor; + private Color thumbBorderColor; + private Color hoverThumbColor; + private Color pressedThumbColor; + + private MouseMotionAdapter mouseMotionListener; + + GradientBar gradientBar; + private List list; + private SelectColorPointBtn p1; + private SelectColorPointBtn p2; + private MouseListener mouseListener; + private double offset = 0.0001; + + boolean[] hoverStatus; + + + /** + * 创建UI + * + * @param c 组件 + * @return UI + */ + public static ComponentUI createUI(JComponent c) { + return new FineGradientBarUI(); + } + + @Override + public void installUI(JComponent c) { + super.installUI(c); + installDefaults(c); + + gradientBar = (GradientBar) c; + list = gradientBar.getList(); + p1 = gradientBar.getSelectColorPointBtnP1(); + p2 = gradientBar.getSelectColorPointBtnP2(); + hoverStatus = new boolean[list.size()]; + mouseMotionListener = new TrackMotionListener(); + mouseListener = new TrackMouseListener(); + gradientBar.addMouseMotionListener(mouseMotionListener); + gradientBar.addMouseListener(mouseListener); + } + + private void installDefaults(JComponent c) { + directionalShapeSize = FineUIUtils.getAndScaleInt("GradientBar.thumbWidth", 12); + recHeight = FineUIUtils.getAndScaleInt("GradientBar.recHeight", 30); + width = FineUIUtils.getAndScaleInt("GradientBar.recWidth", 160); + height = recHeight + directionalShapeSize; + borderWidth = FineUIUtils.getAndScaleInt("GradientBar.borderWidth", 1); + borderColor = UIManager.getColor("GradientBar.borderColor"); + thumbBorderColor = UIManager.getColor("GradientBar.thumbBorderColor"); + hoverThumbColor = UIManager.getColor("GradientBar.hoverThumbColor"); + pressedThumbColor = UIManager.getColor("GradientBar.pressedThumbColor"); + } + + private class TrackMouseListener extends MouseAdapter { + @Override + public void mouseExited(MouseEvent e) { + for (int i = 0; i < list.size(); i++) { + SelectColorPointBtn selectColorPointBtn = list.get(i); + selectColorPointBtn.setHover(false); + hoverStatus[i] = false; + } + + gradientBar.repaint(); + } + + @Override + public void mouseEntered(MouseEvent e) { + checkHoverStatus(e); + } + + @Override + public void mousePressed(MouseEvent e) { + for (SelectColorPointBtn btn : list) { + boolean hover = isOverBtn(e, btn); + btn.setPressed(hover); + } + + gradientBar.repaint(); + } + + @Override + public void mouseReleased(MouseEvent e) { + for (SelectColorPointBtn btn : list) { + btn.setPressed(false); + } + + gradientBar.repaint(); + } + } + + + private class TrackMotionListener extends MouseMotionAdapter { + int index; + + @Override + public void mouseDragged(MouseEvent e) { + if (!gradientBar.isDraggable()) { + return; + } + index = getSelectedIndex(e, index); + int halfSize = directionalShapeSize / 2; + boolean x = e.getX() <= gradientBar.getWidth() - halfSize && e.getX() >= halfSize; + if (x) { + list.get(index).setX(e.getX()); + list.get(index).setStartPosition((double) (e.getX() - halfSize) / (gradientBar.getWidth() - directionalShapeSize)); + gradientBar.repaint(); + } + } + + private int getSelectedIndex(MouseEvent e, int index) { + int oldIndex = index; + + for (int i = 0; i < list.size(); i++) { + if (list.get(i).contains(e.getX(), e.getY())) { + index = i; + break; + } + } + + if (OperatingSystem.isLinux() && AssistUtils.equals(oldIndex, index)) { + if (Math.abs(p1.getX() - e.getX()) > Math.abs(p2.getX() - e.getX())) { + index = 1; + } else { + index = 0; + } + } + return index; + } + + @Override + public void mouseMoved(MouseEvent e) { + checkHoverStatus(e); + } + + } + + private void checkHoverStatus(MouseEvent e) { + boolean repaint = false; + for (int i = 0; i < list.size(); i++) { + SelectColorPointBtn btn = list.get(i); + boolean hover = isOverBtn(e, btn); + if (hoverStatus[i] != hover) { + repaint = true; + hoverStatus[i] = hover; + btn.setHover(hover); + } + } + + if (repaint) { + gradientBar.repaint(); + } + } + + private boolean isOverBtn(MouseEvent e, SelectColorPointBtn btn) { + return btn.contains(e.getX(), e.getY()); + } + + @Override + public void paint(Graphics g, JComponent c) { + Graphics2D g2 = (Graphics2D) g; + + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_NORMALIZE); + + GradientBar component = (GradientBar) c; + List btnList = component.getList(); + Collections.sort(btnList); + + + paintBorder(g2, component); + paintContent(g2, component); + paintButton(g2, btnList); + + } + + /** + * 实际绘制区域x范围(directionalShapeSize / 2, width - directionalShapeSize) + */ + private void paintContent(Graphics2D g2d, GradientBar c) { + List btnList = c.getList(); + + int halfSize = directionalShapeSize / 2; + Point2D start = new Point2D.Float(halfSize, 0); + Point2D end = new Point2D.Float(c.getWidth() - halfSize, 0); + + + Collections.sort(btnList); + Color[] colors = new Color[btnList.size()]; + for (int i = 0; i < btnList.size(); i++) { + colors[i] = btnList.get(i).getColorInner(); + } + + float[] dist = new float[btnList.size()]; + for (int i = 0; i < btnList.size(); i++) { + if (btnList.get(i).getStartPosition() < 0) { + dist[i] = 0; + } else if (btnList.get(i).getStartPosition() > 1) { + dist[i] = 1; + } else { + dist[i] = (float) btnList.get(i).getStartPosition(); + } + + btnList.get(i).setX(dist[i] * (c.getWidth() - directionalShapeSize) + (double) directionalShapeSize / 2); + } + + float dist1 = dist[btnList.size() - 1]; + float dist2 = dist[btnList.size() - 2]; + if (AssistUtils.equals(dist1, dist2)) { + dist[btnList.size() - 1] = (float) (dist2 + offset); + } + LinearGradientPaint paint = new LinearGradientPaint(start, end, dist, colors); + g2d.setPaint(paint); + g2d.fillRect(halfSize + borderWidth, borderWidth, c.getWidth() - directionalShapeSize - borderWidth * 2, recHeight - borderWidth * 2); + } + + private void paintBorder(Graphics2D g2d, GradientBar c) { + int halfSize = directionalShapeSize / 2; + if (borderColor == null) { + return; + } + g2d.setColor(borderColor); + g2d.fillRect(halfSize, 0, c.getWidth() - directionalShapeSize, recHeight); + } + + private void paintButton(Graphics2D g2d, List list) { + + for (SelectColorPointBtn selectColorPointBtn : list) { + Path2D directionalThumbShape = FineSliderUI.createDirectionalThumbShape((float) selectColorPointBtn.getX() - (float) directionalShapeSize / 2, (float) selectColorPointBtn.getY(), directionalShapeSize, directionalShapeSize, 0); + if (selectColorPointBtn.isHover() && hoverThumbColor != null) { + g2d.setColor(hoverThumbColor); + g2d.fill(directionalThumbShape); + } else if (selectColorPointBtn.isPressed() && pressedThumbColor != null) { + g2d.setColor(pressedThumbColor); + g2d.fill(directionalThumbShape); + } else if (thumbBorderColor != null) { + g2d.setColor(thumbBorderColor); + g2d.fill(directionalThumbShape); + } + selectColorPointBtn.updatePath(directionalThumbShape); + + Path2D innerThumbShape = FineSliderUI.createDirectionalThumbShape((float) selectColorPointBtn.getX() - (float) directionalShapeSize / 2 + borderWidth, (float) selectColorPointBtn.getY() + borderWidth, directionalShapeSize - borderWidth * 2, directionalShapeSize - borderWidth * 2, 0); + g2d.setColor(selectColorPointBtn.getColorInner()); + g2d.fill(innerThumbShape); + } + + } + + @Override + public Dimension getPreferredSize(JComponent c) { + return new Dimension(width, height); + } +} diff --git a/designer-base/src/main/java/com/fine/theme/light/ui/FineSliderUI.java b/designer-base/src/main/java/com/fine/theme/light/ui/FineSliderUI.java index 6917f66c9..a8f150fb4 100644 --- a/designer-base/src/main/java/com/fine/theme/light/ui/FineSliderUI.java +++ b/designer-base/src/main/java/com/fine/theme/light/ui/FineSliderUI.java @@ -268,7 +268,7 @@ public class FineSliderUI extends FlatSliderUI { // paint thumb focus border if (focused) { g2.setColor(focusedColor); - g2.fill(createDirectionalThumbShape(0, 0, tw + fw + fw, th + fw + fw + (fw * 0.4142f), fw)); + g2.fill(createDirectionalThumbShape(0, 0, tw + fw + fw, th + fw + fw, fw)); } if (thumbBorderColor != null) { @@ -279,7 +279,7 @@ public class FineSliderUI extends FlatSliderUI { // paint thumb background float lw = UIScale.scale(thumbBorderWidth); g2.setColor(thumbColor); - g2.fill(createDirectionalThumbShape(fw + lw, fw + lw, tw - lw - lw, th - lw - lw - (lw * 0.4142f), 0)); + g2.fill(createDirectionalThumbShape(fw + lw, fw + lw, tw - lw - lw, th - lw - lw, 0)); } else { // paint thumb background g2.setColor(thumbColor); @@ -325,7 +325,7 @@ public class FineSliderUI extends FlatSliderUI { /** * 有标签下创建Thumb形状 */ - public static Shape createDirectionalThumbShape(float x, float y, float w, float h, float arc) { + public static Path2D createDirectionalThumbShape(float x, float y, float w, float h, float arc) { float wh = w / 2; Path2D path = new Path2D.Float(Path2D.WIND_NON_ZERO, 9); diff --git a/designer-base/src/main/java/com/fr/design/style/background/gradient/FixedGradientBar.java b/designer-base/src/main/java/com/fr/design/style/background/gradient/FixedGradientBar.java index 06a217f23..0cb8fd8d4 100644 --- a/designer-base/src/main/java/com/fr/design/style/background/gradient/FixedGradientBar.java +++ b/designer-base/src/main/java/com/fr/design/style/background/gradient/FixedGradientBar.java @@ -12,6 +12,7 @@ public class FixedGradientBar extends GradientBar { public FixedGradientBar(int minvalue, int maxvalue) { super(minvalue, maxvalue); + setDraggable(false); } @Override @@ -19,9 +20,4 @@ public class FixedGradientBar extends GradientBar { setColor(getList().get(select).getColorInner()); super.clickButton(select); } - - @Override - protected void addMouseDragListener() { - //不添加拖拽事件 - } } \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/style/background/gradient/GradientBar.java b/designer-base/src/main/java/com/fr/design/style/background/gradient/GradientBar.java index 97a19f464..d62199b04 100644 --- a/designer-base/src/main/java/com/fr/design/style/background/gradient/GradientBar.java +++ b/designer-base/src/main/java/com/fr/design/style/background/gradient/GradientBar.java @@ -1,5 +1,7 @@ package com.fr.design.style.background.gradient; +import com.fine.theme.light.ui.FineGradientBarUI; +import com.fine.theme.utils.FineUIUtils; import com.fr.base.background.ColorBackground; import com.fr.design.event.UIObserver; import com.fr.design.event.UIObserverListener; @@ -8,34 +10,34 @@ import com.fr.design.style.color.ColorCell; import com.fr.design.style.color.ColorSelectable; import com.fr.design.style.color.NewColorSelectPane; import com.fr.stable.AssistUtils; -import com.fr.stable.os.OperatingSystem; import javax.swing.JPanel; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; import java.awt.Color; -import java.awt.Cursor; -import java.awt.Dimension; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.LinearGradientPaint; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; -import java.awt.geom.Point2D; +import java.util.ArrayList; +import java.util.List; /** - * TODO:面板缩放的功能没有考虑(就是尾值过大,导致超过界面显示的情况),原来的那个实现完全是个BUG。要缩放的情况也比较少,就干脆以后弄吧 + * 渐变色滑块 + * @since 11.0 + * Create on 2023/12/27. */ public class GradientBar extends AbstractComponentPopBox implements UIObserver, ColorSelectable { + private static final String UI_CLASS_ID = "GradientBarUI"; + + @Override + public String getUIClassID() { + return UI_CLASS_ID; + } + private NewColorSelectPane colorPane; - /** - * - */ + + private static final long serialVersionUID = -8503629815871053585L; private List list = new ArrayList(); @@ -57,6 +59,8 @@ public class GradientBar extends AbstractComponentPopBox implements UIObserver, private static final int MAX_VERTICAL = 45; + private boolean draggable = true; + // 选中的颜色 private Color color; @@ -71,19 +75,17 @@ public class GradientBar extends AbstractComponentPopBox implements UIObserver, endLabel = new UINumberField(11); endLabel.setValue(max); endLabel.getDocument().addDocumentListener(docListener); - - this.setPreferredSize(new Dimension(max + 5, 50)); - - p1 = new SelectColorPointBtn(startLabel.getValue(), 30, Color.WHITE); - p2 = new SelectColorPointBtn(endLabel.getValue(), 30, Color.BLACK); + int recHeight = FineUIUtils.getAndScaleInt("GradientBar.recHeight", 30); + p1 = new SelectColorPointBtn(startLabel.getValue(), recHeight, Color.WHITE); + p2 = new SelectColorPointBtn(endLabel.getValue(), recHeight, Color.BLACK); list.add(p1); list.add(p2); - this.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); - + p1.setStartPosition(0); + p2.setStartPosition(1); addMouseClickListener(); - addMouseDragListener(); iniListener(); + setUI(new FineGradientBarUI()); } public List getList() { @@ -110,7 +112,7 @@ public class GradientBar extends AbstractComponentPopBox implements UIObserver, protected void addMouseClickListener() { this.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { - if (e.getX() < max + MOUSE_OFFSET && e.getX() > 0) { + if (e.getX() < getWidth() && e.getX() > 0) { int select = -1; for (int i = 0; i < list.size(); i++) { if (list.get(i).contains(e.getX(), e.getY())) { @@ -159,35 +161,6 @@ public class GradientBar extends AbstractComponentPopBox implements UIObserver, return colorPane; } - protected void addMouseDragListener() { - this.addMouseMotionListener(new MouseAdapter() { - public void mouseDragged(MouseEvent e) { - int oldIndex = index; - for (int i = 0; i < list.size(); i++) { - if (list.get(i).contains(e.getX(), e.getY())) { - index = i; - break; - } - } - if (OperatingSystem.isLinux() && AssistUtils.equals(oldIndex, index)) { - if (Math.abs(p1.getX() - e.getX()) > Math.abs(p2.getX() - e.getX())) { - index = 1; - } else { - index = 0; - } - } - boolean x = e.getX() <= max && e.getX() >= min; - if (x && e.getY() < MAX_VERTICAL) { - list.get(index).setX(e.getX()); - } - - GradientBar.this.repaint(); - startLabel.setText(Double.toString(p1.getX())); - endLabel.setText(Double.toString(p2.getX())); - } - }); - } - private void iniListener() { uiObserverListener = new ArrayList<>(); if (shouldResponseChangeListener()) { @@ -216,40 +189,6 @@ public class GradientBar extends AbstractComponentPopBox implements UIObserver, } }; - @Override - protected void paintComponent(Graphics g) { - Graphics2D g2 = (Graphics2D) g; - - Point2D start = new Point2D.Float(4, 0); - Point2D end = new Point2D.Float(max, 0); - Collections.sort(list); - Color[] c = new Color[list.size()]; - for (int i = 0; i < list.size(); i++) { - c[i] = list.get(i).getColorInner(); - } - float[] dist = new float[list.size()]; - for (int i = 0; i < list.size(); i++) { - double value = list.get(i).getX() - 4; - double defaultMax = max - 4; - if (Double.compare(value, defaultMax) > 0) { - // 设置了预定义的渐变色 渐变色起始位置比较大 然后由预定义样式切换到自定义样式 做下等比例转换 - dist[i] = (float) (value / (GradientBackgroundPane.DEFAULT_GRADIENT_WIDTH - 4)); - list.get(i).setX(max * dist[i]); - } else { - dist[i] = (float) (value / defaultMax); - } - } - LinearGradientPaint paint = new LinearGradientPaint(start, end, dist, c); - - g2.setPaint(paint); - g2.fillRect(4, 0, max - 4, 30); - g2.setColor(new Color(138, 138, 138)); - g2.drawRect(4, 0, max - 4, 30); - for (int i = 0; i < list.size(); i++) { - list.get(i).paint(g2); - } - } - /** * 状态改变 */ @@ -281,14 +220,14 @@ public class GradientBar extends AbstractComponentPopBox implements UIObserver, * @return */ public double getStartValue() { - return startLabel.getValue(); + return p1.getStartPosition() * (max - min) + min; } /** * @return */ public double getEndValue() { - return endLabel.getValue(); + return p2.getStartPosition() * (max - min) + min; } /** @@ -296,7 +235,7 @@ public class GradientBar extends AbstractComponentPopBox implements UIObserver, */ public void setStartValue(double startValue) { startLabel.setValue(startValue); - p1.setX(startValue); + p1.setStartPosition((startValue - min) / (max - min)); } /** @@ -304,7 +243,7 @@ public class GradientBar extends AbstractComponentPopBox implements UIObserver, */ public void setEndValue(double endValue) { endLabel.setValue(endValue); - p2.setX(endValue); + p2.setStartPosition((endValue - min) / (max - min)); } /** @@ -359,4 +298,12 @@ public class GradientBar extends AbstractComponentPopBox implements UIObserver, public void colorSetted(ColorCell colorCell) { } + + public boolean isDraggable() { + return draggable; + } + + public void setDraggable(boolean draggable) { + this.draggable = draggable; + } } \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/style/background/gradient/SelectColorPointBtn.java b/designer-base/src/main/java/com/fr/design/style/background/gradient/SelectColorPointBtn.java index 0d07a96ac..47b925e07 100644 --- a/designer-base/src/main/java/com/fr/design/style/background/gradient/SelectColorPointBtn.java +++ b/designer-base/src/main/java/com/fr/design/style/background/gradient/SelectColorPointBtn.java @@ -4,6 +4,7 @@ import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.geom.GeneralPath; +import java.awt.geom.Path2D; public class SelectColorPointBtn implements Comparable { @@ -11,12 +12,19 @@ public class SelectColorPointBtn implements Comparable { private double y; private double a = 4; private double b = 4; - private GeneralPath ipath; - private GeneralPath jpath; + private Path2D ipath; + private Path2D jpath; private Color colorInner; + // 起始位置,范围(0,1) + private double startPosition; + private double max; + /*提供一个可设置拖拉按钮边框颜色*/ private Color borderColor; + private boolean hover = false; + private boolean pressed = false; + public SelectColorPointBtn(double m, double n, Color colorInner){ this(m, n, colorInner, Color.BLACK); } @@ -40,6 +48,14 @@ public class SelectColorPointBtn implements Comparable { this.x = x; } + public double getStartPosition() { + return startPosition; + } + + public void setStartPosition(double startPosition) { + this.startPosition = startPosition; + } + public double getY() { return y; } @@ -84,6 +100,13 @@ public class SelectColorPointBtn implements Comparable { g2.setColor(new Color(228, 228, 228)); g2.draw(jpath); } + + /** + * 更新拖拉按钮路径 + */ + public void updatePath(Path2D directionalThumbShape) { + this.ipath = directionalThumbShape; + } public boolean contains(double x, double y){ return ipath.contains(x, y); @@ -93,4 +116,20 @@ public class SelectColorPointBtn implements Comparable { public int compareTo(SelectColorPointBtn o) { return Double.compare(x, o.x); } + + public boolean isHover() { + return hover; + } + + public void setHover(boolean b) { + hover = b; + } + + public boolean isPressed() { + return pressed; + } + + public void setPressed(boolean pressed) { + this.pressed = pressed; + } } \ No newline at end of file diff --git a/designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLaf.properties b/designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLaf.properties index e176263d9..5e1601c8f 100644 --- a/designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLaf.properties +++ b/designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLaf.properties @@ -45,4 +45,5 @@ TreeUI=com.fine.theme.light.ui.UIFlatTreeUI ViewportUI=com.formdev.flatlaf.ui.FlatViewportUI HeadGroupUI=com.fine.theme.light.ui.FineHeadGroupUI ButtonGroupUI= com.fine.theme.light.ui.FineButtonGroupUI -SelectBoxUI= com.fine.theme.light.ui.FineSelectBoxUI \ No newline at end of file +SelectBoxUI= com.fine.theme.light.ui.FineSelectBoxUI +GradientBarUI=com.fine.theme.light.ui.FineGradientBarUI \ No newline at end of file diff --git a/designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLightLaf.properties b/designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLightLaf.properties index e23f80bd9..d0241bc58 100644 --- a/designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLightLaf.properties +++ b/designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLightLaf.properties @@ -706,6 +706,16 @@ FormSliderPane.showValueWidth=40 FormSliderPane.showValueHeight=20 FormSliderPane.sliderWidth=220 FormSliderPane.sliderHeight=20 +#---- GradientBar ---- +GradientBar.borderColor=$border.divider +GradientBar.thumbBorderColor=$border.divider +GradientBar.borderWidth=1 +GradientBar.pressedThumbColor=@BrandColor +GradientBar.hoverThumbColor=@BrandColor +GradientBar.thumbWidth=12 +GradientBar.recWidth=160 +GradientBar.recHeight=30 + #---- Spinner ---- diff --git a/designer-base/src/test/java/com/fr/design/gui/storybook/components/SliderStoryBoard.java b/designer-base/src/test/java/com/fr/design/gui/storybook/components/SliderStoryBoard.java index 26a86fdd1..96826f5bc 100644 --- a/designer-base/src/test/java/com/fr/design/gui/storybook/components/SliderStoryBoard.java +++ b/designer-base/src/test/java/com/fr/design/gui/storybook/components/SliderStoryBoard.java @@ -4,6 +4,9 @@ import com.fr.design.gui.ilable.UILabel; import com.fr.design.gui.islider.UISlider; import com.fr.design.gui.storybook.Story; import com.fr.design.gui.storybook.StoryBoard; +import com.fr.design.style.background.gradient.GradientBar; + +import java.awt.Color; import static com.fine.swing.ui.layout.Layouts.*; @@ -32,7 +35,9 @@ public class SliderStoryBoard extends StoryBoard { it.setValue(40); it.setMaximum(90); it.setMinimum(-90); - })) + })), + cell(new UILabel("渐变色滑块")).with(this::h3), + row(cell(new GradientBar(6, 150)).with(it -> it.updateColor(new Color(55, 104, 196), new Color(180, 97, 39)))) ); } } From a1eb39fcc1c3e0b0f7442bd939adbee9c0e08483 Mon Sep 17 00:00:00 2001 From: "Leo.Qin" Date: Wed, 27 Dec 2023 10:06:53 +0800 Subject: [PATCH 4/5] =?UTF-8?q?REPORT-107973=20=E4=B8=BB=E9=A1=B5=E5=8F=8A?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E8=A7=86=E8=A7=89=E6=A0=B7=E5=BC=8F=E7=BF=BB?= =?UTF-8?q?=E6=96=B0=20=E3=80=90=E9=97=AE=E9=A2=98=E5=8E=9F=E5=9B=A0?= =?UTF-8?q?=E3=80=91rt=20=E3=80=90=E6=94=B9=E5=8A=A8=E6=80=9D=E8=B7=AF?= =?UTF-8?q?=E3=80=91=E4=B8=BA=E6=96=B0=E5=A2=9Ekey=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E9=BB=98=E8=AE=A4=E5=80=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/fine/theme/light/ui/FineInputUI.java | 7 +++--- .../fine/theme/light/ui/FineLightIconSet.java | 2 +- .../fine/theme/light/ui/FineTooltipUI.java | 7 ++++-- .../com/fine/theme/utils/FineUIUtils.java | 17 +++++++++++-- .../search/pane/FineSearchPane.java | 24 +++++++++++------- .../fr/design/foldablepane/HeaderPane.java | 13 +++++++--- .../design/gui/frpane/UINumberDragPane.java | 8 +++--- .../com/fr/design/gui/ispinner/UISpinner.java | 25 +++++++++++++------ .../fr/design/gui/itextfield/UITextField.java | 6 ++--- .../mainframe/EastRegionContainerPane.java | 7 +++--- .../accessibles/BaseAccessibleEditor.java | 17 ++++++++----- .../theme/light/ui/laf/FineLaf.properties | 1 + 12 files changed, 90 insertions(+), 44 deletions(-) diff --git a/designer-base/src/main/java/com/fine/theme/light/ui/FineInputUI.java b/designer-base/src/main/java/com/fine/theme/light/ui/FineInputUI.java index 3c5200118..2035d1c02 100644 --- a/designer-base/src/main/java/com/fine/theme/light/ui/FineInputUI.java +++ b/designer-base/src/main/java/com/fine/theme/light/ui/FineInputUI.java @@ -1,6 +1,6 @@ package com.fine.theme.light.ui; -import com.fine.theme.utils.FineUIScale; +import com.fine.theme.utils.FineUIUtils; import com.formdev.flatlaf.ui.FlatButtonUI; import com.formdev.flatlaf.ui.FlatPanelUI; @@ -12,7 +12,7 @@ import javax.swing.plaf.ComponentUI; import java.beans.PropertyChangeEvent; /** - * Input输入框 UI类 + * Input输入框类组件 UI类 * * @author Leo.Qin * @since 11.0 @@ -22,6 +22,7 @@ public class FineInputUI extends FlatPanelUI { private static final String ENABLED = "enabled"; private static final String EDITABLE = "editable"; + private final int defaultArc = 5; public FineInputUI(boolean shared) { super(shared); @@ -44,7 +45,7 @@ public class FineInputUI extends FlatPanelUI { @Override protected void installDefaults(JPanel p) { super.installDefaults(p); - arc = FineUIScale.scale(UIManager.getInt("Input.arc")); + arc = FineUIUtils.getAndScaleInt("Input.arc", defaultArc); } @Override diff --git a/designer-base/src/main/java/com/fine/theme/light/ui/FineLightIconSet.java b/designer-base/src/main/java/com/fine/theme/light/ui/FineLightIconSet.java index 65cec1efe..b7fd93133 100644 --- a/designer-base/src/main/java/com/fine/theme/light/ui/FineLightIconSet.java +++ b/designer-base/src/main/java/com/fine/theme/light/ui/FineLightIconSet.java @@ -41,7 +41,7 @@ public class FineLightIconSet extends AbstractIconSet { // 数据集相关Icon new SvgIconSource("database", "com/fine/theme/icon/dataset/database.svg", true), new SvgIconSource("preview", "com/fine/theme/icon/dataset/preview.svg", true), - new SvgIconSource("connection", "com/fine/theme/icon/dataset/connection.svg", true), + new SvgIconSource("connection", "com/fine/theme/icon/dataset/connection.svg"), new SvgIconSource("class_table_data", "com/fine/theme/icon/dataset/class_table_data.svg", true), new SvgIconSource("data_table", "com/fine/theme/icon/dataset/data_table.svg", true), new SvgIconSource("multi", "com/fine/theme/icon/dataset/multi.svg", true), diff --git a/designer-base/src/main/java/com/fine/theme/light/ui/FineTooltipUI.java b/designer-base/src/main/java/com/fine/theme/light/ui/FineTooltipUI.java index 87b029529..b839c52c9 100644 --- a/designer-base/src/main/java/com/fine/theme/light/ui/FineTooltipUI.java +++ b/designer-base/src/main/java/com/fine/theme/light/ui/FineTooltipUI.java @@ -1,6 +1,7 @@ package com.fine.theme.light.ui; import com.fine.theme.utils.FineUIScale; +import com.fine.theme.utils.FineUIUtils; import com.formdev.flatlaf.ui.FlatToolTipUI; import com.formdev.flatlaf.ui.FlatUIUtils; import com.fr.base.BaseUtils; @@ -26,6 +27,8 @@ import java.util.List; * Created on 2023/12/8 */ public class FineTooltipUI extends FlatToolTipUI { + private final int defaultMaxWidth = 392; + private final int defaultArc = 5; private int maxWidth; private int arc; private List lines; @@ -70,8 +73,8 @@ public class FineTooltipUI extends FlatToolTipUI { protected void installDefaults(JComponent c) { super.installDefaults(c); c.setOpaque(false); - arc = FineUIScale.scale(UIManager.getInt("ToolTip.arc")); - maxWidth = FineUIScale.scale(UIManager.getInt("ToolTip.maxWidth")); + arc = FineUIScale.scale(FineUIUtils.getAndScaleInt("ToolTip.arc", defaultArc)); + maxWidth = FineUIUtils.getAndScaleInt("ToolTip.maxWidth", defaultMaxWidth); } diff --git a/designer-base/src/main/java/com/fine/theme/utils/FineUIUtils.java b/designer-base/src/main/java/com/fine/theme/utils/FineUIUtils.java index 25db5c228..e3065c16f 100644 --- a/designer-base/src/main/java/com/fine/theme/utils/FineUIUtils.java +++ b/designer-base/src/main/java/com/fine/theme/utils/FineUIUtils.java @@ -6,12 +6,12 @@ import com.fr.value.AtomicClearableLazyValue; import javax.swing.UIManager; import java.awt.Color; +import java.awt.Composite; import java.awt.Graphics; import java.awt.Graphics2D; -import java.awt.Insets; -import java.awt.Composite; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; +import java.awt.Insets; import java.awt.geom.RoundRectangle2D; import java.lang.reflect.Field; @@ -142,6 +142,19 @@ public class FineUIUtils { return (margin != null) ? margin : defaultInsets; } + /** + * 通过key获取UI的边距,如果没有则使用后备边距,并根据dpi进行缩放 + * + * @param key 边距key + * @param defaultInsets 后备边距 + * @return 根据dpi缩放后的边距 + */ + public static Insets getAndScaleUIInsets(String key, Insets defaultInsets) { + Insets margin = UIManager.getInsets(key); + Insets insets = (margin != null) ? margin : defaultInsets; + return FineUIScale.scale(insets); + } + /** * 绘制混合图像,含圆角、背景色设置 * diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/management/search/pane/FineSearchPane.java b/designer-base/src/main/java/com/fr/design/data/datapane/management/search/pane/FineSearchPane.java index 18af10fb6..9f3f98dfb 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/management/search/pane/FineSearchPane.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/management/search/pane/FineSearchPane.java @@ -2,7 +2,7 @@ package com.fr.design.data.datapane.management.search.pane; import com.fine.theme.icon.LazyIcon; import com.fine.theme.light.ui.FineInputUI; -import com.fine.theme.utils.FineUIScale; +import com.fine.theme.utils.FineUIUtils; import com.fr.design.event.HoverAware; import com.fr.design.gui.ibutton.UIButton; import com.fr.design.gui.ilable.UILabel; @@ -10,7 +10,6 @@ import com.fr.design.gui.itextfield.UITextField; import javax.swing.BorderFactory; import javax.swing.JPanel; -import javax.swing.UIManager; import javax.swing.event.DocumentListener; import java.awt.BorderLayout; import java.awt.Insets; @@ -28,14 +27,23 @@ import java.awt.event.MouseEvent; */ public class FineSearchPane extends JPanel implements HoverAware { + private final Insets defaultLabelInsets = new Insets(3, 6, 3, 4); + private final Insets defaultButtonInsets = new Insets(4, 4, 4, 4); private UITextField searchTextField; private UIButton clearButton; + + private static final String UI_CLASS_ID = "InputUI"; + + @Override + public String getUIClassID() { + return UI_CLASS_ID; + } + private boolean hover; public FineSearchPane() { this.setLayout(new BorderLayout()); - this.setUI(new FineInputUI(false)); initComponents(); } @@ -43,9 +51,8 @@ public class FineSearchPane extends JPanel implements HoverAware { private void initComponents() { // 左侧搜索图标 UILabel searchLabel = new UILabel(new LazyIcon("search")); - Insets labelInsets = UIManager.getInsets("SearchPanel.labelBorderInsets"); - Insets scaledInsets = FineUIScale.scale(labelInsets); - searchLabel.setBorder(BorderFactory.createEmptyBorder(scaledInsets.top, scaledInsets.left, scaledInsets.bottom, scaledInsets.right)); + Insets labelInsets = FineUIUtils.getAndScaleUIInsets("SearchPanel.labelBorderInsets", defaultLabelInsets); + searchLabel.setBorder(BorderFactory.createEmptyBorder(labelInsets.top, labelInsets.left, labelInsets.bottom, labelInsets.right)); // 中间输入框 searchTextField = new UITextField(); @@ -68,9 +75,8 @@ public class FineSearchPane extends JPanel implements HoverAware { // 右侧返回图标 clearButton = new UIButton(new LazyIcon("clear")); clearButton.setUI(new FineInputUI.FineInputButtonUI(false)); - Insets buttonInsets = UIManager.getInsets("SearchPanel.buttonBorderInsets"); - Insets buttonScaledInsets = FineUIScale.scale(buttonInsets); - clearButton.setBorder(BorderFactory.createEmptyBorder(buttonScaledInsets.top, buttonScaledInsets.left, buttonScaledInsets.bottom, buttonScaledInsets.right)); + Insets buttonInsets = FineUIUtils.getAndScaleUIInsets("SearchPanel.buttonBorderInsets", defaultButtonInsets); + clearButton.setBorder(BorderFactory.createEmptyBorder(buttonInsets.top, buttonInsets.left, buttonInsets.bottom, buttonInsets.right)); this.add(searchLabel, BorderLayout.WEST); this.add(searchTextField, BorderLayout.CENTER); diff --git a/designer-base/src/main/java/com/fr/design/foldablepane/HeaderPane.java b/designer-base/src/main/java/com/fr/design/foldablepane/HeaderPane.java index 9d53782d2..cefeda51f 100644 --- a/designer-base/src/main/java/com/fr/design/foldablepane/HeaderPane.java +++ b/designer-base/src/main/java/com/fr/design/foldablepane/HeaderPane.java @@ -2,6 +2,7 @@ package com.fr.design.foldablepane; import com.fine.theme.icon.LazyIcon; import com.fine.theme.utils.FineUIScale; +import com.fine.theme.utils.FineUIUtils; import com.fr.base.GraphHelper; import javax.swing.BorderFactory; @@ -24,6 +25,9 @@ import java.awt.Insets; */ public class HeaderPane extends JPanel { private static final long serialVersionUID = 1L; + private final Insets defaultInsets = new Insets(0, 6, 0, 6); + private final int defaultWidth = 248; + private final int defaultHeight = 24; private int headWidth; private int headHeight; private Color bgColor; @@ -88,12 +92,13 @@ public class HeaderPane extends JPanel { this.isShow = true; triangleDown = new LazyIcon("triangle_down"); triangleRight = new LazyIcon("triangle_right"); - this.setPreferredSize(FineUIScale.scale(new Dimension(UIManager.getInt("HeaderPane.width"), UIManager.getInt("HeaderPane.height")))); - Insets insets = UIManager.getInsets("ExpandablePane.HeaderPane.borderInsets"); - Insets scaledInsets = FineUIScale.scale(insets); + int width = FineUIUtils.getAndScaleInt("HeaderPane.width", defaultWidth); + int height = FineUIUtils.getAndScaleInt("HeaderPane.height", defaultHeight); + this.setPreferredSize(new Dimension(width, height)); + Insets insets = FineUIUtils.getAndScaleUIInsets("ExpandablePane.HeaderPane.borderInsets", defaultInsets); this.setForeground(UIManager.getColor("ExpandablePane.HeaderPane.foreground")); this.setFont(getFont().deriveFont(Font.BOLD)); - this.setBorder(BorderFactory.createEmptyBorder(scaledInsets.top, scaledInsets.left, scaledInsets.bottom, scaledInsets.right)); + this.setBorder(BorderFactory.createEmptyBorder(insets.top, insets.left, insets.bottom, insets.right)); } public HeaderPane(Color bgColor, String title, int headHeight) { diff --git a/designer-base/src/main/java/com/fr/design/gui/frpane/UINumberDragPane.java b/designer-base/src/main/java/com/fr/design/gui/frpane/UINumberDragPane.java index 731402572..99bc1205a 100644 --- a/designer-base/src/main/java/com/fr/design/gui/frpane/UINumberDragPane.java +++ b/designer-base/src/main/java/com/fr/design/gui/frpane/UINumberDragPane.java @@ -3,8 +3,8 @@ package com.fr.design.gui.frpane; import com.fr.design.beans.BasicBeanPane; import com.fr.design.event.GlobalNameListener; import com.fr.design.event.GlobalNameObserver; +import com.fr.design.gui.islider.UISlider; import com.fr.design.gui.ispinner.UISpinner; -import com.fr.design.gui.style.NumberDragBar; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; @@ -14,7 +14,7 @@ import java.awt.Dimension; public class UINumberDragPane extends BasicBeanPane implements GlobalNameObserver { private static final long serialVersionUID = -8681716725163358249L; - private NumberDragBar dragBar; + private UISlider dragBar; private UISpinner spinner; private boolean isEditing = false; private String numberDargPaneName = ""; @@ -33,7 +33,9 @@ public class UINumberDragPane extends BasicBeanPane implements GlobalNam } public UINumberDragPane(double minValue, double maxValue, double dierta) { - dragBar = new NumberDragBar((int) minValue, (int) maxValue); + dragBar = new UISlider((int) minValue, (int) maxValue); + dragBar.setPaintLabels(true); + dragBar.setMajorTickSpacing((int) maxValue); spinner = createUISpinner(minValue, maxValue, dierta); spinner.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_StyleAlignment_Text_Rotation")); this.setLayout(new BorderLayout(4, 0)); diff --git a/designer-base/src/main/java/com/fr/design/gui/ispinner/UISpinner.java b/designer-base/src/main/java/com/fr/design/gui/ispinner/UISpinner.java index b956dbf5e..08ef5d810 100644 --- a/designer-base/src/main/java/com/fr/design/gui/ispinner/UISpinner.java +++ b/designer-base/src/main/java/com/fr/design/gui/ispinner/UISpinner.java @@ -3,6 +3,7 @@ package com.fr.design.gui.ispinner; import com.fine.theme.icon.LazyIcon; import com.fine.theme.light.ui.FineInputUI; import com.fine.theme.utils.FineUIScale; +import com.fine.theme.utils.FineUIUtils; import com.fr.design.event.GlobalNameListener; import com.fr.design.event.GlobalNameObserver; import com.fr.design.event.HoverAware; @@ -44,6 +45,8 @@ import java.awt.event.MouseWheelListener; */ public class UISpinner extends JPanel implements UIObserver, GlobalNameObserver, HoverAware { + private final Insets defaultInsets = new Insets(0, 6, 0, 6); + private final int defaultButtonSize = 24; protected double value; private static final int DEFAULT_NUMBERFIELD_COLUMNS = 2; private UINumberField textField; @@ -64,6 +67,13 @@ public class UISpinner extends JPanel implements UIObserver, GlobalNameObserver, private boolean hover; + private static final String UI_CLASS_ID = "InputUI"; + + @Override + public String getUIClassID() { + return UI_CLASS_ID; + } + public UISpinner() { } @@ -89,7 +99,6 @@ public class UISpinner extends JPanel implements UIObserver, GlobalNameObserver, this.dierta = dierta; initComponents(); iniListener(); - setUI(FineInputUI.createUI(this)); } private void iniListener() { @@ -272,6 +281,10 @@ public class UISpinner extends JPanel implements UIObserver, GlobalNameObserver, textField = initNumberField(); textField.setMaxValue(maxValue); textField.setMinValue(minValue); + Insets insets = FineUIUtils.getAndScaleUIInsets("InputTextField.borderInsets", defaultInsets); + textField.setBorder(BorderFactory.createEmptyBorder(insets.top, insets.left, insets.bottom, insets.right)); + textField.setOpaque(false); + setValue(value); preButton = createArrowButton(new LazyIcon("up_arrow_12")); nextButton = createArrowButton(new LazyIcon("down_arrow_12")); @@ -283,9 +296,9 @@ public class UISpinner extends JPanel implements UIObserver, GlobalNameObserver, arrowPane.add(nextButton); arrowPane.setOpaque(false); - int buttonWidth = UIManager.getInt("InputButton.width"); - int buttonHeight = UIManager.getInt("InputButton.height"); - arrowPane.setPreferredSize(FineUIScale.scale(new Dimension(buttonWidth, buttonHeight))); + int buttonWidth = FineUIUtils.getAndScaleInt("InputButton.width", defaultButtonSize); + int buttonHeight = FineUIUtils.getAndScaleInt("InputButton.height", defaultButtonSize); + arrowPane.setPreferredSize(new Dimension(buttonWidth, buttonHeight)); add(arrowPane, BorderLayout.EAST); componentInitListeners(); } @@ -370,10 +383,6 @@ public class UISpinner extends JPanel implements UIObserver, GlobalNameObserver, return false; } }; - Insets insets = UIManager.getInsets("InputTextField.borderInsets"); - Insets scaledInsets = FineUIScale.scale(insets); - numberField.setBorder(BorderFactory.createEmptyBorder(scaledInsets.top, scaledInsets.left, scaledInsets.bottom, scaledInsets.right)); - numberField.setOpaque(false); return numberField; } diff --git a/designer-base/src/main/java/com/fr/design/gui/itextfield/UITextField.java b/designer-base/src/main/java/com/fr/design/gui/itextfield/UITextField.java index 7c3376823..b7bb6a545 100644 --- a/designer-base/src/main/java/com/fr/design/gui/itextfield/UITextField.java +++ b/designer-base/src/main/java/com/fr/design/gui/itextfield/UITextField.java @@ -1,6 +1,6 @@ package com.fr.design.gui.itextfield; -import com.fine.theme.utils.FineUIScale; +import com.fine.theme.utils.FineUIUtils; import com.fr.common.inputevent.InputEventBaseOnOS; import com.fr.design.event.GlobalNameListener; import com.fr.design.event.GlobalNameObserver; @@ -14,7 +14,6 @@ import com.fr.stable.StringUtils; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JTextField; -import javax.swing.UIManager; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.text.Document; @@ -33,6 +32,7 @@ import java.awt.event.MouseEvent; * @since xxx */ public class UITextField extends JTextField implements UIObserver, GlobalNameObserver, HoverAware { + private final int defaultHeight = 24; private boolean isBorderPainted = true; private boolean isRoundBorder = true; private int rectDirection = Constants.NULL; @@ -243,6 +243,6 @@ public class UITextField extends JTextField implements UIObserver, GlobalNameObs @Override public Dimension getPreferredSize() { - return new Dimension(super.getPreferredSize().width, FineUIScale.scale(UIManager.getInt("Input.height"))); + return new Dimension(super.getPreferredSize().width, FineUIUtils.getAndScaleInt("Input.height", defaultHeight)); } } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/EastRegionContainerPane.java b/designer-base/src/main/java/com/fr/design/mainframe/EastRegionContainerPane.java index 1f489489d..14a8f216f 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/EastRegionContainerPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/EastRegionContainerPane.java @@ -3,6 +3,7 @@ package com.fr.design.mainframe; import com.fine.theme.icon.LazyIcon; import com.fine.theme.light.ui.RectangleButtonUI; import com.fine.theme.utils.FineUIScale; +import com.fine.theme.utils.FineUIUtils; import com.formdev.flatlaf.FlatDarkLaf; import com.formdev.flatlaf.ui.FlatLineBorder; import com.fr.base.FRContext; @@ -1171,6 +1172,7 @@ public class EastRegionContainerPane extends UIEastResizableContainer { // 弹出属性面板的工具条 private class PopupToolPane extends JPanel { private final UIButton popupButton; + private final Insets defaultInsets = new Insets(0, 10, 0, 10); private String title; private PropertyItem propertyItem; private String buttonType; @@ -1263,9 +1265,8 @@ public class EastRegionContainerPane extends UIEastResizableContainer { popupButton = createPopupButton(buttonType); contentPane.add(popupButton, BorderLayout.EAST); - Insets insets = UIManager.getInsets("PopupToolPane.borderInsets"); - Insets scaledInsets = FineUIScale.scale(insets); - contentPane.setBorder(new EmptyBorder(scaledInsets.top, scaledInsets.left, scaledInsets.bottom, scaledInsets.right)); + Insets insets = FineUIUtils.getAndScaleUIInsets("PopupToolPane.borderInsets", defaultInsets); + contentPane.setBorder(new EmptyBorder(insets.top, insets.left, insets.bottom, insets.right)); setLayout(new BorderLayout()); add(contentPane, BorderLayout.CENTER); diff --git a/designer-base/src/main/java/com/fr/design/mainframe/widget/accessibles/BaseAccessibleEditor.java b/designer-base/src/main/java/com/fr/design/mainframe/widget/accessibles/BaseAccessibleEditor.java index 9c8c8e2a5..99a1dc1f6 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/widget/accessibles/BaseAccessibleEditor.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/widget/accessibles/BaseAccessibleEditor.java @@ -3,6 +3,7 @@ package com.fr.design.mainframe.widget.accessibles; import com.fine.theme.icon.LazyIcon; import com.fine.theme.light.ui.FineInputUI; import com.fine.theme.utils.FineUIScale; +import com.fine.theme.utils.FineUIUtils; import com.fr.design.Exception.ValidationException; import com.fr.design.designer.properties.Decoder; import com.fr.design.designer.properties.Encoder; @@ -39,6 +40,7 @@ import java.util.ArrayList; */ public class BaseAccessibleEditor extends BasicPane implements AccessibleEditor, HoverAware { + private final Insets defaultInsets = new Insets(0, 6, 0, 6); private ArrayList listeners; private boolean showButton; protected Encoder encoder; @@ -47,6 +49,13 @@ public class BaseAccessibleEditor extends BasicPane implements AccessibleEditor, protected ITextComponent txtValue; private boolean hover; + private static final String UI_CLASS_ID = "InputUI"; + + @Override + public String getUIClassID() { + return UI_CLASS_ID; + } + public BaseAccessibleEditor(Encoder enc, Decoder dec, boolean showBtn) { listeners = new ArrayList(); this.showButton = showBtn; @@ -56,12 +65,8 @@ public class BaseAccessibleEditor extends BasicPane implements AccessibleEditor, initListener(); txtValue.setEditable(dec != null); ((JComponent) txtValue).setOpaque(false); - Insets insets = UIManager.getInsets("InputTextField.borderInsets"); - Insets scaledInsets = FineUIScale.scale(insets); - ((JComponent) txtValue).setBorder(BorderFactory.createEmptyBorder(scaledInsets.top, scaledInsets.left, scaledInsets.bottom, scaledInsets.right)); - - this.setUI(FineInputUI.createUI(this)); - setPreferredSize(new Dimension(getPreferredSize().width, FineUIScale.scale(UIManager.getInt("Input.height")))); + Insets insets = FineUIUtils.getAndScaleUIInsets("InputTextField.borderInsets", defaultInsets); + ((JComponent) txtValue).setBorder(BorderFactory.createEmptyBorder(insets.top, insets.left, insets.bottom, insets.right)); } private void initListener() { diff --git a/designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLaf.properties b/designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLaf.properties index 5e1601c8f..adb218b4a 100644 --- a/designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLaf.properties +++ b/designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLaf.properties @@ -46,4 +46,5 @@ ViewportUI=com.formdev.flatlaf.ui.FlatViewportUI HeadGroupUI=com.fine.theme.light.ui.FineHeadGroupUI ButtonGroupUI= com.fine.theme.light.ui.FineButtonGroupUI SelectBoxUI= com.fine.theme.light.ui.FineSelectBoxUI +InputUI=com.fine.theme.light.ui.FineInputUI GradientBarUI=com.fine.theme.light.ui.FineGradientBarUI \ No newline at end of file From db8656de54f873fd08ebc512809d926c3f75ad4b Mon Sep 17 00:00:00 2001 From: "Leo.Qin" Date: Wed, 27 Dec 2023 10:24:12 +0800 Subject: [PATCH 5/5] =?UTF-8?q?REPORT-107973=20=E6=B7=BB=E5=8A=A0=E6=B3=A8?= =?UTF-8?q?=E9=87=8A=E3=80=81=E6=A0=BC=E5=BC=8F=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/fine/theme/light/ui/laf/FineLaf.java | 2 ++ .../com/fr/design/style/background/gradient/GradientBar.java | 1 + 2 files changed, 3 insertions(+) diff --git a/designer-base/src/main/java/com/fine/theme/light/ui/laf/FineLaf.java b/designer-base/src/main/java/com/fine/theme/light/ui/laf/FineLaf.java index 079d013d6..7ab6d6c72 100644 --- a/designer-base/src/main/java/com/fine/theme/light/ui/laf/FineLaf.java +++ b/designer-base/src/main/java/com/fine/theme/light/ui/laf/FineLaf.java @@ -31,6 +31,8 @@ public abstract class FineLaf extends FlatLaf { @Override public void initialize() { super.initialize(); + // flat默认使用系统弹窗,3.3 版本之前无法实现圆角弹窗。 + // popup弹窗不使用flat提供的工具,使用swing原生自带的 PopupFactory.setSharedInstance(new PopupFactory()); } } diff --git a/designer-base/src/main/java/com/fr/design/style/background/gradient/GradientBar.java b/designer-base/src/main/java/com/fr/design/style/background/gradient/GradientBar.java index d62199b04..1540191df 100644 --- a/designer-base/src/main/java/com/fr/design/style/background/gradient/GradientBar.java +++ b/designer-base/src/main/java/com/fr/design/style/background/gradient/GradientBar.java @@ -24,6 +24,7 @@ import java.util.List; /** * 渐变色滑块 + * * @since 11.0 * Create on 2023/12/27. */