From 7ac0d7deae64a043dcce0fe68205b5786c2e0644 Mon Sep 17 00:00:00 2001 From: vito Date: Fri, 15 Dec 2023 18:17:14 +0800 Subject: [PATCH] =?UTF-8?q?REPORT-99485=20fix:UIHeadGroup=E5=9C=A8?= =?UTF-8?q?=E5=88=87=E6=8D=A2=E4=B8=BB=E9=A2=98=E6=97=B6=E6=97=A0=E6=B3=95?= =?UTF-8?q?=E5=BA=94=E7=94=A8UI=20new:=20storybook=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E6=90=9C=E7=B4=A2=E6=95=85=E4=BA=8B=20fix:=20button=E6=94=BE?= =?UTF-8?q?=E5=BC=80=E9=AB=98=E5=BA=A6=E9=99=90=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fine/theme/light/ui/FineHeadGroupUI.java | 69 ++++++++++++ .../com/fr/design/gui/ibutton/UIButton.java | 45 ++++---- .../fr/design/gui/ibutton/UIHeadGroup.java | 70 +++--------- .../light/ui/laf/FineLightLaf.properties | 1 + .../com/fr/design/gui/storybook/Story.java | 19 ++++ .../gui/storybook/StoryBookComponent.java | 10 +- .../fr/design/gui/storybook/Storybook.java | 101 ++++++++++++------ .../components/ButtonStoryBoard.java | 2 + .../components/ButtonTabStoryBoard.java | 2 + .../components/CheckBoxStoryBoard.java | 9 +- 10 files changed, 210 insertions(+), 118 deletions(-) create mode 100644 designer-base/src/main/java/com/fine/theme/light/ui/FineHeadGroupUI.java create mode 100644 designer-base/src/test/java/com/fr/design/gui/storybook/Story.java diff --git a/designer-base/src/main/java/com/fine/theme/light/ui/FineHeadGroupUI.java b/designer-base/src/main/java/com/fine/theme/light/ui/FineHeadGroupUI.java new file mode 100644 index 0000000000..6b2289f0c6 --- /dev/null +++ b/designer-base/src/main/java/com/fine/theme/light/ui/FineHeadGroupUI.java @@ -0,0 +1,69 @@ +package com.fine.theme.light.ui; + +import com.fine.theme.utils.FineUIUtils; +import com.formdev.flatlaf.ui.FlatUIUtils; + +import javax.swing.JComponent; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.PanelUI; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; + +import static com.formdev.flatlaf.ui.FlatStylingSupport.Styleable; + +/** + * HeadGroup 的UI类 + * + * @author vito + * @since 11.0 + * Created on 2023/12/15 + */ +public class FineHeadGroupUI extends PanelUI { + + @Styleable(dot = true) + protected Color background; + + @Styleable(dot = true) + protected int arc; + + @SuppressWarnings({"MethodOverridesStaticMethodOfSuperclass", "UnusedDeclaration"}) + public static ComponentUI createUI(JComponent c) { + return new FineHeadGroupUI(); + } + + @Override + public void installUI(JComponent c) { + super.installUI(c); + background = FineUIUtils.getUIColor("HeadGroup.background", "desktop"); + arc = FineUIUtils.getUIInt("HeadGroup.arc", "Component.arc"); + } + + + @Override + public void uninstallUI(JComponent c) { + super.uninstallUI(c); + } + + @Override + public Dimension getMinimumSize(JComponent component) { + return new Dimension(0, 0); + } + + @Override + public Dimension getMaximumSize(JComponent component) { + return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE); + } + + @Override + public void update(Graphics g, JComponent c) { + paintBackground(g, c); + paint(g, c); + } + + protected void paintBackground(Graphics g, JComponent c) { + FlatUIUtils.setRenderingHints(g); + g.setColor(background); + g.fillRoundRect(0, 0, c.getWidth(), c.getHeight(), arc, arc); + } +} diff --git a/designer-base/src/main/java/com/fr/design/gui/ibutton/UIButton.java b/designer-base/src/main/java/com/fr/design/gui/ibutton/UIButton.java index f6c37d815a..8a64e7e687 100644 --- a/designer-base/src/main/java/com/fr/design/gui/ibutton/UIButton.java +++ b/designer-base/src/main/java/com/fr/design/gui/ibutton/UIButton.java @@ -64,15 +64,6 @@ public class UIButton extends JButton implements UIObserver, UITextComponent { init(); } - public UIButton(Icon icon, boolean decorate) { - this(icon); - if (!decorate) { - setContentAreaFilled(false); - setFocusPainted(false); - setBorderPainted(false); - } - } - public UIButton(Icon icon) { super(icon); if (icon instanceof LazyIcon) { @@ -107,7 +98,7 @@ public class UIButton extends JButton implements UIObserver, UITextComponent { setPressedIcon(pressed); setExtraPainted(false); setBackground(null); - setForeground(UIConstants.FONT_COLOR); +// setForeground(UIConstants.FONT_COLOR); setOpaque(false); initListener(); } @@ -148,7 +139,7 @@ public class UIButton extends JButton implements UIObserver, UITextComponent { public void set4ToolbarButton() { setNormalPainted(false); Dimension dim = getPreferredSize(); - dim.height = HEIGHT; +// dim.height = HEIGHT; setBackground(null); setOpaque(false); setSize(dim); @@ -159,6 +150,7 @@ public class UIButton extends JButton implements UIObserver, UITextComponent { setNormalPainted(false); setBackground(null); setOpaque(false); + setBorderPainted(false); setSize(new Dimension(40, 40)); setBorderPaintedOnlyWhenPressed(true); } @@ -167,6 +159,7 @@ public class UIButton extends JButton implements UIObserver, UITextComponent { setNormalPainted(false); setBackground(null); setOpaque(false); + setSize(new Dimension(34, 44)); setBorderPaintedOnlyWhenPressed(true); } @@ -193,13 +186,13 @@ public class UIButton extends JButton implements UIObserver, UITextComponent { // } //@Override - public Dimension getPreferredSize() { - Dimension dim = super.getPreferredSize(); - if (isFixedHeight() || dim.height < HEIGHT) { - dim.height = HEIGHT; - } - return dim; - } +// public Dimension getPreferredSize() { +// Dimension dim = super.getPreferredSize(); +// if (isFixedHeight() || dim.height < HEIGHT) { +// dim.height = HEIGHT; +// } +// return dim; +// } public int getBorderType() { @@ -331,14 +324,14 @@ public class UIButton extends JButton implements UIObserver, UITextComponent { this.isBorderPaintedOnlyWhenPressed = value; } - private boolean isFixedHeight() { - String text = this.getText(); - if (StringUtils.isEmpty(text)) { - return true; - } - // 如果允许换行,需要放开按钮高度的限制 - return !text.startsWith(""); - } +// private boolean isFixedHeight() { +// String text = this.getText(); +// if (StringUtils.isEmpty(text)) { +// return true; +// } +// // 如果允许换行,需要放开按钮高度的限制 +// return !text.startsWith(""); +// } /** * 主函数 diff --git a/designer-base/src/main/java/com/fr/design/gui/ibutton/UIHeadGroup.java b/designer-base/src/main/java/com/fr/design/gui/ibutton/UIHeadGroup.java index f5560810ec..b72bbf1dab 100644 --- a/designer-base/src/main/java/com/fr/design/gui/ibutton/UIHeadGroup.java +++ b/designer-base/src/main/java/com/fr/design/gui/ibutton/UIHeadGroup.java @@ -2,9 +2,6 @@ package com.fr.design.gui.ibutton; import com.fine.swing.ui.layout.Layouts; import com.fine.swing.ui.layout.Row; -import com.fine.theme.utils.FineUIUtils; -import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable; -import com.formdev.flatlaf.ui.FlatUIUtils; import com.formdev.flatlaf.util.ScaledEmptyBorder; import com.fr.third.guava.collect.Streams; @@ -13,11 +10,8 @@ import javax.swing.ButtonGroup; import javax.swing.Icon; import javax.swing.JComponent; import javax.swing.JToggleButton; +import javax.swing.UIDefaults; import javax.swing.event.ChangeListener; -import javax.swing.plaf.ComponentUI; -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -36,7 +30,7 @@ import static com.formdev.flatlaf.FlatClientProperties.BUTTON_TYPE_TAB; */ public class UIHeadGroup extends Row { - + private static final String uiClassID = "HeadGroupUI"; private UIHeadGroupSingleSelectionModel model; private List btns; @@ -60,11 +54,21 @@ public class UIHeadGroup extends Row { intiContent(); } + /** + * Returns the name of the L&F class that renders this component. + * + * @return the string "ToolTipUI" + * @see JComponent#getUIClassID + * @see UIDefaults#getUI + */ + public String getUIClassID() { + return uiClassID; + } + private void intiContent() { setSpacing(2); setOpaque(false); add(buttonGroup()); - setUI(new UIHeadGroupUI()); setSelectedIndex(0); setBorder(new ScaledEmptyBorder(2, 2, 2, 2)); } @@ -97,54 +101,6 @@ public class UIHeadGroup extends Row { // do nothing } - private static class UIHeadGroupUI extends ComponentUI { - - @Styleable(dot = true) - protected Color background; - - @Styleable(dot = true) - protected int arc; - - @SuppressWarnings({"MethodOverridesStaticMethodOfSuperclass", "UnusedDeclaration"}) - public static ComponentUI createUI(JComponent c) { - return new UIHeadGroupUI(); - } - - @Override - public void installUI(JComponent c) { - super.installUI(c); - background = FineUIUtils.getUIColor("HeadGroup.background", "desktop"); - arc = FineUIUtils.getUIInt("HeadGroup.arc", "Component.arc"); - } - - @Override - public void uninstallUI(JComponent c) { - super.uninstallUI(c); - } - - @Override - public Dimension getMinimumSize(JComponent component) { - return new Dimension(0, 0); - } - - @Override - public Dimension getMaximumSize(JComponent component) { - return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE); - } - - @Override - public void update(Graphics g, JComponent c) { - paintBackground(g, c); - paint(g, c); - } - - protected void paintBackground(Graphics g, JComponent c) { - FlatUIUtils.setRenderingHints(g); - g.setColor(background); - g.fillRoundRect(0, 0, c.getWidth(), c.getHeight(), arc, arc); - } - } - private UIHeadGroupSingleSelectionModel getModel() { return model; } 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 ccfdeed071..bd35cf06e7 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 @@ -86,6 +86,7 @@ ToolBarSeparatorUI = com.formdev.flatlaf.ui.FlatToolBarSeparatorUI ToolTipUI=com.fine.theme.light.ui.FineTooltipUI TreeUI = com.fine.theme.light.ui.UIFlatTreeUI ViewportUI = com.formdev.flatlaf.ui.FlatViewportUI +HeadGroupUI=com.fine.theme.light.ui.FineHeadGroupUI #---- variables ---- diff --git a/designer-base/src/test/java/com/fr/design/gui/storybook/Story.java b/designer-base/src/test/java/com/fr/design/gui/storybook/Story.java new file mode 100644 index 0000000000..5e18f2bd9c --- /dev/null +++ b/designer-base/src/test/java/com/fr/design/gui/storybook/Story.java @@ -0,0 +1,19 @@ +package com.fr.design.gui.storybook; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * @author vito + * @since 11.0 + * Created on 2023/12/15 + */ + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +@Inherited +public @interface Story { +} diff --git a/designer-base/src/test/java/com/fr/design/gui/storybook/StoryBookComponent.java b/designer-base/src/test/java/com/fr/design/gui/storybook/StoryBookComponent.java index 8926899aea..da0a797db9 100644 --- a/designer-base/src/test/java/com/fr/design/gui/storybook/StoryBookComponent.java +++ b/designer-base/src/test/java/com/fr/design/gui/storybook/StoryBookComponent.java @@ -9,10 +9,16 @@ import javax.swing.JComponent; */ public class StoryBookComponent { public String name; - public JComponent component; + public String className; + public Class component; - public StoryBookComponent(String name, JComponent component) { + public StoryBookComponent(String name, Class component) { this.name = name; this.component = component; } + + public StoryBookComponent(String name, String className) { + this.name = name; + this.className = className; + } } diff --git a/designer-base/src/test/java/com/fr/design/gui/storybook/Storybook.java b/designer-base/src/test/java/com/fr/design/gui/storybook/Storybook.java index 6517967adc..7ae6be93c0 100644 --- a/designer-base/src/test/java/com/fr/design/gui/storybook/Storybook.java +++ b/designer-base/src/test/java/com/fr/design/gui/storybook/Storybook.java @@ -2,26 +2,17 @@ package com.fr.design.gui.storybook; import com.fanruan.gui.UiInspector; import com.fine.theme.light.ui.laf.FineLightLaf; +import com.finebi.cbb.utils.StringUtils; import com.formdev.flatlaf.FlatDarkLaf; import com.formdev.flatlaf.FlatLaf; import com.formdev.flatlaf.FlatLightLaf; import com.formdev.flatlaf.extras.FlatAnimatedLafChange; import com.formdev.flatlaf.util.ScaledEmptyBorder; import com.fr.design.gui.UILookAndFeel; -import com.fr.design.gui.storybook.components.ButtonStoryBoard; -import com.fr.design.gui.storybook.components.ButtonTabStoryBoard; -import com.fr.design.gui.storybook.components.CheckBoxStoryBoard; -import com.fr.design.gui.storybook.components.ComboBoxStoryBoard; -import com.fr.design.gui.storybook.components.EastRegionContainer; -import com.fr.design.gui.storybook.components.ExpandablePaneStoryBoard; -import com.fr.design.gui.storybook.components.InputStoryBoard; -import com.fr.design.gui.storybook.components.RadioButtonStoryBoard; -import com.fr.design.gui.storybook.components.SliderStoryBoard; -import com.fr.design.gui.storybook.components.ToggleButtonStoryBoard; -import com.fr.design.gui.storybook.components.ToolTipStoryBoard; -import com.fr.design.gui.storybook.components.UIHeadGroupStoryBoard; +import com.fr.value.NotNullLazyValue; import javax.swing.DefaultListCellRenderer; +import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JList; import javax.swing.JMenu; @@ -38,7 +29,12 @@ import java.awt.BorderLayout; import java.awt.Component; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; +import java.io.File; +import java.net.URISyntaxException; +import java.net.URL; import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; import static com.fine.swing.ui.layout.Layouts.cell; import static com.fine.swing.ui.layout.Layouts.row; @@ -53,21 +49,26 @@ import static com.fine.theme.utils.FineUIScale.scale; * Created on 2023/11/27 */ public class Storybook { + public static final String COMPONENTS_DIR = "/com/fr/design/gui/storybook/components"; + public static final String COMPONENTS_PACKAGE = COMPONENTS_DIR.substring(1) + .replaceAll("/", ".") + "."; - JPanel cards; + private final NotNullLazyValue StoryBookComponent = NotNullLazyValue.createValue(this::components); + + private JPanel cards; + private JFrame jf; public void start() { FineLightLaf.setup(); - JFrame jf = new JFrame("Story Book"); + jf = new JFrame("Story Book"); jf.setJMenuBar(initMenu()); jf.add(row( - cell(new JList<>(components())).with(it -> { + cell(new JList<>(StoryBookComponent.getValue())).with(it -> { it.setBorder(new ScaledEmptyBorder(10, 10, 10, 10)); it.setCellRenderer(new MyListCellRenderer()); it.addListSelectionListener(e -> { - StoryBookComponent[] cs = components(); cards.removeAll(); - cards.add(cs[it.getSelectedIndex()].component); + cards.add(newPanel(StoryBookComponent.getValue()[it.getSelectedIndex()])); cards.revalidate(); }); }), @@ -75,7 +76,7 @@ public class Storybook { cards = new JPanel(new BorderLayout()); it.setViewportView(cards); cards.setBorder(new ScaledEmptyBorder(10, 10, 10, 10)); - cards.add(components()[0].component); + cards.add(newPanel(StoryBookComponent.getValue()[0])); }) ).getComponent()); jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); @@ -84,6 +85,17 @@ public class Storybook { jf.setVisible(true); } + private JComponent newPanel(StoryBookComponent storyBookComponent) { + try { + if (StringUtils.isNotBlank(storyBookComponent.className)) { + return (JComponent) Class.forName(storyBookComponent.className).newInstance(); + } else { + return storyBookComponent.component.newInstance(); + } + } catch (InstantiationException | IllegalAccessException | ClassNotFoundException ex) { + throw new RuntimeException(ex); + } + } static class MyListCellRenderer extends DefaultListCellRenderer { @Override @@ -96,21 +108,47 @@ public class Storybook { private StoryBookComponent[] components() { ArrayList components = new ArrayList<>(); - components.add(new StoryBookComponent("Button", new ButtonStoryBoard())); - components.add(new StoryBookComponent("HeadGroup", new UIHeadGroupStoryBoard())); - components.add(new StoryBookComponent("ToggleButton", new ToggleButtonStoryBoard())); - components.add(new StoryBookComponent("EastRegionContainer", new EastRegionContainer())); - components.add(new StoryBookComponent("ButtonTabGroup", new ButtonTabStoryBoard())); - components.add(new StoryBookComponent("CheckBox", new CheckBoxStoryBoard())); - components.add(new StoryBookComponent("ComboBox", new ComboBoxStoryBoard())); - components.add(new StoryBookComponent("RadioButton", new RadioButtonStoryBoard())); - components.add(new StoryBookComponent("Input", new InputStoryBoard())); - components.add(new StoryBookComponent("Slider", new SliderStoryBoard())); - components.add(new StoryBookComponent("ToolTip", new ToolTipStoryBoard())); - components.add(new StoryBookComponent("ExpandblePane", new ExpandablePaneStoryBoard())); + for (String s : getClasses()) { + components.add(new StoryBookComponent(s.replace("StoryBoard", ""), COMPONENTS_PACKAGE + s)); + } + return components.toArray(new StoryBookComponent[0]); } + private static List getClasses() { + List classNames = new ArrayList<>(); + URL resource = Storybook.class.getResource(COMPONENTS_DIR); + try { + File folder = new File(resource.toURI()); + File[] files = folder.listFiles(); + if (files != null) { + for (File file : files) { + if (file.isFile() && file.getName().endsWith(".class")) { + String className = file.getName().replace(".class", ""); + if (isStory(className)) { + classNames.add(className); + } + } + } + } + return classNames.stream().sorted().collect(Collectors.toList()); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + } + + /** + * 标记Story注解或者继承自StoryBoard的将展示到Storybook + */ + private static boolean isStory(String className) { + try { + Class aClass = Class.forName(COMPONENTS_PACKAGE + className); + return aClass.isAnnotationPresent(Story.class) || StoryBoard.class.isAssignableFrom(aClass); + } catch (ClassNotFoundException e) { + return false; + } + } + /** * 应用主题 */ @@ -134,6 +172,7 @@ public class Storybook { FineLightLaf.setup(); FlatLaf.updateUI(); FlatAnimatedLafChange.hideSnapshotWithAnimation(); + jf.setSize(scale(600), scale(400)); } /** @@ -207,7 +246,7 @@ public class Storybook { } - public static void main(String... args) { + public static void main(String... args) throws URISyntaxException { SwingUtilities.invokeLater(() -> new Storybook().start()); } diff --git a/designer-base/src/test/java/com/fr/design/gui/storybook/components/ButtonStoryBoard.java b/designer-base/src/test/java/com/fr/design/gui/storybook/components/ButtonStoryBoard.java index 86937b0441..bc157a2f57 100644 --- a/designer-base/src/test/java/com/fr/design/gui/storybook/components/ButtonStoryBoard.java +++ b/designer-base/src/test/java/com/fr/design/gui/storybook/components/ButtonStoryBoard.java @@ -2,6 +2,7 @@ package com.fr.design.gui.storybook.components; import com.fine.theme.icon.LazyIcon; import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.storybook.Story; import com.fr.design.gui.storybook.StoryBoard; import javax.swing.JButton; @@ -17,6 +18,7 @@ import static com.fine.swing.ui.layout.Layouts.row; * @since 11.0 * Created on 2023/11/27 */ +@Story public class ButtonStoryBoard extends StoryBoard { public ButtonStoryBoard() { diff --git a/designer-base/src/test/java/com/fr/design/gui/storybook/components/ButtonTabStoryBoard.java b/designer-base/src/test/java/com/fr/design/gui/storybook/components/ButtonTabStoryBoard.java index abfb4d7659..8f9fe8bdbe 100644 --- a/designer-base/src/test/java/com/fr/design/gui/storybook/components/ButtonTabStoryBoard.java +++ b/designer-base/src/test/java/com/fr/design/gui/storybook/components/ButtonTabStoryBoard.java @@ -4,6 +4,7 @@ import com.fine.theme.icon.LazyIcon; import com.fr.design.gui.ibutton.UIButtonGroup; import com.fr.design.gui.ibutton.UITabGroup; import com.fr.design.gui.ilable.UILabel; +import com.fr.design.gui.storybook.Story; import com.fr.design.gui.storybook.StoryBoard; import com.fr.stable.ArrayUtils; @@ -19,6 +20,7 @@ import static com.fine.swing.ui.layout.Layouts.flex; * @since 11.0 * Created on 2023/12/14 */ +@Story public class ButtonTabStoryBoard extends StoryBoard { public ButtonTabStoryBoard() { super("切换按钮组"); diff --git a/designer-base/src/test/java/com/fr/design/gui/storybook/components/CheckBoxStoryBoard.java b/designer-base/src/test/java/com/fr/design/gui/storybook/components/CheckBoxStoryBoard.java index 0e86de2e65..0ea08447b3 100644 --- a/designer-base/src/test/java/com/fr/design/gui/storybook/components/CheckBoxStoryBoard.java +++ b/designer-base/src/test/java/com/fr/design/gui/storybook/components/CheckBoxStoryBoard.java @@ -3,11 +3,15 @@ package com.fr.design.gui.storybook.components; import com.fr.design.gui.icheckbox.UICheckBox; import com.fr.design.gui.ilable.UILabel; +import com.fr.design.gui.storybook.Story; import com.fr.design.gui.storybook.StoryBoard; -import java.awt.*; +import java.awt.Component; -import static com.fine.swing.ui.layout.Layouts.*; +import static com.fine.swing.ui.layout.Layouts.cell; +import static com.fine.swing.ui.layout.Layouts.column; +import static com.fine.swing.ui.layout.Layouts.fix; +import static com.fine.swing.ui.layout.Layouts.flex; import static com.fine.swing.ui.layout.Layouts.row; /** @@ -17,6 +21,7 @@ import static com.fine.swing.ui.layout.Layouts.row; * @since 11.0 * Created on 2023/12/14 */ +@Story public class CheckBoxStoryBoard extends StoryBoard { public CheckBoxStoryBoard() {