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