Browse Source

REPORT-99485 fix:UIHeadGroup在切换主题时无法应用UI

new: storybook自动搜索故事
fix: button放开高度限制
newui
vito 12 months ago
parent
commit
7ac0d7deae
  1. 69
      designer-base/src/main/java/com/fine/theme/light/ui/FineHeadGroupUI.java
  2. 45
      designer-base/src/main/java/com/fr/design/gui/ibutton/UIButton.java
  3. 70
      designer-base/src/main/java/com/fr/design/gui/ibutton/UIHeadGroup.java
  4. 1
      designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLightLaf.properties
  5. 19
      designer-base/src/test/java/com/fr/design/gui/storybook/Story.java
  6. 10
      designer-base/src/test/java/com/fr/design/gui/storybook/StoryBookComponent.java
  7. 101
      designer-base/src/test/java/com/fr/design/gui/storybook/Storybook.java
  8. 2
      designer-base/src/test/java/com/fr/design/gui/storybook/components/ButtonStoryBoard.java
  9. 2
      designer-base/src/test/java/com/fr/design/gui/storybook/components/ButtonTabStoryBoard.java
  10. 9
      designer-base/src/test/java/com/fr/design/gui/storybook/components/CheckBoxStoryBoard.java

69
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);
}
}

45
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("<html>");
}
// private boolean isFixedHeight() {
// String text = this.getText();
// if (StringUtils.isEmpty(text)) {
// return true;
// }
// // 如果允许换行,需要放开按钮高度的限制
// return !text.startsWith("<html>");
// }
/**
* 主函数

70
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<AbstractButton> btns;
@ -60,11 +54,21 @@ public class UIHeadGroup extends Row {
intiContent();
}
/**
* Returns the name of the L&amp;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;
}

1
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 ----

19
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 {
}

10
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<? extends JComponent> component;
public StoryBookComponent(String name, JComponent component) {
public StoryBookComponent(String name, Class<? extends JComponent> component) {
this.name = name;
this.component = component;
}
public StoryBookComponent(String name, String className) {
this.name = name;
this.className = className;
}
}

101
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[]> 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<StoryBookComponent> 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<String> getClasses() {
List<String> 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());
}

2
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() {

2
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("切换按钮组");

9
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() {

Loading…
Cancel
Save