diff --git a/designer-base/src/main/java/com/fine/theme/light/ui/FineButtonGroupUI.java b/designer-base/src/main/java/com/fine/theme/light/ui/FineButtonGroupUI.java index cb406e8319..2035abf493 100644 --- a/designer-base/src/main/java/com/fine/theme/light/ui/FineButtonGroupUI.java +++ b/designer-base/src/main/java/com/fine/theme/light/ui/FineButtonGroupUI.java @@ -1,14 +1,11 @@ package com.fine.theme.light.ui; -import com.fine.theme.utils.FineUIUtils; - import javax.swing.JComponent; -import javax.swing.border.LineBorder; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.PanelUI; /** - * 按钮组UI,应用于 + * 按钮组UI,应用于 {@link com.fr.design.gui.ibutton.UIButtonGroup} * * @author Levy.Xie * @since 11.0 @@ -29,7 +26,7 @@ public class FineButtonGroupUI extends PanelUI { @Override public void installUI(JComponent c) { super.installUI(c); - c.setBorder(new LineBorder(FineUIUtils.getUIColor("defaultBorderColor", "Component.borderColor"))); + c.setBorder(new FineRoundBorder()); } @Override diff --git a/designer-base/src/main/java/com/fine/theme/light/ui/FineToggleButtonUI.java b/designer-base/src/main/java/com/fine/theme/light/ui/FineToggleButtonUI.java index bb7a9cbb7e..149fd479cd 100644 --- a/designer-base/src/main/java/com/fine/theme/light/ui/FineToggleButtonUI.java +++ b/designer-base/src/main/java/com/fine/theme/light/ui/FineToggleButtonUI.java @@ -17,12 +17,23 @@ import java.awt.Color; import java.awt.Component; import java.awt.Graphics; import java.awt.Graphics2D; +import java.awt.Shape; +import java.awt.Rectangle; import static com.fine.theme.utils.FineClientProperties.BUTTON_TYPE_GROUP; import static com.fine.theme.utils.FineClientProperties.BUTTON_TYPE; import static com.fine.theme.utils.FineClientProperties.BUTTON_TYPE_TAB; +import static com.fine.theme.utils.FineClientProperties.BUTTON_GROUP_POSITION; +import static com.fine.theme.utils.FineClientProperties.GROUP_BUTTON_POSITION_INNER; +import static com.fine.theme.utils.FineClientProperties.GROUP_BUTTON_POSITION_LEFT; +import static com.fine.theme.utils.FineClientProperties.GROUP_BUTTON_POSITION_LEFT_BOTTOM; +import static com.fine.theme.utils.FineClientProperties.GROUP_BUTTON_POSITION_LEFT_TOP; +import static com.fine.theme.utils.FineClientProperties.GROUP_BUTTON_POSITION_RIGHT; +import static com.fine.theme.utils.FineClientProperties.GROUP_BUTTON_POSITION_RIGHT_BOTTOM; +import static com.fine.theme.utils.FineClientProperties.GROUP_BUTTON_POSITION_RIGHT_TOP; import static com.fine.theme.utils.FineClientProperties.TAB_BUTTON_SELECTED_BACKGROUND; import static com.formdev.flatlaf.FlatClientProperties.clientPropertyColor; +import static com.formdev.flatlaf.FlatClientProperties.clientPropertyInt; /** * 提供 {@link javax.swing.JToggleButton} 的UI类 @@ -75,6 +86,10 @@ public class FineToggleButtonUI extends FlatToggleButtonUI { return null; } + static int getGroupButtonPosition(AbstractButton c) { + return clientPropertyInt(c, BUTTON_GROUP_POSITION, GROUP_BUTTON_POSITION_INNER); + } + static boolean isTabButton(Component c) { return c instanceof JToggleButton && BUTTON_TYPE_TAB.equals(getButtonTypeStr((JToggleButton) c)); } @@ -134,8 +149,38 @@ public class FineToggleButtonUI extends FlatToggleButtonUI { try { FlatUIUtils.setRenderingHints(g2); g2.setColor(FlatUIUtils.deriveColor(background, getBackgroundBase(c, true))); - float focusWidth = FlatUIUtils.getBorderFocusWidth(c); - FlatUIUtils.paintComponentBackground(g2, 0, 0, c.getWidth(), c.getHeight(), focusWidth, 0); + + int position = getGroupButtonPosition((AbstractButton) c); + if (position == GROUP_BUTTON_POSITION_INNER) { + float focusWidth = FlatUIUtils.getBorderFocusWidth(c); + FlatUIUtils.paintComponentBackground(g2, 0, 0, c.getWidth(), c.getHeight(), focusWidth, 0); + } else { + float arc = FlatUIUtils.getBorderArc( c ) / 2; + Shape path2D; + switch (position) { + case GROUP_BUTTON_POSITION_LEFT: + path2D = FineUIUtils.createLeftRoundRectangle(0, 0, c.getWidth(), c.getHeight(), arc); + break; + case GROUP_BUTTON_POSITION_RIGHT: + path2D = FineUIUtils.createRightRoundRectangle(0, 0, c.getWidth(), c.getHeight(), arc); + break; + case GROUP_BUTTON_POSITION_LEFT_TOP: + path2D = FineUIUtils.createTopLeftRoundRectangle(0, 0, c.getWidth(), c.getHeight(), arc); + break; + case GROUP_BUTTON_POSITION_LEFT_BOTTOM: + path2D = FineUIUtils.createBottomLeftRoundRectangle(0, 0, c.getWidth(), c.getHeight(), arc); + break; + case GROUP_BUTTON_POSITION_RIGHT_TOP: + path2D = FineUIUtils.createTopRightRoundRectangle(0, 0, c.getWidth(), c.getHeight(), arc); + break; + case GROUP_BUTTON_POSITION_RIGHT_BOTTOM: + path2D = FineUIUtils.createBottomRightRoundRectangle(0, 0, c.getWidth(), c.getHeight(), arc); + break; + default: + path2D = new Rectangle(); + } + g2.fill(path2D); + } } finally { g2.dispose(); } 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 72effbc10b..5015dd9d9d 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 @@ -14,6 +14,7 @@ import javax.swing.JComponent; */ public interface FineClientProperties extends FlatClientProperties { + //--------------------------- ButtonGroup ----------------------- String BUTTON_TYPE_GROUP = "group"; String STYLE_PRIMARY = "primary"; @@ -90,4 +91,14 @@ public interface FineClientProperties extends FlatClientProperties { } + String BUTTON_GROUP_POSITION = "group_position"; + + int GROUP_BUTTON_POSITION_INNER = 0; + int GROUP_BUTTON_POSITION_LEFT = 1; + int GROUP_BUTTON_POSITION_RIGHT = 2; + int GROUP_BUTTON_POSITION_LEFT_TOP = 3; + int GROUP_BUTTON_POSITION_LEFT_BOTTOM = 4; + int GROUP_BUTTON_POSITION_RIGHT_TOP = 5; + int GROUP_BUTTON_POSITION_RIGHT_BOTTOM = 6; + } 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 0448fa82f0..01b92af016 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 @@ -235,6 +235,35 @@ public class FineUIUtils { g2.fill(path2D); } + /** + * 创建一个部分圆角的矩形路径 + * + * @param x x坐标 + * @param y y坐标 + * @param width 矩形宽度 + * @param height 矩形高度 + * @param arcTopLeft 左上圆角弧度 + * @param arcTopRight 右上圆角弧度 + * @param arcBottomRight 右下圆角弧度 + * @param arcBottomLeft 左下圆角弧度 + * @return 路径 + */ + public static Path2D createPartRoundRectangle(double x, double y, double width, double height, + double arcTopLeft, double arcTopRight, double arcBottomRight, double arcBottomLeft) { + Path2D path = new Path2D.Double(Path2D.WIND_EVEN_ODD, 7); + path.moveTo(x + arcTopLeft, y); + path.lineTo(x + width - arcTopRight, y); + path.quadTo(x + width, y, x + width, y + arcTopRight); + path.lineTo(x + width, y + height - arcBottomRight); + path.quadTo(x + width, y + height, x + width - arcBottomRight, y + height); + path.lineTo(x + arcBottomLeft, y + height); + path.quadTo(x, y + height, x, y + height - arcBottomLeft); + path.lineTo(x, y + arcTopLeft); + path.quadTo(x, y, x + arcTopLeft, y); + path.closePath(); + return path; + } + /** * 创建一个左圆角矩形路径 @@ -247,16 +276,7 @@ public class FineUIUtils { * @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; + return createPartRoundRectangle(x, y, width, height, arc, 0, 0, arc); } @@ -271,16 +291,7 @@ public class FineUIUtils { * @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; + return createPartRoundRectangle(x, y, width, height, 0, arc, arc, 0); } /** @@ -294,16 +305,63 @@ public class FineUIUtils { * @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; + return createPartRoundRectangle(x, y, width, height, arc, arc, 0, 0); + } + + /** + * 创建一个左上圆角的矩形路径 + * + * @param x x坐标 + * @param y y坐标 + * @param width 矩形宽度 + * @param height 矩形高度 + * @param arc 圆角弧度 + * @return 路径 + */ + public static Path2D createTopLeftRoundRectangle(float x, float y, float width, float height, float arc) { + return createPartRoundRectangle(x, y, width, height, arc, 0, 0, 0); + } + + /** + * 创建一个左下圆角的矩形路径 + * + * @param x x坐标 + * @param y y坐标 + * @param width 矩形宽度 + * @param height 矩形高度 + * @param arc 圆角弧度 + * @return 路径 + */ + public static Path2D createBottomLeftRoundRectangle(float x, float y, float width, float height, float arc) { + return createPartRoundRectangle(x, y, width, height, 0, 0, 0, arc); + } + + /** + * 创建一个右上圆角的矩形路径 + * + * @param x x坐标 + * @param y y坐标 + * @param width 矩形宽度 + * @param height 矩形高度 + * @param arc 圆角弧度 + * @return 路径 + */ + public static Path2D createTopRightRoundRectangle(float x, float y, float width, float height, float arc) { + return createPartRoundRectangle(x, y, width, height, 0, arc, 0, 0); + } + + /** + * 创建一个右下圆角的矩形路径 + * + * @param x x坐标 + * @param y y坐标 + * @param width 矩形宽度 + * @param height 矩形高度 + * @param arc 圆角弧度 + * @return 路径 + */ + public static Path2D createBottomRightRoundRectangle(float x, float y, float width, float height, float arc) { + return createPartRoundRectangle(x, y, width, height, 0, 0, arc, 0); } } diff --git a/designer-base/src/main/java/com/fr/design/gui/ibutton/UIButtonGroup.java b/designer-base/src/main/java/com/fr/design/gui/ibutton/UIButtonGroup.java index 4906c3dbe5..4f5dadba45 100644 --- a/designer-base/src/main/java/com/fr/design/gui/ibutton/UIButtonGroup.java +++ b/designer-base/src/main/java/com/fr/design/gui/ibutton/UIButtonGroup.java @@ -3,13 +3,13 @@ package com.fr.design.gui.ibutton; import com.fine.swing.ui.layout.Column; import com.fine.swing.ui.layout.Row; import com.fine.swing.ui.layout.Spacer; +import com.fine.theme.light.ui.FineRoundBorder; import com.fine.theme.utils.FineUIScale; import com.fine.theme.utils.FineUIUtils; import com.fr.design.event.GlobalNameListener; import com.fr.design.event.GlobalNameObserver; import com.fr.design.event.UIObserver; import com.fr.design.event.UIObserverListener; -import com.fr.design.utils.gui.UIComponentUtils; import com.fr.stable.ArrayUtils; import com.fr.stable.StringUtils; @@ -17,7 +17,6 @@ import javax.swing.Icon; import javax.swing.border.LineBorder; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; -import java.awt.Dimension; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; @@ -29,19 +28,24 @@ import java.util.List; import static com.fine.swing.ui.layout.Layouts.cell; import static com.fine.theme.utils.FineClientProperties.BUTTON_TYPE_GROUP; import static com.fine.theme.utils.FineClientProperties.BUTTON_TYPE; +import static com.fine.theme.utils.FineClientProperties.BUTTON_GROUP_POSITION; +import static com.fine.theme.utils.FineClientProperties.GROUP_BUTTON_POSITION_INNER; +import static com.fine.theme.utils.FineClientProperties.GROUP_BUTTON_POSITION_LEFT; +import static com.fine.theme.utils.FineClientProperties.GROUP_BUTTON_POSITION_LEFT_BOTTOM; +import static com.fine.theme.utils.FineClientProperties.GROUP_BUTTON_POSITION_LEFT_TOP; +import static com.fine.theme.utils.FineClientProperties.GROUP_BUTTON_POSITION_RIGHT; +import static com.fine.theme.utils.FineClientProperties.GROUP_BUTTON_POSITION_RIGHT_BOTTOM; +import static com.fine.theme.utils.FineClientProperties.GROUP_BUTTON_POSITION_RIGHT_TOP; public class UIButtonGroup extends Column implements GlobalNameObserver, UIObserver { private static final String UI_CLASS_ID = "ButtonGroupUI"; private static final long serialVersionUID = 1L; - private static final int TEXT_LENGTH = 3; - private static final int BUTTON_SIZE = 2; - private int currentButtonSize = 0; protected List labelButtonList; + protected int totalButtonSize; protected int selectedIndex = -1; private List objectList;// 起到一个render的作用 private GlobalNameListener globalNameListener = null; private String buttonGroupName = StringUtils.EMPTY; - private boolean isToolBarComponent = false; private boolean isClick; private UIObserverListener uiObserverListener; @@ -64,6 +68,7 @@ public class UIButtonGroup extends Column implements GlobalNameObserver, UIOb this.objectList = Arrays.asList(objects); } labelButtonList = new ArrayList<>(iconArray.length); + totalButtonSize = iconArray.length; for (int i = 0; i < iconArray.length; i++) { final int index = i; Icon icon = iconArray[i]; @@ -89,7 +94,7 @@ public class UIButtonGroup extends Column implements GlobalNameObserver, UIOb return false; } }; - initButton(labelButton); + initButton(labelButton, index); } initLayout(getCols()); } @@ -98,6 +103,7 @@ public class UIButtonGroup extends Column implements GlobalNameObserver, UIOb if (!ArrayUtils.isEmpty(objects) && iconArray.length == objects.length) { this.objectList = Arrays.asList(objects); } + totalButtonSize = iconArray.length; labelButtonList = new ArrayList<>(iconArray.length); for (int i = 0; i < iconArray.length; i++) { final int index = i; @@ -124,7 +130,7 @@ public class UIButtonGroup extends Column implements GlobalNameObserver, UIOb return false; } }; - initButton(labelButton); + initButton(labelButton, index); } initLayout(getCols()); } @@ -133,8 +139,8 @@ public class UIButtonGroup extends Column implements GlobalNameObserver, UIOb if (!ArrayUtils.isEmpty(objects) && textArray.length == objects.length) { this.objectList = Arrays.asList(objects); } - currentButtonSize = textArray.length; labelButtonList = new ArrayList<>(textArray.length); + totalButtonSize = textArray.length; for (int i = 0; i < textArray.length; i++) { final int index = i; final UIToggleButton labelButton = new UIToggleButton(textArray[i]) { @@ -159,7 +165,7 @@ public class UIButtonGroup extends Column implements GlobalNameObserver, UIOb } }; - initButton(labelButton); + initButton(labelButton, index); } initLayout(getCols()); } @@ -169,8 +175,13 @@ public class UIButtonGroup extends Column implements GlobalNameObserver, UIOb return UI_CLASS_ID; } + /** + * 计算按钮组的列布局 + * + * @return 列布局,形如[5,3] 即为两行,首行5个组件,次行3个组件 + */ protected int[] getCols() { - return new int[]{labelButtonList.size()}; + return new int[]{totalButtonSize}; } protected void initLayout(int[] cols) { @@ -198,21 +209,41 @@ public class UIButtonGroup extends Column implements GlobalNameObserver, UIOb return spacer; } - protected void initButton(UIToggleButton labelButton) { + protected void initButton(UIToggleButton labelButton, int index) { + labelButton.setBorder(new FineRoundBorder()); labelButton.setBorderPainted(false); labelButton.putClientProperty(BUTTON_TYPE, BUTTON_TYPE_GROUP); - adjustButton(labelButton); - UIComponentUtils.setLineWrap(labelButton); + labelButton.putClientProperty(BUTTON_GROUP_POSITION, getGroupButtonPosition(index)); labelButtonList.add(labelButton); } - - private void adjustButton(UIToggleButton labelButton) { - if (labelButton.getText().length() > TEXT_LENGTH && currentButtonSize > BUTTON_SIZE) { - Dimension dimension = labelButton.getPreferredSize(); - dimension.height <<= 1; - labelButton.setPreferredSize(dimension); + /** + * 计算按钮位于整个按钮组件中的位置 + * @param index 按钮序号 + * @return 按钮位置,详见 {@link com.fine.theme.utils.FineClientProperties} + */ + protected int getGroupButtonPosition(int index) { + int[] cols = getCols(); + if (cols.length == 1) { + if (index == 0) { + return GROUP_BUTTON_POSITION_LEFT; + } else if (index == totalButtonSize - 1) { + return GROUP_BUTTON_POSITION_RIGHT; + } + } else { + int rightTopCorner = cols[0] - 1; + int leftBottomCorner = totalButtonSize - cols[cols.length - 1]; + if (index == 0) { + return GROUP_BUTTON_POSITION_LEFT_TOP; + } else if (index == totalButtonSize - 1) { + return GROUP_BUTTON_POSITION_RIGHT_BOTTOM; + } else if (index == rightTopCorner) { + return GROUP_BUTTON_POSITION_RIGHT_TOP; + } else if (index == leftBottomCorner) { + return GROUP_BUTTON_POSITION_LEFT_BOTTOM; + } } + return GROUP_BUTTON_POSITION_INNER; } public boolean hasClick() { @@ -224,7 +255,6 @@ public class UIButtonGroup extends Column implements GlobalNameObserver, UIOb } public void setForToolBarButtonGroup(boolean isToolBarComponent) { - this.isToolBarComponent = isToolBarComponent; if (isToolBarComponent) { for (UIToggleButton uiToggleButton : labelButtonList) { uiToggleButton.set4ToolbarButton(); diff --git a/designer-base/src/main/java/com/fr/design/gui/ibutton/UITabGroup.java b/designer-base/src/main/java/com/fr/design/gui/ibutton/UITabGroup.java index 148a0711ae..5352ddd3da 100644 --- a/designer-base/src/main/java/com/fr/design/gui/ibutton/UITabGroup.java +++ b/designer-base/src/main/java/com/fr/design/gui/ibutton/UITabGroup.java @@ -33,7 +33,7 @@ public class UITabGroup extends UIButtonGroup { @Override protected int[] getCols() { - int buttons = labelButtonList.size(); + int buttons = totalButtonSize; if (buttons < ROW_MAX_LIMIT) { return new int[]{buttons}; } diff --git a/designer-chart/src/main/java/com/fr/van/chart/custom/component/VanChartCustomPlotUITabGroup.java b/designer-chart/src/main/java/com/fr/van/chart/custom/component/VanChartCustomPlotUITabGroup.java index f36eca435d..e4ce883912 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/custom/component/VanChartCustomPlotUITabGroup.java +++ b/designer-chart/src/main/java/com/fr/van/chart/custom/component/VanChartCustomPlotUITabGroup.java @@ -37,7 +37,7 @@ public class VanChartCustomPlotUITabGroup extends UITabGroup{ } @Override - protected void initButton(UIToggleButton labelButton) { + protected void initButton(UIToggleButton labelButton, int buttonIndex) { int ButtonWidth = WIDTH / 3; if (listNum <= 1){ diff --git a/designer-realize/src/main/java/com/fr/design/report/ReportColumnsPane.java b/designer-realize/src/main/java/com/fr/design/report/ReportColumnsPane.java index f1897e148e..3d9ba00e00 100644 --- a/designer-realize/src/main/java/com/fr/design/report/ReportColumnsPane.java +++ b/designer-realize/src/main/java/com/fr/design/report/ReportColumnsPane.java @@ -99,10 +99,10 @@ public class ReportColumnsPane extends BasicPane{ onOffButtonGroup = new UIButtonGroup(textArray) { @Override - protected void initButton(UIToggleButton labelButton) { + protected void initButton(UIToggleButton labelButton, int index) { labelButton.setSize(new Dimension(60,20)); labelButton.setPreferredSize(new Dimension(60, 20)); - super.initButton(labelButton); + super.initButton(labelButton, index); } }; onOffButtonGroup.addActionListener(onOffListener);