From 5b91851bc7cafee363c8021d8a00f538e1cd5431 Mon Sep 17 00:00:00 2001 From: vito Date: Thu, 28 Dec 2023 10:34:55 +0800 Subject: [PATCH] REPORT-99485 buttonui --- .../fine/theme/light/ui/FineButtonBorder.java | 42 +++ .../com/fine/theme/light/ui/FineButtonUI.java | 114 +++++++ .../light/ui/FineCombinationButtonUI.java | 88 ++++++ .../fine/theme/light/ui/FineLightIconSet.java | 1 + .../theme/utils/FineClientProperties.java | 77 +++++ .../com/fine/theme/utils/FineUIUtils.java | 130 +++++++- .../gui/ibutton/UICombinationButton.java | 286 ++++++++++-------- .../theme/light/ui/laf/FineLaf.properties | 7 +- .../light/ui/laf/FineLightLaf.properties | 123 ++++++-- .../components/ButtonStoryBoard.java | 130 +++++++- 10 files changed, 833 insertions(+), 165 deletions(-) create mode 100644 designer-base/src/main/java/com/fine/theme/light/ui/FineButtonBorder.java create mode 100644 designer-base/src/main/java/com/fine/theme/light/ui/FineButtonUI.java create mode 100644 designer-base/src/main/java/com/fine/theme/light/ui/FineCombinationButtonUI.java diff --git a/designer-base/src/main/java/com/fine/theme/light/ui/FineButtonBorder.java b/designer-base/src/main/java/com/fine/theme/light/ui/FineButtonBorder.java new file mode 100644 index 0000000000..16405a1552 --- /dev/null +++ b/designer-base/src/main/java/com/fine/theme/light/ui/FineButtonBorder.java @@ -0,0 +1,42 @@ +package com.fine.theme.light.ui; + +import com.fine.theme.utils.FineUIUtils; +import com.formdev.flatlaf.ui.FlatButtonBorder; + +import java.awt.Component; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Paint; + +import static com.fine.theme.light.ui.FineButtonUI.isPartRoundButton; + +/** + * 按钮边框 + * + * @author vito + * @since 11.0 + * Created on 2023/12/20 + */ +public class FineButtonBorder extends FlatButtonBorder { + + public FineButtonBorder() { + } + + + @Override + public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { + if (isPartRoundButton(c)) { + Graphics2D g2 = (Graphics2D) g.create(); + Paint borderPaint = getBorderColor(c); + if (borderPaint == null) { + return; + } + g2.setPaint(borderPaint); + FineUIUtils.paintPartRoundButtonBorder(c, g2, x, y, width, height, borderWidth, (float) getArc(c)); + } else { + super.paintBorder(c, g, x, y, width, height); + } + } + + +} diff --git a/designer-base/src/main/java/com/fine/theme/light/ui/FineButtonUI.java b/designer-base/src/main/java/com/fine/theme/light/ui/FineButtonUI.java new file mode 100644 index 0000000000..d5b3c17f74 --- /dev/null +++ b/designer-base/src/main/java/com/fine/theme/light/ui/FineButtonUI.java @@ -0,0 +1,114 @@ +package com.fine.theme.light.ui; + +import com.fine.theme.utils.FineClientProperties; +import com.fine.theme.utils.FineUIUtils; +import com.formdev.flatlaf.ui.FlatButtonUI; +import com.formdev.flatlaf.ui.FlatUIUtils; + +import javax.swing.AbstractButton; +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.plaf.ComponentUI; +import java.awt.Color; +import java.awt.Component; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.geom.Path2D; + +import static com.formdev.flatlaf.FlatClientProperties.BUTTON_TYPE; + +/** + * 按钮UI + * + * @author vito + * @since 11.0 + * Created on 2023/12/20 + */ +public class FineButtonUI extends FlatButtonUI { + + /** + * @param shared + * @since 2 + */ + protected FineButtonUI(boolean shared) { + super(shared); + } + + /** + * 是否左圆角矩形 + * + * @param c 组件 + * @return 是否左圆角矩形 + */ + public static boolean isLeftRoundButton(Component c) { + return c instanceof JButton + && FineClientProperties.BUTTON_TYPE_LEFT_ROUND_RECT.equals(getButtonTypeStr((JButton) c)); + } + + /** + * 是否右圆角矩形 + * + * @param c 组件 + * @return 是否右圆角矩形 + */ + public static boolean isRightRoundButton(Component c) { + return c instanceof JButton + && FineClientProperties.BUTTON_TYPE_RIGHT_ROUND_RECT.equals(getButtonTypeStr((JButton) c)); + } + + /** + * 是否部分圆角矩形 + * + * @param c 组件 + * @return 是否部分圆角矩形 + */ + public static boolean isPartRoundButton(Component c) { + return isLeftRoundButton(c) || isRightRoundButton(c); + } + + protected void paintBackground(Graphics g, JComponent c) { + if (isPartRoundButton(c)) { + Color background = getBackground(c); + if (background == null) { + return; + } + + Graphics2D g2 = (Graphics2D) g.create(); + try { + FlatUIUtils.setRenderingHints(g2); + float arc = FlatUIUtils.getBorderArc(c); + int width = c.getWidth(); + int height = c.getHeight(); + + g2.setColor(FlatUIUtils.deriveColor(background, getBackgroundBase(c, false))); + Path2D path2DLeft; + if (isLeftRoundButton(c)) { + path2DLeft = FineUIUtils.createLeftRoundRectangle(0, 0, width, height, arc); + } else { + path2DLeft = FineUIUtils.createRightRoundRectangle(0, 0, width, height, arc); + } + g2.fill(path2DLeft); + } finally { + g2.dispose(); + } + } else { + super.paintBackground(g, c); + } + } + + /** + * 创建UI + */ + public static ComponentUI createUI(JComponent c) { + return new FineButtonUI(false); + } + + static String getButtonTypeStr(AbstractButton c) { + Object value = c.getClientProperty(BUTTON_TYPE); + if (value instanceof String) { + return (String) value; + } + return null; + } + +} diff --git a/designer-base/src/main/java/com/fine/theme/light/ui/FineCombinationButtonUI.java b/designer-base/src/main/java/com/fine/theme/light/ui/FineCombinationButtonUI.java new file mode 100644 index 0000000000..ea617a090b --- /dev/null +++ b/designer-base/src/main/java/com/fine/theme/light/ui/FineCombinationButtonUI.java @@ -0,0 +1,88 @@ +package com.fine.theme.light.ui; + +import com.fine.theme.utils.FineClientProperties; +import com.fine.theme.utils.FineUIUtils; +import com.formdev.flatlaf.ui.FlatPanelUI; +import com.formdev.flatlaf.ui.FlatUIUtils; +import com.fr.design.gui.ibutton.UICombinationButton; + +import javax.swing.JComponent; +import javax.swing.plaf.ComponentUI; +import java.awt.Color; +import java.awt.Graphics; +import java.beans.PropertyChangeEvent; + +import static com.formdev.flatlaf.ui.FlatStylingSupport.Styleable; + +/** + * @author vito + * @since 11.0 + * Created on 2023/12/21 + */ +public class FineCombinationButtonUI extends FlatPanelUI { + @Styleable(dot = true) + protected Color background; + + @Styleable(dot = true) + protected int arc; + + @Styleable(dot = true) + protected Color borderColor; + + /** + * @param shared + * @since 2 + */ + protected FineCombinationButtonUI(boolean shared) { + super(shared); + } + + /** + * 创建UI + * + * @param c 组件 + * @return ComponentUI + */ + public static ComponentUI createUI(JComponent c) { + return new FineCombinationButtonUI(false); + } + + @Override + public void installUI(JComponent c) { + super.installUI(c); + background = FineUIUtils.getUIColor("CombinationButton.background", "desktop"); + borderColor = FineUIUtils.getUIColor("CombinationButton.borderColor", "CombinationButton.secondary.background"); + arc = FineUIUtils.getUIInt("CombinationButton.arc", "Component.arc"); + } + + @Override + public void uninstallUI(JComponent c) { + super.uninstallUI(c); + } + + @Override + public void paint(Graphics g, JComponent c) { + paintBackground(g, c); + super.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); + } + + @Override + public void propertyChange(PropertyChangeEvent e) { + super.propertyChange(e); + switch (e.getPropertyName()) { + case FineClientProperties.STYLE_CLASS: + UICombinationButton b = (UICombinationButton) e.getSource(); + b.setPrimary(); + b.repaint(); + break; + default: + break; + } + } +} 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 b7fd93133b..28b9996671 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 @@ -147,6 +147,7 @@ public class FineLightIconSet extends AbstractIconSet { new SvgIconSource("sort_asc", "com/fine/theme/icon/toolbar/sort_asc.svg", true), new SvgIconSource("tool_edit", "com/fine/theme/icon/toolbar/edit.svg", true), new SvgIconSource("tool_edit_white", "com/fine/theme/icon/toolbar/edit_white.svg", true), + new SvgIconSource("tool_more", "com/fine/theme/icon/toolbar/more.svg", true), // 参数面板 new SvgIconSource("param_edit", "com/fine/theme/icon/param/edit.svg", true, 24), diff --git a/designer-base/src/main/java/com/fine/theme/utils/FineClientProperties.java b/designer-base/src/main/java/com/fine/theme/utils/FineClientProperties.java index ab6384aef6..72effbc10b 100644 --- a/designer-base/src/main/java/com/fine/theme/utils/FineClientProperties.java +++ b/designer-base/src/main/java/com/fine/theme/utils/FineClientProperties.java @@ -1,7 +1,10 @@ package com.fine.theme.utils; +import com.finebi.cbb.utils.StringUtils; import com.formdev.flatlaf.FlatClientProperties; +import javax.swing.JComponent; + /** * FR-UI中使用的各类属性 * @@ -13,4 +16,78 @@ public interface FineClientProperties extends FlatClientProperties { String BUTTON_TYPE_GROUP = "group"; + String STYLE_PRIMARY = "primary"; + String STYLE_SECONDARY = "secondary"; + String STYLE_SIZE_MEDIUM = "medium"; + String STYLE_SIZE_SMALL = "small"; + + String BUTTON_TYPE_LEFT_ROUND_RECT = "leftRoundRect"; + String BUTTON_TYPE_RIGHT_ROUND_RECT = "rightRoundRect"; + + /** + * 添加组件的样式类,类似css,该方法会接在原样式后方 + * + * FineClientProperties.appendStyle("primary small") + * + * + * @param it 组件 + * @param styleClass 样式字符串,支持连续添加类,用空格 + */ + static void appendStyle(JComponent it, String styleClass) { + Object oriProperty = it.getClientProperty(FineClientProperties.STYLE_CLASS); + if (oriProperty instanceof String && StringUtils.isNotBlank((String) oriProperty)) { + styleClass = oriProperty + " " + styleClass; + } + it.putClientProperty(FineClientProperties.STYLE_CLASS, styleClass); + } + + /** + * 设置组件的样式类,类似css,该方法会替换原样式 + * + * FineClientProperties.setStyle("primary small") + * + * + * @param jComponent 组件 + * @param styleClass 样式字符串,支持连续添加类,用空格 + */ + static void setStyle(JComponent jComponent, String styleClass) { + jComponent.putClientProperty(FineClientProperties.STYLE_CLASS, styleClass); + } + + /** + * 样式组合 + * + * @param styleClasses 所有样式 + * @return 样式列表 + */ + static String join(String... styleClasses) { + final StringBuilder sb = new StringBuilder(); + for (final String style : styleClasses) { + if (style == null) { + continue; + } + if (sb.length() > 0) { + sb.append(" "); + } + sb.append(style); + } + return sb.toString(); + } + + /** + * 包含样式 + * + * @param jComponent 组件 + * @param styleClass 样式 + * @return 是否包含指定的样式 + */ + static boolean hasStyle(JComponent jComponent, String styleClass) { + Object style = jComponent.getClientProperty(FineClientProperties.STYLE_CLASS); + if (style instanceof String && StringUtils.isNotBlank((String) style)) { + return ((String) style).contains(styleClass); + } + return false; + } + + } 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 e3065c16fc..8a1e135097 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,15 +6,20 @@ import com.fr.value.AtomicClearableLazyValue; import javax.swing.UIManager; import java.awt.Color; +import java.awt.Component; import java.awt.Composite; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import java.awt.Insets; +import java.awt.geom.Path2D; import java.awt.geom.RoundRectangle2D; import java.lang.reflect.Field; +import static com.fine.theme.light.ui.FineButtonUI.isLeftRoundButton; +import static com.formdev.flatlaf.util.UIScale.scale; + /** * UI绘制的一些常用方法 * @@ -133,7 +138,7 @@ public class FineUIUtils { /** * 通过key获取UI的边距,如果没有则使用后备边距 * - * @param key 边距key + * @param key 边距key * @param defaultInsets 后备边距 * @return 边距 */ @@ -178,4 +183,127 @@ public class FineUIUtils { g2d.setComposite(oldComposite); } + + /** + * 绘制部分圆角矩形边框 + * + * @param g2 Graphics2D + * @param x x坐标 + * @param y y坐标 + * @param width 宽度 + * @param height 高度 + * @param borderWidth 边框宽度 + * @param arc 圆角 + */ + public static void paintPartRoundButtonBorder(Component c, Graphics2D g2, int x, int y, int width, int height, + float borderWidth, float arc) { + FlatUIUtils.setRenderingHints(g2); + arc = scale(arc); + float t = scale(borderWidth); + float t2x = t * 2; + Path2D path2D = new Path2D.Float(Path2D.WIND_EVEN_ODD); + if (isLeftRoundButton(c)) { + path2D.append(createLeftRoundRectangle(x, y, width, height, arc), false); + path2D.append(createLeftRoundRectangle(x + t, y + t, width - t, height - t2x, arc - t), false); + } else { + path2D.append(createRightRoundRectangle(x, y, width, height, arc), false); + path2D.append(createRightRoundRectangle(x, y + t, width - t, height - t2x, arc - t), false); + } + g2.fill(path2D); + } + + /** + * 绘制圆角tab边框 + * + * @param g2 Graphics2D + * @param x x坐标 + * @param y y坐标 + * @param width 宽度 + * @param height 高度 + * @param borderWidth 边框宽度 + * @param arc 圆角 + */ + public static void paintRoundTabBorder(Graphics2D g2, double x, double y, double width, double height, + float borderWidth, float arc) { + FlatUIUtils.setRenderingHints(g2); + arc = scale(arc); + float t = scale(borderWidth); + float t2x = t * 2; + Path2D path2D = new Path2D.Float(Path2D.WIND_EVEN_ODD); + path2D.append(createTopRoundRectangle(x, y, width, height, arc), false); + path2D.append(createTopRoundRectangle(x + t, y + t, width - t2x, height - t2x, arc - t), false); + g2.fill(path2D); + } + + + /** + * 创建一个左圆角矩形路径 + * + * @param x x坐标 + * @param y y坐标 + * @param width 矩形宽度 + * @param height 矩形高度 + * @param arc 圆角弧度 + * @return 路径 + */ + public static Path2D createLeftRoundRectangle(float x, float y, float width, float height, float arc) { + Path2D path = new Path2D.Float(Path2D.WIND_EVEN_ODD, 7); + path.moveTo(x, y + arc); + path.lineTo(x, y + height - arc); + path.quadTo(x, y + height, x + arc, y + height); + path.lineTo(x + width, y + height); + path.lineTo(x + width, y); + path.lineTo(x + arc, y); + path.quadTo(x, y, x, arc + y); + path.closePath(); + return path; + } + + + /** + * 创建一个右圆角矩形路径 + * + * @param x x坐标 + * @param y y坐标 + * @param width 矩形宽度 + * @param height 矩形高度 + * @param arc 圆角弧度 + * @return 路径 + */ + public static Path2D createRightRoundRectangle(float x, float y, float width, float height, float arc) { + Path2D path = new Path2D.Float(Path2D.WIND_EVEN_ODD, 7); + path.moveTo(x, y); + path.lineTo(x, y + height); + path.lineTo(x + width - arc, y + height); + path.quadTo(x + width, y + height, x + width, y + height - arc); + path.lineTo(x + width, y + arc); + path.quadTo(x + width, y, x + width - arc, y); + path.lineTo(x, y); + path.closePath(); + return path; + } + + /** + * 创建一个顶圆角矩形路径 + * + * @param x x坐标 + * @param y y坐标 + * @param width 矩形宽度 + * @param height 矩形高度 + * @param arc 圆角弧度 + * @return 路径 + */ + public static Path2D createTopRoundRectangle(double x, double y, double width, double height, double arc) { + Path2D path = new Path2D.Double(Path2D.WIND_EVEN_ODD, 7); + path.moveTo(x, y + height); + path.lineTo(x, y + arc); + path.quadTo(x, y, x + arc, y); + path.lineTo(x + width - arc, y); + path.quadTo(x + width, y, x + width, y + arc); + path.lineTo(x + width, y + height); + path.lineTo(x, y + height); + path.closePath(); + return path; + } + } diff --git a/designer-base/src/main/java/com/fr/design/gui/ibutton/UICombinationButton.java b/designer-base/src/main/java/com/fr/design/gui/ibutton/UICombinationButton.java index 4a24c8de25..da48b216d4 100644 --- a/designer-base/src/main/java/com/fr/design/gui/ibutton/UICombinationButton.java +++ b/designer-base/src/main/java/com/fr/design/gui/ibutton/UICombinationButton.java @@ -1,143 +1,163 @@ package com.fr.design.gui.ibutton; -import java.awt.BorderLayout; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; +import com.fr.design.constants.UIConstants; +import com.fr.design.utils.gui.GUICoreUtils; import javax.swing.Icon; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JPopupMenu; +import java.awt.BorderLayout; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.function.Consumer; -import com.fr.design.constants.UIConstants; -import com.fr.stable.Constants; -import com.fr.design.utils.gui.GUICoreUtils; +import static com.fine.theme.utils.FineClientProperties.BUTTON_TYPE_LEFT_ROUND_RECT; +import static com.fine.theme.utils.FineClientProperties.BUTTON_TYPE_RIGHT_ROUND_RECT; +import static com.fine.theme.utils.FineClientProperties.STYLE_PRIMARY; +import static com.fine.theme.utils.FineClientProperties.setStyle; +import static com.formdev.flatlaf.FlatClientProperties.BUTTON_TYPE; + +public class UICombinationButton extends JPanel { + private static final String UI_CLASS_ID = "CombinationButtonUI"; + + protected UIButton leftButton; + protected UIButton rightButton; + + + private Consumer leftClickLister; + private Consumer rightClickLister; + + protected void leftButtonClickEvent() { + // 左边按钮点击事件 + } + + protected void rightButtonClickEvent() { + // 右边按钮点击事件 + } + + public UICombinationButton() { + this(new UIButton(), new UIButton()); + } + + + /** + * 添加左按钮监听器 + * + * @param lister 监听 + */ + public void addLeftClickLister(Consumer lister) { + this.leftClickLister = lister; + } + + /** + * 添加右按钮监听器 + * + * @param lister 监听 + */ + public void addRightClickLister(Consumer lister) { + this.rightClickLister = lister; + } + + public UICombinationButton(UIButton left, UIButton right) { + leftButton = left; + leftButton.putClientProperty(BUTTON_TYPE, BUTTON_TYPE_LEFT_ROUND_RECT); + rightButton = right; + rightButton.putClientProperty(BUTTON_TYPE, BUTTON_TYPE_RIGHT_ROUND_RECT); + leftButton.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + if (leftClickLister != null) { + leftClickLister.accept(e); + } else { + leftButtonClickEvent(); + } + } + }); + rightButton.addMouseListener(new MouseAdapter() { + + @Override + public void mouseClicked(MouseEvent e) { + if (rightClickLister != null) { + rightClickLister.accept(e); + } else { + rightButtonClickEvent(); + } + } + }); + + this.setLayout(new BorderLayout()); + this.add(leftButton, BorderLayout.WEST); + this.add(rightButton, BorderLayout.EAST); + } + + public UICombinationButton(String left, Icon right) { + this(); + leftButton.setText(left); + rightButton.setIcon(right); + } + + public UICombinationButton(String left, String right) { + this(); + leftButton.setText(left); + rightButton.setText(right); + } + + public UICombinationButton(Icon left, Icon right) { + this(); + leftButton.setIcon(left); + rightButton.setIcon(right); + } + + @Override + public String getUIClassID() { + return UI_CLASS_ID; + } + + public void setPrimary() { + setStyle(leftButton, STYLE_PRIMARY); + setStyle(rightButton, STYLE_PRIMARY); + } + + public UIButton getLeftButton() { + return leftButton; + } + + public void setExtraPainted(boolean isExtraPainted) { +// if (!isExtraPainted) { +// leftButton.setBackground(null); +// rightButton.setBackground(null); +// leftButton.setOpaque(false); +// rightButton.setOpaque(false); +// } + } + + public UIButton getRightButton() { + return rightButton; + } + + public void set4Toolbar() { + leftButton.setNormalPainted(false); + rightButton.setNormalPainted(false); + leftButton.setBorderPaintedOnlyWhenPressed(true); + rightButton.setBorderPaintedOnlyWhenPressed(true); + } + + protected void showPopWindow(JPopupMenu menu) { + GUICoreUtils.showPopupMenu(menu, this, 0, getY() + getHeight() - 3); + } + + public static void main(String... args) { + JFrame jf = new JFrame("test"); + jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + JPanel content = (JPanel) jf.getContentPane(); + content.setLayout(null); -public class UICombinationButton extends JPanel{ - protected UIButton leftButton; - protected UIButton rightButton; - - protected void leftButtonClickEvent() { - // 左边按钮点击事件 - } - - protected void rightButtonClickEvent() { - // 右边按钮点击事件 - } - - public UICombinationButton() { - this(new UIButton(), new UIButton()); - } - - public UICombinationButton(UIButton left, UIButton right) { - leftButton = left; - rightButton = right; - - leftButton.setRoundBorder(true, Constants.RIGHT); - rightButton.setRoundBorder(true, Constants.LEFT); - - leftButton.addMouseListener(new MouseAdapter() { - @Override - public void mousePressed(MouseEvent e) { - rightButton.getModel().setPressed(true); - rightButton.getModel().setSelected(true); - rightButton.repaint(); - } - - @Override - public void mouseReleased(MouseEvent e) { - rightButton.getModel().setPressed(false); - rightButton.getModel().setSelected(false); - rightButton.repaint(); - } - @Override - public void mouseClicked(MouseEvent e) { - leftButtonClickEvent(); - } - }); - rightButton.addMouseListener(new MouseAdapter() { - @Override - public void mousePressed(MouseEvent e) { - leftButton.getModel().setPressed(true); - leftButton.getModel().setSelected(true); - leftButton.repaint(); - } - - @Override - public void mouseReleased(MouseEvent e) { - leftButton.getModel().setPressed(false); - leftButton.getModel().setSelected(false); - leftButton.repaint(); - } - - @Override - public void mouseClicked(MouseEvent e) { - rightButtonClickEvent(); - } - }); - - this.setLayout(new BorderLayout()); - this.add(leftButton, BorderLayout.CENTER); - this.add(rightButton, BorderLayout.EAST); - } - - public UICombinationButton(String left, Icon right) { - this(); - leftButton.setText(left); - rightButton.setIcon(right); - } - - public UICombinationButton(String left, String right) { - this(); - leftButton.setText(left); - rightButton.setText(right); - } - - public UICombinationButton(Icon left, Icon right) { - this(); - leftButton.setIcon(left); - rightButton.setIcon(right); - } - - public UIButton getLeftButton() { - return leftButton; - } - - public void setExtraPainted(boolean isExtraPainted) { - if(!isExtraPainted) { - leftButton.setBackground(null); - rightButton.setBackground(null); - leftButton.setOpaque(false); - rightButton.setOpaque(false); - } - } - - public UIButton getRightButton() { - return rightButton; - } - - public void set4Toolbar() { - leftButton.setNormalPainted(false); - rightButton.setNormalPainted(false); - leftButton.setBorderPaintedOnlyWhenPressed(true); - rightButton.setBorderPaintedOnlyWhenPressed(true); - } - - protected void showPopWindow(JPopupMenu menu) { - GUICoreUtils.showPopupMenu(menu, this, 0, getY() + getHeight() - 3); - } - - public static void main(String... args) { - JFrame jf = new JFrame("test"); - jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - JPanel content = (JPanel)jf.getContentPane(); - content.setLayout(null); - - UICombinationButton bb = new UICombinationButton("123455", UIConstants.ARROW_DOWN_ICON); - bb.setBounds(20, 20, bb.getPreferredSize().width, bb.getPreferredSize().height); - content.add(bb); - GUICoreUtils.centerWindow(jf); - jf.setSize(400, 400); - jf.setVisible(true); - } + UICombinationButton bb = new UICombinationButton("123455", UIConstants.ARROW_DOWN_ICON); + bb.setBounds(20, 20, bb.getPreferredSize().width, bb.getPreferredSize().height); + content.add(bb); + GUICoreUtils.centerWindow(jf); + jf.setSize(400, 400); + jf.setVisible(true); + } } \ 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 adb218b4a6..fd9df53c87 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 @@ -1,6 +1,6 @@ # \u516C\u5171\u5C5E\u6027\uFF0C\u5982UI\u7B49\uFF0C\u5176\u4ED6\u4E3B\u9898\u7EE7\u627F\u8BE5\u4E3B\u9898\uFF0C\u9632\u6B62\u51FA\u73B0UI\u4E0D\u5B58\u5728\u7B49\u95EE\u9898 #---- UI delegates ---- -ButtonUI=com.formdev.flatlaf.ui.FlatButtonUI +ButtonUI=com.fine.theme.light.ui.FineButtonUI CheckBoxUI=com.fine.theme.light.ui.FineCheckBoxUI CheckBoxMenuItemUI=com.formdev.flatlaf.ui.FlatCheckBoxMenuItemUI ColorChooserUI=com.formdev.flatlaf.ui.FlatColorChooserUI @@ -44,7 +44,8 @@ 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 -ButtonGroupUI= com.fine.theme.light.ui.FineButtonGroupUI -SelectBoxUI= com.fine.theme.light.ui.FineSelectBoxUI +ButtonGroupUI=com.fine.theme.light.ui.FineButtonGroupUI +SelectBoxUI=com.fine.theme.light.ui.FineSelectBoxUI +CombinationButtonUI=com.fine.theme.light.ui.FineCombinationButtonUI InputUI=com.fine.theme.light.ui.FineInputUI 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 d0241bc58e..0184ae3b18 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 @@ -59,7 +59,7 @@ Component.defaultVGap=10 @disabledForeground = tint(@foreground,55%) # component background -@buttonBackground = lighten(@background,5%) +@buttonBackground = #FFF @componentBackground = @background @menuBackground = @background @@ -135,33 +135,50 @@ fill.disabled=#F2F4F8 border.divider=#DADEE7 tooltip.normal=#3F506A tooltip.disabled=#A3ADBD +hover.deep=#e2fbe6 #---- Button ---- -Button.border = com.formdev.flatlaf.ui.FlatButtonBorder -Button.arc = 3 -Button.minimumWidth = 72 +Button.border =com.fine.theme.light.ui.FineButtonBorder +Button.arc = 6 +Button.minimumWidth = 0 Button.margin = 2,12,2,12 Button.iconTextGap = 4 Button.rollover = true Button.defaultButtonFollowsFocus = false -Button.borderWidth = 1 +Button.borderWidth = 2 +Button.medium.margin = 2,12,2,12 +Button.small.margin = 0,10,0,10 Button.background = @buttonBackground -Button.focusedBackground = changeLightness($Component.focusColor,95%) -Button.hoverBackground = darken($Button.background,3%,derived) -Button.pressedBackground = darken($Button.background,10%,derived) +Button.focusedBackground = @buttonBackground +Button.hoverBackground = $fill.hover +Button.pressedBackground = $fill.click Button.selectedBackground = darken($Button.background,20%,derived) Button.selectedForeground = $Button.foreground Button.disabledSelectedBackground = darken($Button.background,13%,derived) +Button.disabledBackground = $fill.disabled Button.borderColor = $Component.borderColor Button.disabledBorderColor = $Component.disabledBorderColor -Button.focusedBorderColor = $Component.focusedBorderColor -Button.hoverBorderColor = $Button.focusedBorderColor +Button.focusedBorderColor = $border.divider +Button.hoverBorderColor = $border.divider Button.innerFocusWidth = 0 +Button.text.background = $Button.background +Button.text.foreground = $Button.foreground +Button.text.focusedBackground = $Button.focusedBackground +Button.text.hoverBackground = darken($Button.default.background,3%,derived) +Button.text.pressedBackground = darken($Button.default.background,10%,derived) +Button.text.borderColor = @accentButtonDefaultBorderColor +Button.text.hoverBorderColor = $Button.hoverBorderColor +Button.text.focusedBorderColor = $Button.focusedBorderColor +Button.text.focusColor = $Component.focusColor +Button.text.borderWidth = 2 + + + Button.default.background = $Button.background Button.default.foreground = $Button.foreground Button.default.focusedBackground = $Button.focusedBackground @@ -179,10 +196,29 @@ Button.toolbar.selectedBackground = $Button.selectedBackground Button.toolbar.margin = 3,3,3,3 Button.toolbar.spacingInsets = 1,2,1,2 +Button.group.background = #FFF +Button.group.selectedBackground = #2576EF +Button.group.pressedBackground = #2576EF +Button.group.selectedForeground = #FFF +Button.group.pressedForeground = #FFF +Button.group.minimumWidth = 32 +Button.group.minimumHeight = 20 +Button.group.arc = $Component.arc + +Button.tab.hoverBackground = darken($Button.background,12%,derived) +#Button.tab.pressedBackground = #DEEAFD +Button.tab.selectedBackground = #DEEAFD +Button.tab.margin = 3,3,3,3 +Button.tab.spacingInsets = 1,2,1,2 + +CombinationButton.background = $Button.background +CombinationButton.borderColor = $Component.borderColor +CombinationButton.arc = $Button.arc + #---- CheckBox ---- CheckBox.border = com.formdev.flatlaf.ui.FlatMarginBorder -CheckBox.icon = com.formdev.flatlaf.icons.FlatCheckBoxIcon +CheckBox.icon = com.fine.theme.icon.AnimatedSwitchIcon CheckBox.arc = 4 CheckBox.margin = 2,2,2,2 CheckBox.iconTextGap = 4 @@ -288,8 +324,8 @@ Component.minimumWidth = 64 Component.arrowType = chevron Component.hideMnemonics = true -Component.borderColor = shade(@background,20%) -Component.disabledBorderColor = tint($Component.borderColor,20%) +Component.borderColor = $defaultBorderColor +Component.disabledBorderColor = $defaultBorderColor Component.focusedBorderColor = shade($Component.focusColor,10%) Component.focusColor = @accentFocusColor Component.linkColor = @accentLinkColor @@ -774,19 +810,19 @@ SplitPaneDivider.draggingColor = $Component.borderColor #---- TabbedPane ---- -TabbedPane.tabHeight = 32 -TabbedPane.tabSelectionHeight = 3 -TabbedPane.cardTabSelectionHeight = 3 +TabbedPane.tabHeight = 30 +TabbedPane.tabSelectionHeight = 0 +TabbedPane.cardTabSelectionHeight = 0 TabbedPane.tabArc = 0 TabbedPane.tabSelectionArc = 0 TabbedPane.cardTabArc = 12 -TabbedPane.selectedInsets = 0,0,0,0 +TabbedPane.selectedInsets = 10,0,0,0 TabbedPane.tabSelectionInsets = 0,0,0,0 TabbedPane.contentSeparatorHeight = 1 -TabbedPane.showTabSeparators = false +TabbedPane.showTabSeparators = true TabbedPane.tabSeparatorsFullHeight = false TabbedPane.hasFullBorder = false -TabbedPane.tabInsets = 4,12,4,12 +TabbedPane.tabInsets = 4,6,4,6 TabbedPane.tabAreaInsets = 0,0,0,0 TabbedPane.selectedTabPadInsets = 0,0,0,0 TabbedPane.tabRunOverlay = 0 @@ -794,6 +830,9 @@ TabbedPane.tabsOverlapBorder = false TabbedPane.disabledForeground = @disabledForeground TabbedPane.shadow = @background TabbedPane.contentBorderInsets = null +TabbedPane.background = $fill.disabled +TabbedPane.selectedBackground = #fff +TabbedPane.tabSeparatorColor = $border.divider # allowed values: moreTabsButton or arrowButtons TabbedPane.hiddenTabsNavigation = moreTabsButton # allowed values: leading, trailing, center or fill @@ -830,21 +869,32 @@ TabbedPane.closeCrossLineWidth = 1 TabbedPane.underlineColor = @accentUnderlineColor TabbedPane.inactiveUnderlineColor = mix(@accentUnderlineColor,$TabbedPane.background,50%) TabbedPane.disabledUnderlineColor = darken(@background,28%) -TabbedPane.hoverColor = #DADEE7 +TabbedPane.hoverColor = $fill.hover TabbedPane.focusColor = mix(@selectionBackground,$TabbedPane.background,10%) -TabbedPane.contentAreaColor = $Component.borderColor +TabbedPane.contentAreaColor = $fill.hover TabbedPane.buttonHoverBackground = darken($TabbedPane.background,7%,derived) TabbedPane.buttonPressedBackground = darken($TabbedPane.background,10%,derived) TabbedPane.closeBackground = null TabbedPane.closeForeground = @disabledForeground -TabbedPane.closeHoverBackground = darken($TabbedPane.background,20%,derived) +TabbedPane.closeHoverBackground = $hover.deep TabbedPane.closeHoverForeground = @foreground TabbedPane.closePressedBackground = darken($TabbedPane.background,25%,derived) TabbedPane.closePressedForeground = $TabbedPane.closeHoverForeground - +#---- TemplateTabPane ---- +TemplateTabPane.tabHeight = 30 +TemplateTabPane.tabSelectionHeight = 0 +TemplateTabPane.cardTabSelectionHeight = 0 +TemplateTabPane.selectedInsets = 10,0,0,0 +TemplateTabPane.hoverColor = $fill.hover +TemplateTabPane.contentAreaColor = $fill.hover +TemplateTabPane.background = $fill.disabled +TemplateTabPane.selectedBackground = #fff +TemplateTabPane.tabSeparatorColor = $border.divider +TemplateTabPane.closeHoverBackground = $hover.deep +TemplateTabPane.tabInsets = 4,6,4,6 #---- Table ---- Table.rowHeight = 20 @@ -1175,6 +1225,33 @@ CellOtherSetPane.height=$Component.defaultHeight toolbar.pressedBackground: darken($TextField.background,8%); \ toolbar.selectedBackground: darken($TextField.background,12%) +[style]Button.primary = \ + background : @BrandColor; \ + foreground : #FFF; \ + focusedBackground : #5493F2; \ + hoverBackground : #5493F2; \ + pressedBackground : #105DD1; \ + disabledSelectedBackground : #F2F4F8; \ + borderWidth : 0 + +[style]Button.small = margin : 0,10,0,10; + +[style]Button.secondary = \ + background : $Button.background; \ + foreground : $Button.foreground; \ + focusedBackground : $Button.focusedBackground; \ + hoverBackground : darken($Button.default.background,3%,derived); \ + pressedBackground : darken($Button.default.background,10%,derived); \ + borderColor : @accentButtonDefaultBorderColor; \ + hoverBorderColor : $Button.hoverBorderColor; \ + focusedBorderColor : $Button.focusedBorderColor; \ + focusColor : $Component.focusColor; \ + borderWidth : 2 + +[style]CombinationButton.primary = \ + background : @BrandColor; \ + arc : 3 + #---- clearButton ---- # for clear/cancel button in text fields 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 bc157a2f57..e0d0dad170 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,14 +2,21 @@ 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.ibutton.UICombinationButton; +import com.fr.design.gui.ilable.UILabel; import com.fr.design.gui.storybook.Story; import com.fr.design.gui.storybook.StoryBoard; import javax.swing.JButton; 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.flex; import static com.fine.swing.ui.layout.Layouts.row; +import static com.fine.theme.utils.FineClientProperties.STYLE_PRIMARY; +import static com.fine.theme.utils.FineClientProperties.STYLE_SIZE_SMALL; +import static com.fine.theme.utils.FineClientProperties.join; +import static com.fine.theme.utils.FineClientProperties.setStyle; /** * 按钮 @@ -23,14 +30,127 @@ public class ButtonStoryBoard extends StoryBoard { public ButtonStoryBoard() { super("按钮"); + setSpacing(16); add( - row(10, - cell(new UIButton("按钮")), - cell(new UIButton("保存", new LazyIcon("save"))), - cell(new UIButton(new LazyIcon("multi"))) + row(30, true, + column(16, + cell(new UILabel(STYLE_PRIMARY)).with(this::h2), + cell(new UILabel("medium")).with(this::h3), + row(20, + cell(new UILabel("正常")), + cell(new UIButton("按钮")) + .with(it -> setStyle(it, STYLE_PRIMARY)), + cell(new UIButton("按钮", new LazyIcon("add"))) + .with(it -> setStyle(it, STYLE_PRIMARY)), + cell(new UIButton(new LazyIcon("multi"))) + .with(it -> setStyle(it, STYLE_PRIMARY)) + ), + row(20, + cell(new UILabel("禁用")), + cell(new UIButton("按钮")).with(it -> { + setStyle(it, STYLE_PRIMARY); + it.setEnabled(false); + }), + cell(new UIButton("保存", new LazyIcon("save"))).with(it -> { + setStyle(it, STYLE_PRIMARY); + it.setEnabled(false); + }), + cell(new UIButton(new LazyIcon("add"))).with(it -> { + setStyle(it, STYLE_PRIMARY); + it.setEnabled(false); + }) + ), + cell(new UILabel("small")).with(this::h3), + row(20, + cell(new UILabel("正常")), + cell(new UIButton("按钮")) + .with(it -> setStyle(it, join(STYLE_PRIMARY, STYLE_SIZE_SMALL))), + cell(new UIButton("按钮", new LazyIcon("add"))) + .with(it -> setStyle(it, join(STYLE_PRIMARY, STYLE_SIZE_SMALL))), + cell(new UIButton(new LazyIcon("multi"))) + .with(it -> setStyle(it, join(STYLE_PRIMARY, STYLE_SIZE_SMALL))) + ), + row(20, + cell(new UILabel("禁用")), + cell(new UIButton("按钮")).with(it -> { + setStyle(it, join(STYLE_PRIMARY, STYLE_SIZE_SMALL)); + it.setEnabled(false); + }), + cell(new UIButton("保存", new LazyIcon("save"))).with(it -> { + setStyle(it, join(STYLE_PRIMARY, STYLE_SIZE_SMALL)); + it.setEnabled(false); + }), + cell(new UIButton(new LazyIcon("add"))).with(it -> { + setStyle(it, join(STYLE_PRIMARY, STYLE_SIZE_SMALL)); + it.setEnabled(false); + }) + ) + ), + column(16, + cell(new UILabel("Secondary")).with(this::h2), + cell(new UILabel("medium")).with(this::h3), + row(20, + cell(new UILabel("正常")).with(it -> setStyle(it, "secondary")), + cell(new UIButton("按钮")), + cell(new UIButton("按钮", new LazyIcon("add"))), + cell(new UIButton(new LazyIcon("multi"))) + ), + row(20, + cell(new UILabel("禁用")), + cell(new UIButton("按钮")).with(it -> it.setEnabled(false)), + cell(new UIButton("保存", new LazyIcon("save"))).with(it -> it.setEnabled(false)), + cell(new UIButton(new LazyIcon("add"))).with(it -> it.setEnabled(false)) + ), + cell(new UILabel("small")).with(this::h3), + row(20, + cell(new UILabel("正常")), + cell(new UIButton("按钮")) + .with(it -> setStyle(it, STYLE_SIZE_SMALL)), + cell(new UIButton("按钮", new LazyIcon("add"))) + .with(it -> setStyle(it, STYLE_SIZE_SMALL)), + cell(new UIButton(new LazyIcon("multi"))) + .with(it -> setStyle(it, STYLE_SIZE_SMALL)) + ), + row(20, + cell(new UILabel("禁用")), + cell(new UIButton("按钮")).with(it -> { + setStyle(it, STYLE_SIZE_SMALL); + it.setEnabled(false); + }), + cell(new UIButton("保存", new LazyIcon("save"))).with(it -> { + setStyle(it, STYLE_SIZE_SMALL); + it.setEnabled(false); + }), + cell(new UIButton(new LazyIcon("add"))).with(it -> { + setStyle(it, STYLE_SIZE_SMALL); + it.setEnabled(false); + }) + ) + ) ), - row(10, + cell(new UILabel("JButton")).with(this::h2), + row(20, + cell(new UILabel("medium")), cell(new JButton("按钮")), + cell(new JButton("按钮", new LazyIcon("add"))), + cell(new JButton(new LazyIcon("multi"))) + ), + row(20, + cell(new UILabel("medium")), + cell(new JButton("按钮")).with(it -> it.setEnabled(false)), + cell(new JButton("保存", new LazyIcon("save"))).with(it -> it.setEnabled(false)), + cell(new JButton(new LazyIcon("add"))).with(it -> it.setEnabled(false)) + ), + row(20, + cell(new UICombinationButton("按钮", new LazyIcon("triangle_down"))) + .with(it -> { + setStyle(it, STYLE_PRIMARY); + it.setExtraPainted(false); + }), + cell(new UICombinationButton("按钮", new LazyIcon("triangle_down"))) + .with(it -> setStyle(it, STYLE_PRIMARY)), + cell(new UICombinationButton("按钮2", new LazyIcon("triangle_down"))), + cell(new JButton("按钮", new LazyIcon("add"))), cell(new JButton(new LazyIcon("multi"))) ), flex()