Browse Source

Merge remote-tracking branch 'origin/newui' into newui

newui
Leo.Qin 11 months ago
parent
commit
5d76adc33a
  1. 42
      designer-base/src/main/java/com/fine/theme/light/ui/FineButtonBorder.java
  2. 7
      designer-base/src/main/java/com/fine/theme/light/ui/FineButtonGroupUI.java
  3. 114
      designer-base/src/main/java/com/fine/theme/light/ui/FineButtonUI.java
  4. 90
      designer-base/src/main/java/com/fine/theme/light/ui/FineCombinationButtonUI.java
  5. 2
      designer-base/src/main/java/com/fine/theme/light/ui/FineLightIconSet.java
  6. 407
      designer-base/src/main/java/com/fine/theme/light/ui/FineTemplateTabPaneUI.java
  7. 56
      designer-base/src/main/java/com/fine/theme/light/ui/FineToggleButtonUI.java
  8. 2
      designer-base/src/main/java/com/fine/theme/light/ui/laf/FineLaf.java
  9. 88
      designer-base/src/main/java/com/fine/theme/utils/FineClientProperties.java
  10. 188
      designer-base/src/main/java/com/fine/theme/utils/FineUIUtils.java
  11. 693
      designer-base/src/main/java/com/fr/design/file/MultiTemplateTabPane.java
  12. 72
      designer-base/src/main/java/com/fr/design/gui/ibutton/UIButtonGroup.java
  13. 280
      designer-base/src/main/java/com/fr/design/gui/ibutton/UICombinationButton.java
  14. 1
      designer-base/src/main/java/com/fr/design/gui/ibutton/UIHeadGroup.java
  15. 2
      designer-base/src/main/java/com/fr/design/gui/ibutton/UITabGroup.java
  16. 1
      designer-base/src/main/java/com/fr/design/gui/itoolbar/UIToolbar.java
  17. 47
      designer-base/src/main/java/com/fr/design/mainframe/CenterRegionContainerPane.java
  18. 2
      designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java
  19. 6
      designer-base/src/main/java/com/fr/design/mainframe/JVirtualTemplate.java
  20. 11
      designer-base/src/main/resources/com/fine/theme/icon/clear_hover.svg
  21. 3
      designer-base/src/main/resources/com/fine/theme/icon/toolbar/more.svg
  22. 3
      designer-base/src/main/resources/com/fine/theme/icon/toolbar/more_disable.svg
  23. 10
      designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLaf.properties
  24. 126
      designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLightLaf.properties
  25. 130
      designer-base/src/test/java/com/fr/design/gui/storybook/components/ButtonStoryBoard.java
  26. 42
      designer-base/src/test/java/com/fr/design/gui/storybook/components/JTestTemplate.java
  27. 36
      designer-base/src/test/java/com/fr/design/gui/storybook/components/TemplateTabStoryBoard.java
  28. 2
      designer-chart/src/main/java/com/fr/van/chart/custom/component/VanChartCustomPlotUITabGroup.java
  29. 3
      designer-form/src/main/java/com/fr/design/mainframe/JForm.java
  30. 3
      designer-realize/src/main/java/com/fr/design/mainframe/JWorkBook.java
  31. 3
      designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/CellPresentPane.java
  32. 4
      designer-realize/src/main/java/com/fr/design/report/ReportColumnsPane.java
  33. 124
      designer-realize/src/main/java/com/fr/start/MainDesigner.java

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

7
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

114
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;
}
}

90
designer-base/src/main/java/com/fine/theme/light/ui/FineCombinationButtonUI.java

@ -0,0 +1,90 @@
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;
/**
* 双组件按钮UI
*
* @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;
}
}
}

2
designer-base/src/main/java/com/fine/theme/light/ui/FineLightIconSet.java

@ -165,6 +165,7 @@ public class FineLightIconSet extends AbstractIconSet {
new SvgIconSource("chart_line", "com/fine/theme/icon/chart/chart_line.svg", true),
new SvgIconSource("popup", "com/fine/theme/icon/popup/popup.svg", true),
new SvgIconSource("clear", "com/fine/theme/icon/clear.svg", true),
new SvgIconSource("clear_hover", "com/fine/theme/icon/clear_hover.svg", true),
// 工具栏
new SvgIconSource("tool_copy", "com/fine/theme/icon/toolbar/copy.svg", true),
@ -172,6 +173,7 @@ public class FineLightIconSet extends AbstractIconSet {
new SvgIconSource("move_up", "com/fine/theme/icon/toolbar/move_up.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),

407
designer-base/src/main/java/com/fine/theme/light/ui/FineTemplateTabPaneUI.java

@ -0,0 +1,407 @@
package com.fine.theme.light.ui;
import com.fine.theme.icon.LazyIcon;
import com.fine.theme.utils.FineClientProperties;
import com.fine.theme.utils.FineUIUtils;
import com.formdev.flatlaf.ui.FlatUIUtils;
import com.fr.base.GraphHelper;
import com.fr.base.vcs.DesignerMode;
import com.fr.design.file.MultiTemplateTabPane;
import com.fr.stable.collections.combination.Pair;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.PanelUI;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.geom.Path2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import static com.fine.theme.utils.FineUIScale.scale;
import static com.fine.theme.utils.FineUIUtils.paintRoundTabBorder;
import static com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
/**
* 文件Tab栏UI
*
* @author vito
* @since 11.0
* Created on 2023/12/27
*/
public class FineTemplateTabPaneUI extends PanelUI {
private MultiTemplateTabPane tabPane;
private static final String ELLIPSIS = "...";
private static final int ICON_TEXT_GAP = 4;
private static final int LEADING_WIDTH = 0;
private static final int TRAILING_WIDTH = 34;
@Styleable(dot = true)
protected Color background;
@Styleable(dot = true)
protected Color selectedBackground;
@Styleable(dot = true)
protected Color hoverColor;
@Styleable(dot = true)
protected Color closeIconHoverBackground;
@Styleable(dot = true)
protected Color closeHoverBackground;
@Styleable(dot = true)
protected Color borderColor;
@Styleable(dot = true)
protected int tabHeight;
@Styleable(dot = true)
protected int separatorHeight;
@Styleable(dot = true)
protected int borderWidth;
@Styleable(dot = true)
protected int tabArc;
@Styleable(dot = true)
protected Insets tabInsets;
protected Icon fileIcon;
protected Icon moreAction;
protected Icon addAction;
protected Icon moreHoverAction;
private Icon closeIcon;
private Icon closeHoverIcon;
private int leadingWidth;
private int trailingWidth;
protected FineTemplateTabPaneUI() {
}
/**
* 创建UI
*
* @param c 组件
* @return ComponentUI
*/
public static ComponentUI createUI(JComponent c) {
return new FineTemplateTabPaneUI();
}
@Override
public void installUI(JComponent c) {
super.installUI(c);
this.tabPane = (MultiTemplateTabPane) c;
closeIcon = new LazyIcon("clear");
closeHoverIcon = new LazyIcon("clear_hover");
addAction = new LazyIcon("add_worksheet");
moreAction = new LazyIcon("tool_more");
moreHoverAction = new LazyIcon("clear_hover");
fileIcon = new LazyIcon("cpt_icon");
FineClientProperties.setStyle(tabPane, "Default");
leadingWidth = scale(LEADING_WIDTH);
trailingWidth = scale(TRAILING_WIDTH);
borderWidth = FineUIUtils.getUIInt("TemplateTabPane.borderWidth", "TemplateTabPane.borderWidth");
tabArc = FineUIUtils.getUIInt("TemplateTabPane.tabArc", "TemplateTabPane.tabArc");
background = FineUIUtils.getUIColor("TemplateTabPane.background", "TabbedPane.background");
selectedBackground = FineUIUtils.getUIColor("TemplateTabPane.selectedBackground", "TemplateTabPane.selectedBackground");
closeHoverBackground = FineUIUtils.getUIColor("TemplateTabPane.closeHoverBackground", "TemplateTabPane.closeHoverBackground");
borderColor = FineUIUtils.getUIColor("TemplateTabPane.borderColor", "TabbedPane.tabSeparatorColor");
hoverColor = FineUIUtils.getUIColor("TemplateTabPane.hoverColor", "TemplateTabPane.hoverColor");
closeIconHoverBackground = FineUIUtils.getUIColor("TemplateTabPane.icon.hoverBackground ", "TemplateTabPane.icon.hoverBackground ");
// ---- scaled ----
tabInsets = FineUIUtils.getAndScaleUIInsets("TemplateTabPane.tabInsets", new Insets(4, 6, 4, 6));
tabHeight = FineUIUtils.getAndScaleInt("TemplateTabPane.tabHeight", "TabbedPane.tabHeight");
separatorHeight = FineUIUtils.getAndScaleInt("TemplateTabPane.separatorHeight", "TemplateTabPane.separatorHeight");
}
@Override
public void uninstallUI(JComponent c) {
super.uninstallUI(c);
}
@Override
public void update(Graphics g, JComponent c) {
super.update(g, c);
double maxWidth = c.getWidth() - leadingWidth - trailingWidth;
Graphics2D g2d = (Graphics2D) g;
paintDefaultBackground(g2d);
paintPaneUnderLine(c.getWidth(), g2d);
paintTabs(g2d, maxWidth);
}
private void paintDefaultBackground(Graphics2D g2d) {
//画默认背景
g2d.setPaint(new GradientPaint(0, 0, tabPane.getBackground(), 1, (float) (tabHeight), tabPane.getBackground()));
g2d.fillRect(0, 0, tabPane.getWidth(), tabHeight);
}
private void paintPaneUnderLine(float w, Graphics2D g2d) {
g2d.setPaint(borderColor);
float h = (float) tabHeight;
int t = scale(borderWidth);
Path2D border = new Path2D.Float(Path2D.WIND_EVEN_ODD);
border.append(FlatUIUtils.createComponentRectangle(0, 0, w, h, 0), false);
border.append(FlatUIUtils.createComponentRectangle(0, 0, w, h - t, 0), false);
g2d.fill(border);
}
private void paintTabs(Graphics2D g2d, double maxWidth) {
int maxStringlength = calculateStringMaxLength();
if (tabPane.getSelectedIndex() >= tabPane.getTabCount()) {
tabPane.setSelectedIndex(tabPane.getTabCount() - 1);
}
if (tabPane.getSelectedIndex() < 0) {
tabPane.setSelectedIndex(0);
}
double templateStartX = leadingWidth;
//从可以开始展示在tab面板上的tab开始画
Pair<Integer, Integer> viewRange = tabPane.getViewRange();
for (int i = viewRange.getFirst(); i <= viewRange.getSecond(); i++) {
Icon icon = tabPane.getTemplateIconByIndex(i);
String name = tabPane.getTemplateShowNameByIndex(i);
//如果tab名字的长度大于最大能显示的英文字符长度,则进行省略号处理
if (getStringWidth(name) > maxStringlength) {
name = getEllipsisName(name, maxStringlength);
}
Icon tabcloseIcon = tabPane.isCloseCurrent(i) ? closeHoverIcon : closeIcon;
if (i == tabPane.getSelectedIndex()) {
paintSelectedTab(g2d, icon, templateStartX, name, tabcloseIcon);
} else {
paintUnSelectedTab(g2d, icon, templateStartX, name, tabcloseIcon,
tabPane.getHoverIndex(), i);
}
templateStartX += tabPane.getTabWidth();
}
paintSeparators(g2d);
if (!DesignerMode.isVcsMode()) {
paintTrailingAction(g2d, maxWidth);
}
}
private void paintSeparators(Graphics2D g2d) {
g2d.setPaint(borderColor);
float x = leadingWidth;
Pair<Integer, Integer> viewRange = tabPane.getViewRange();
for (int i = viewRange.getFirst(); i <= viewRange.getSecond(); i++) {
if (i != tabPane.getSelectedIndex()
&& i + 1 != tabPane.getSelectedIndex()) {
paintSeparator(g2d, x);
}
x += tabPane.getTabWidth();
}
}
private void paintLeadingAction(Graphics2D g2d, double tabPaneWidth) {
int x = (leadingWidth - addAction.getIconWidth()) / 2;
int y = (tabHeight - addAction.getIconHeight()) / 2;
if (tabPane.isHoverMoreAction()) {
closeHoverIcon.paintIcon(tabPane, g2d, x, y);
} else {
addAction.paintIcon(tabPane, g2d, x, y);
}
}
private void paintTrailingAction(Graphics2D g2d, double tabPaneWidth) {
int x = leadingWidth + (int) tabPaneWidth + (trailingWidth - moreAction.getIconWidth()) / 2;
int y = (tabHeight - moreAction.getIconHeight()) / 2;
if (tabPane.isHoverMoreAction()) {
closeHoverIcon.paintIcon(tabPane, g2d, x, y);
} else {
moreAction.paintIcon(tabPane, g2d, x, y);
}
}
/**
* 判断tab文字的长度大于能装下的最大文字长度要用省略号
*
* @param name
* @param maxStringlength
* @return
*/
private String getEllipsisName(String name, int maxStringlength) {
int ellipsisWidth = getStringWidth(ELLIPSIS);
int leftkeyPoint = 0;
int rightKeyPoint = name.length() - 1;
int leftStrWidth = 0;
int rightStrWidth = 0;
while (leftStrWidth + rightStrWidth + ellipsisWidth < maxStringlength) {
if (leftStrWidth <= rightStrWidth) {
leftkeyPoint++;
} else {
rightKeyPoint--;
}
leftStrWidth = getStringWidth(name.substring(0, leftkeyPoint));
rightStrWidth = getStringWidth(name.substring(rightKeyPoint));
if (leftStrWidth + rightStrWidth + ellipsisWidth > maxStringlength) {
if (leftStrWidth <= rightStrWidth) {
rightKeyPoint++;
} else {
leftkeyPoint--;
}
break;
}
}
return name.substring(0, leftkeyPoint) + ELLIPSIS + name.substring(rightKeyPoint);
}
/**
* 计算过长度之后的每个tab的能接受的文字的英文字符数
*
* @return
*/
private int calculateStringMaxLength() {
return tabPane.getTabWidth()
- tabInsets.left - tabInsets.right
- ICON_TEXT_GAP * 2
- fileIcon.getIconWidth() - closeIcon.getIconWidth();
}
private int getStringWidth(String str) {
FontMetrics fm = GraphHelper.getFontMetrics(tabPane.getFont());
int size = 0;
for (int i = 0; i < str.length(); i++) {
size += fm.charWidth(str.codePointAt(i));
}
return size;
}
/**
* 画选中的tab
*
* @param g2d
* @param sheeticon
* @param templateStartX
* @param sheetName
* @param closeIcon
* @return
*/
private void paintSelectedTab(Graphics2D g2d, Icon sheeticon, double templateStartX, String sheetName, Icon closeIcon) {
Object[] oriRenderingHints = FlatUIUtils.setRenderingHints(g2d);
// 绘制选中背景
g2d.setPaint(selectedBackground);
Path2D tabShape = FineUIUtils.createTopRoundRectangle(templateStartX, 0,
tabPane.getTabWidth(), tabHeight, tabArc);
g2d.fill(tabShape);
// 绘制选中边框
g2d.setPaint(borderColor);
paintRoundTabBorder(g2d, templateStartX, 0,
tabPane.getTabWidth(), tabHeight, borderWidth, (float) tabArc);
FlatUIUtils.resetRenderingHints(g2d, oriRenderingHints);
// 绘制图标
int sheetIconY = (tabHeight - sheeticon.getIconHeight()) / 2;
sheeticon.paintIcon(tabPane, g2d, (int) templateStartX + tabInsets.left, sheetIconY);
// 绘制字符
g2d.setPaint(tabPane.getForeground());
Point2D.Double textPoint = calTextPoint(templateStartX, sheeticon.getIconWidth());
g2d.drawString(sheetName, (int) textPoint.x, (int) textPoint.y);
int closePosition = (int) templateStartX + tabPane.getTabWidth()
- this.closeIcon.getIconWidth() - tabInsets.right;
int closeY = (tabHeight - closeIcon.getIconHeight()) / 2;
if (!DesignerMode.isVcsMode()) {
closeIcon.paintIcon(tabPane, g2d, closePosition, closeY);
}
}
private Point2D.Double calTextPoint(double x, int iconWidth) {
FontMetrics fm = tabPane.getFontMetrics(tabPane.getFont());
int ascent = fm.getAscent();
int gap = (tabHeight - tabInsets.top - tabInsets.bottom - ascent) / 2;
double y = tabInsets.top + ascent + gap;
return new Point2D.Double(x + iconWidth + tabInsets.left + ICON_TEXT_GAP, y);
}
/**
* 画没有选中的tab
*
* @param g2d
* @param sheeticon
* @param templateStartX
* @param sheetName
* @param closeIcon
*/
private void paintUnSelectedTab(Graphics2D g2d, Icon sheeticon, double templateStartX, String sheetName, Icon closeIcon, int mouseOveredIndex, int selfIndex) {
if (selfIndex == mouseOveredIndex) {
g2d.setPaint(hoverColor);
} else {
g2d.setPaint(background);
}
Object[] oriRenderingHints = FlatUIUtils.setRenderingHints(g2d);
Path2D tabShape = FineUIUtils.createTopRoundRectangle(templateStartX, 0,
tabPane.getTabWidth(), tabHeight - scale(borderWidth), tabArc);
g2d.fill(tabShape);
FlatUIUtils.resetRenderingHints(g2d, oriRenderingHints);
int sheetIconY = (tabHeight - sheeticon.getIconHeight()) / 2;
sheeticon.paintIcon(tabPane, g2d, (int) templateStartX + tabInsets.left, sheetIconY);
// 画字符
g2d.setPaint(tabPane.getForeground());
Point2D.Double textPoint = calTextPoint(templateStartX, sheeticon.getIconWidth());
g2d.drawString(sheetName, (int) textPoint.x, (int) textPoint.y);
int closeY = (tabHeight - closeIcon.getIconHeight()) / 2;
int closePosition = (int) templateStartX + tabPane.getTabWidth()
- this.closeIcon.getIconWidth() - tabInsets.right;
if (!DesignerMode.isVcsMode()) {
closeIcon.paintIcon(tabPane, g2d, closePosition, closeY);
}
}
private void paintSeparator(Graphics2D g2d, float templateStartX) {
float x = templateStartX + tabPane.getTabWidth();
float gap = (tabHeight - separatorHeight) / 2.0f;
g2d.fill(new Rectangle2D.Float(x, gap, scale(borderWidth), tabHeight - gap * 2));
}
@Override
public Dimension getPreferredSize(JComponent c) {
return new Dimension(c.getWidth(), tabHeight);
}
@Override
public Dimension getMinimumSize(JComponent c) {
return new Dimension(0, tabHeight);
}
@Override
public Dimension getMaximumSize(JComponent c) {
return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
}
}

56
designer-base/src/main/java/com/fine/theme/light/ui/FineToggleButtonUI.java

@ -6,6 +6,7 @@ import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
import com.formdev.flatlaf.ui.FlatToggleButtonUI;
import com.formdev.flatlaf.ui.FlatUIUtils;
import com.fr.design.gui.ibutton.UIButton;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.AbstractButton;
@ -17,12 +18,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 +87,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,13 +150,49 @@ 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 = getGroupButtonPath2D(c, position, arc);
g2.fill(path2D);
}
} finally {
g2.dispose();
}
}
@NotNull
private static Shape getGroupButtonPath2D(JComponent c, int position, float arc) {
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();
}
return path2D;
}
@Override
protected Color getForeground(JComponent c) {
if (isGroupButton(c) && ((AbstractButton)c).isSelected()) {

2
designer-base/src/main/java/com/fine/theme/light/ui/laf/FineLaf.java

@ -22,7 +22,7 @@ public abstract class FineLaf extends FlatLaf {
public String getName() {
return NAME;
}
@Override
public String getDescription() {
return "Fine New Look and Feel";

88
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中使用的各类属性
*
@ -11,6 +14,91 @@ import com.formdev.flatlaf.FlatClientProperties;
*/
public interface FineClientProperties extends FlatClientProperties {
//--------------------------- ButtonGroup -----------------------
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该方法会接在原样式后方
* <code>
* FineClientProperties.appendStyle("primary small")
* </code>
*
* @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该方法会替换原样式
* <code>
* FineClientProperties.setStyle("primary small")
* </code>
*
* @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;
}
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;
}

188
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,185 @@ 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 - t, arc - t), false);
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;
}
/**
* 创建一个左圆角矩形路径
*
* @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) {
return createPartRoundRectangle(x, y, width, height, arc, 0, 0, arc);
}
/**
* 创建一个右圆角矩形路径
*
* @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) {
return createPartRoundRectangle(x, y, width, height, 0, arc, arc, 0);
}
/**
* 创建一个顶圆角矩形路径
*
* @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) {
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);
}
}

693
designer-base/src/main/java/com/fr/design/file/MultiTemplateTabPane.java

@ -1,8 +1,7 @@
package com.fr.design.file;
import com.fr.base.GraphHelper;
import com.fr.base.svg.IconUtils;
import com.fine.theme.icon.LazyIcon;
import com.fr.base.vcs.DesignerMode;
import com.fr.design.actions.UpdateAction;
import com.fr.design.actions.file.LocateAction;
@ -15,67 +14,45 @@ import com.fr.design.i18n.DesignSizeI18nManager;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.mainframe.TemplateSavingChecker;
import com.fr.design.mainframe.manager.search.TemplateTreeSearchManager;
import com.fr.design.utils.DesignUtils;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.design.utils.gui.GUIPaintUtils;
import com.fr.design.worker.WorkerManager;
import com.fr.design.worker.save.CallbackSaveWorker;
import com.fr.file.FILE;
import com.fr.file.FileNodeFILE;
import com.fr.general.ComparatorUtils;
import com.fr.general.IOUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.Constants;
import com.fr.stable.collections.combination.Pair;
import com.fr.third.javax.annotation.Nonnull;
import com.fr.workspace.WorkContext;
import com.fr.workspace.server.lock.TplOperator;
import javax.swing.BorderFactory;
import javax.swing.ButtonModel;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.MenuElement;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.ToolTipManager;
import javax.swing.plaf.basic.BasicMenuItemUI;
import java.awt.AWTEvent;
import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.AWTEventListener;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.GeneralPath;
import java.awt.geom.Line2D;
import java.awt.geom.Path2D;
import java.awt.geom.RoundRectangle2D;
import java.awt.event.MouseMotionAdapter;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static com.fine.theme.utils.FineUIScale.scale;
import static com.fr.design.dialog.FineJOptionPane.showConfirmDialog;
import static javax.swing.JOptionPane.OK_CANCEL_OPTION;
import static javax.swing.JOptionPane.OK_OPTION;
import static javax.swing.JOptionPane.WARNING_MESSAGE;
// todo: 自己绘制组件
/**
* 改个名字一个拼写 n 个错误
*
@ -84,28 +61,14 @@ import static javax.swing.JOptionPane.WARNING_MESSAGE;
* <p>
* created by daisy on 2013/08/05
**/
public class MultiTemplateTabPane extends JComponent {
private static Icon LIST_DOWN = IconUtils.readIcon("/com/fr/design/standard/list/list");
private static Icon MOUSE_OVER_LIST_DOWN = IconUtils.readIcon("/com/fr/design/standard/list/list_pressed.svg");
private static Icon MOUSE_PRESS_LIST_DOWN = IconUtils.readIcon("/com/fr/design/standard/list/list_pressed.svg");
private static Icon CLOSE = IconUtils.readIcon("/com/fr/design/standard/close/close");
private static Icon MOUSE_OVER_CLOSE = IconUtils.readIcon("/com/fr/design/standard/close/close_mouseover.svg");
private static Icon MOUSE_PRESS_CLOSE = IconUtils.readIcon("/com/fr/design/standard/close/close_press.svg");
private static final Icon WHITE_SAVING_CLOSE_ICON = new ImageIcon(IOUtils.readImage("/com/fr/design/images/file/white_saving_close.gif"));
private static final Icon GREY_SAVING_CLOSE_ICON = new ImageIcon(IOUtils.readImage("/com/fr/design/images/file/grey_saving_close.gif"));
private static final String ELLIPSIS = "...";
private static final int GAP = 5;
private static final int SMALLGAP = 3;
private static final int LIST_BUTTON_WIDTH = 34;
private static final int HEIGHT = 26;
private static final int LIST_DOWN_HEIGHT = 25;
private static final double CORNOR_RADIUS = 0.0;
//选了30度和60度的特殊角度的x,y作为经过的两个点的坐标
private static final double SPECIAL_LOCATION_1 = 2.5;
private static final double SPECIAL_LOCATION_2 = 4.330127;
private static final int ICON_WIDTH = 22;
public class MultiTemplateTabPane extends JPanel {
private static final String UI_CLASS_ID = "TemplateTabPaneUI";
private static final int GAP = 6;
private static final int SMALLGAP = 4;
private static final int TRAILING_WIDTH = 34;
private static final int LEADING_WIDTH = 38;
//每个标签页的最大的长度和最小长度。这些长度均为均分
@ -122,8 +85,7 @@ public class MultiTemplateTabPane extends JComponent {
private int mouseOveredIndex = -1;
//tab栏可以放下的每个tab的实际宽度
private int realWidth = MAXWIDTH;
private int tabWidth;
//当前标签页栏存放的所有标签页的index
private int minPaintIndex = 0;
@ -132,13 +94,12 @@ public class MultiTemplateTabPane extends JComponent {
//每个关闭图标的起始位置
private int[] startX;
private boolean[] isNeedToolTips;
//记录关闭按钮的状态
private int closeIconIndex = -1;
private boolean isCloseCurrent = false;
private Icon clodeMode = CLOSE;
private Icon listDownMode = LIST_DOWN;
private boolean hoverMoreAction = false;
private Icon clodeIcon = new LazyIcon("clear");
private boolean isShowList = false;
//自动新建的模板B若没有进行任何编辑,切换到其他
@ -146,10 +107,14 @@ public class MultiTemplateTabPane extends JComponent {
// 模板时,模板B会自动关闭
private JTemplate<?, ?> temTemplate = null;
// private final Color selectedColor = UIManager.getColor("TabbedPane.hoverColor");
// private Color hoverColor = UIManager.getColor("TabbedPane.inactiveUnderlineColor");
@Override
public String getUIClassID() {
return UI_CLASS_ID;
}
/**
* 单例
*/
public static MultiTemplateTabPane getInstance() {
if (THIS == null) {
THIS = new MultiTemplateTabPane();
@ -162,27 +127,19 @@ public class MultiTemplateTabPane extends JComponent {
* 多工作簿面板
*/
public MultiTemplateTabPane() {
this.setLayout(new BorderLayout(0, 0));
this.addMouseListener(new MultiTemplateTabMouseListener());
this.addMouseMotionListener(new MultiTemplateTabMouseMotionListener());
this.setBorder(null);
// this.setForeground(new Color(58, 56, 58));
this.setFont(DesignUtils.getDefaultGUIFont().applySize(12));
openedTemplate = HistoryTemplateListCache.getInstance().getHistoryList();
selectedIndex = openedTemplate.size() - 1;
AWTEventListener awt = new AWTEventListener() {
@Override
public void eventDispatched(AWTEvent event) {
if (event instanceof MouseEvent) {
MouseEvent mv = (MouseEvent) event;
if (mv.getClickCount() > 0 && !ComparatorUtils.equals(mv.getSource(), MultiTemplateTabPane.this)) {
isShowList = false;
}
java.awt.Toolkit.getDefaultToolkit().addAWTEventListener(event -> {
if (event instanceof MouseEvent) {
MouseEvent mv = (MouseEvent) event;
if (mv.getClickCount() > 0 && !ComparatorUtils.equals(mv.getSource(), MultiTemplateTabPane.this)) {
isShowList = false;
}
}
};
java.awt.Toolkit.getDefaultToolkit().addAWTEventListener(awt, AWTEvent.MOUSE_EVENT_MASK);
}, AWTEvent.MOUSE_EVENT_MASK);
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
@ -229,6 +186,7 @@ public class MultiTemplateTabPane extends JComponent {
/**
* 判断模板是否可以关闭两个条件1是否满足CloseOption里面的条件在左侧在右侧等2是否和当前正在编辑模板属于同一种模板tab操作类型
*
* @param closeJTemplate
* @param tplIndex
* @param i
@ -369,7 +327,7 @@ public class MultiTemplateTabPane extends JComponent {
if (openedTemplate.size() == 0) {
DesignerContext.getDesignerFrame().addAndActivateJTemplate();
} else if (option == CloseOption.All){
} else if (option == CloseOption.All) {
//openedTemplate(0)是JVirtualTemplate时需重新打开
openedTemplate.get(0).activeOldJTemplate();
} else {
@ -417,9 +375,10 @@ public class MultiTemplateTabPane extends JComponent {
/**
* 关闭所有指定模板tab操作类型的模板
*
* @param operatorType
*/
public void closeOtherByOperatorType(String operatorType){
public void closeOtherByOperatorType(String operatorType) {
JTemplate<?, ?> currentEditingTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
SaveSomeTemplatePane saveSomeTempaltePane = new SaveSomeTemplatePane(false);
if (saveSomeTempaltePane.showSavePane(null, false, true)) {
@ -438,6 +397,7 @@ public class MultiTemplateTabPane extends JComponent {
/**
* 关闭指定的非当前编辑模板
*
* @param templates
* @param operatorType
*/
@ -471,91 +431,19 @@ public class MultiTemplateTabPane extends JComponent {
}
@Override
public Dimension getPreferredSize() {
Dimension dimension = super.getPreferredSize();
dimension.height = HEIGHT;
return dimension;
}
private UIMenuItem initCloseOther() {
UIMenuItem closeOther = new UIMenuItem(Toolkit.i18nText("Fine-Design_Basic_FS_Close_Other_Templates"));
// Yvan: 英文下文本显示不全,后续发现如果将模板名设置的比较短,其它语言也会出现显示不全的问题,所以设置一下文本水平居中
closeOther.setHorizontalAlignment(SwingConstants.CENTER);
setListDownItemPreferredSize(closeOther);
closeOther.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (openedTemplate.size() == 1) {
return;
}
if (!TemplateSavingChecker.check()) {
return;
}
SaveSomeTemplatePane saveSomeTempaltePane = new SaveSomeTemplatePane(false);
//点击关闭其他模板,并且点击确定保存
if (saveSomeTempaltePane.showSavePane()) {
JTemplate<?, ?>[] panes = new JTemplate<?, ?>[openedTemplate.size()];
for (int i = 0; i < openedTemplate.size(); i++) {
panes[i] = openedTemplate.get(i);
}
for (int i = 0; i < panes.length; i++) {
if (i != selectedIndex) {
JTemplate<?, ?> jTemplate = panes[i];
//判断关闭的模板是不是格式刷的被参照的模板
openedTemplate.remove(jTemplate);
closeFormat(jTemplate);
HistoryTemplateListCache.getInstance().closeSelectedReport(jTemplate);
closeAndFreeLock(jTemplate);
}
}
JTemplate<?, ?> currentTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
HistoryTemplateListCache.getInstance().removeAllHistory();
DesignerContext.getDesignerFrame().activateJTemplate(currentTemplate);
THIS.repaint();
}
//如果取消保存了,则不关闭其他模板
}
});
if (openedTemplate.size() == 1) {
closeOther.setEnabled(false);
}
return closeOther;
}
private UIMenuItem[] createListDownTemplate() {
UIMenuItem[] templates = new UIMenuItem[openedTemplate.size()];
for (int i = 0; i < openedTemplate.size(); i++) {
final int index = i;
final JTemplate tem = openedTemplate.get(i);
templates[i] = new UIMenuItem(tempalteShowName(tem), tem.getIcon());
// templates[i].setUI(new UIListDownItemUI());
setListDownItemPreferredSize(templates[i]);
if (i == selectedIndex) {
//画选中的高亮
// templates[i].setBackground(UIConstants.SHADOW_CENTER);
}
templates[i].addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
selectedIndex = index;
tem.activeNewJTemplate();
}
});
}
return templates;
private String tempalteShowName(JTemplate<?, ?> template) {
return template.getTabShowName(template);
}
private void setListDownItemPreferredSize(UIMenuItem item) {
Dimension dimension = item.getPreferredSize();
dimension.height = LIST_DOWN_HEIGHT;
item.setPreferredSize(dimension);
public String getTemplateShowNameByIndex(int index) {
JTemplate template = openedTemplate.get(index);
return template.getTabShowName(template);
}
private String tempalteShowName(JTemplate<?, ?> template) {
return template.getTabShowName(template);
public Icon getTemplateIconByIndex(int index) {
JTemplate template = openedTemplate.get(index);
return template.getIcon();
}
/**
@ -585,145 +473,23 @@ public class MultiTemplateTabPane extends JComponent {
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
double maxWidth = getWidth() - LIST_BUTTON_WIDTH * 1.0D; //最大宽度
Graphics2D g2d = (Graphics2D) g;
paintBackgroundAndLine(g2d, maxWidth);
}
@Override
public void paint(Graphics g) {
//不可见时,按钮.4f透明
AlphaComposite composite = DesignerMode.isVcsMode()
? AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.4f)
: (AlphaComposite) ((Graphics2D) g).getComposite();
((Graphics2D) g).setComposite(composite);
super.paint(g);
}
private void paintBackgroundAndLine(Graphics2D g2d, double maxWidth) {
paintDefaultBackground(g2d);
//最多能画的个数
int maxTemplateNum = (int) (maxWidth) / MINWIDTH;
//计算开始画的最小模板index和最大模板index
double maxWidth = getWidth() - scale(TRAILING_WIDTH) - scale(LEADING_WIDTH); //最大宽度
int maxTemplateNum = (int) (maxWidth) / scale(MINWIDTH);
calMinAndMaxIndex(maxTemplateNum);
calculateRealAverageWidth(maxWidth, maxTemplateNum);
int maxStringlength = calculateStringMaxLength();
if (selectedIndex >= openedTemplate.size()) {
selectedIndex = openedTemplate.size() - 1;
}
if (selectedIndex < 0) {
selectedIndex = 0;
}
double templateStartX = 0;
startX = new int[maxPaintIndex - minPaintIndex + 1];
isNeedToolTips = new boolean[maxPaintIndex - minPaintIndex + 1];
//从可以开始展示在tab面板上的tab开始画
for (int i = minPaintIndex; i <= maxPaintIndex; i++) {
JTemplate template = openedTemplate.get(i);
if (!showJTemplateTab(template)){
continue;
}
Icon icon = template.getIcon();
String name = tempalteShowName(template);
//如果tab名字的长度大于最大能显示的英文字符长度,则进行省略号处理
if (getStringWidth(name) > maxStringlength) {
name = getEllipsisName(name, maxStringlength);
isNeedToolTips[i - minPaintIndex] = true;
} else {
isNeedToolTips[i - minPaintIndex] = false;
}
Icon selectedIcon;
if (i == closeIconIndex) {
selectedIcon = clodeMode;
} else {
selectedIcon = CLOSE;
}
if (i == selectedIndex) {
if (template.isSaving()) {
selectedIcon = WHITE_SAVING_CLOSE_ICON;
}
startX[i - minPaintIndex] = paintSelectedTab(g2d, icon, templateStartX, name, selectedIcon);
} else {
if (template.isSaving()) {
selectedIcon = GREY_SAVING_CLOSE_ICON;
}
boolean isLeft = i < selectedIndex;
startX[i - minPaintIndex] = paintUnSelectedTab(g2d, icon, templateStartX, name, selectedIcon, isLeft, mouseOveredIndex, i);
}
templateStartX += realWidth;
}
if (!DesignerMode.isVcsMode()) {
paintListDown(g2d, maxWidth);
}
paintUnderLine(templateStartX, maxWidth, g2d);
}
private void paintUnderLine(double templateStartX, double maxWidth, Graphics2D g2d) {
//画下面的那条线
if (templateStartX < maxWidth) {
GeneralPath generalPath = new GeneralPath(Path2D.WIND_EVEN_ODD, 2);
generalPath.moveTo((float) templateStartX, (float) (getHeight() - 1.0D));
generalPath.lineTo((float) maxWidth, (float) (getHeight() - 1.0D));
g2d.fill(generalPath);
//TODO hzzz delete
// g2d.setPaint(UIConstants.LINE_COLOR);
// g2d.draw(new Line2D.Double((float) templateStartX, getHeight() - 1, (float) maxWidth + LIST_BUTTON_WIDTH, getHeight() - 1));
}
}
private void paintDefaultBackground(Graphics2D g2d) {
//画默认背景
g2d.setPaint(new GradientPaint(1, 1, getBackground(), 1, (float) (getHeight() - 1.0D), getBackground()));
g2d.fillRect(0, 0, getWidth(), getHeight());
}
private void paintListDown(Graphics2D g2d, double maxWidth) {
int x = (int) maxWidth + (LIST_BUTTON_WIDTH - listDownMode.getIconWidth()) / 2;
int y = (getHeight() - listDownMode.getIconHeight()) / 2;
listDownMode.paintIcon(this, g2d, x, y);
calculateClosePosition();
super.paintComponent(g);
}
/**
* 判断tab文字的长度大于能装下的最大文字长度要用省略号
*
* @param name
* @param maxStringlength
* @return
*/
private String getEllipsisName(String name, int maxStringlength) {
//若是名字长度大于能显示的长度,那能显示的文字的最大长度还要减去省略号的最大长度
// int maxellipsislength = maxStringlength - ELLIPSIS.length();
int ellipsisWidth = getStringWidth(ELLIPSIS);
int leftkeyPoint = 0;
int rightKeyPoint = name.length() - 1;
int leftStrWidth = 0;
int rightStrWidth = 0;
while (leftStrWidth + rightStrWidth + ellipsisWidth < maxStringlength) {
if (leftStrWidth <= rightStrWidth) {
leftkeyPoint++;
} else {
rightKeyPoint--;
}
leftStrWidth = getStringWidth(name.substring(0, leftkeyPoint));
rightStrWidth = getStringWidth(name.substring(rightKeyPoint));
if (leftStrWidth + rightStrWidth + ellipsisWidth > maxStringlength) {
if (leftStrWidth <= rightStrWidth) {
rightKeyPoint++;
}
break;
}
private void calculateClosePosition() {
startX = new int[maxPaintIndex - minPaintIndex + 1];
double templateStartX = scale(LEADING_WIDTH);
for (int i = getViewRange().getFirst(); i <= getViewRange().getSecond(); i++) {
int closePosition = (int) templateStartX + getTabWidth() - clodeIcon.getIconWidth() - GAP;
startX[i - minPaintIndex] = closePosition;
templateStartX += getTabWidth();
}
return name.substring(0, leftkeyPoint) + ELLIPSIS + name.substring(rightKeyPoint);
}
private void calMinAndMaxIndex(int maxTemplateNum) {
@ -766,9 +532,10 @@ public class MultiTemplateTabPane extends JComponent {
/**
* 先计算出需要补充的tab个数
*
* @return
*/
private int calTabCountComplemented(){
private int calTabCountComplemented() {
int a = 0;
for (int i = minPaintIndex; i <= maxPaintIndex; i++) {
JTemplate template = openedTemplate.get(i);
@ -783,9 +550,9 @@ public class MultiTemplateTabPane extends JComponent {
/**
* 由于可能存在宽度为0的tab所以这边需要重新check下先往后补再往前补
*/
private void checkActualPaintIndex(){
private void checkActualPaintIndex() {
int tabCount = calTabCountComplemented();
if (tabCount == 0){
if (tabCount == 0) {
return;
}
if (maxPaintIndex < openedTemplate.size() - 1) {
@ -795,19 +562,19 @@ public class MultiTemplateTabPane extends JComponent {
tabCount--;
}
maxPaintIndex++;
if (tabCount == 0){
if (tabCount == 0) {
return;
}
}
}
if (minPaintIndex > 0){
if (minPaintIndex > 0) {
for (int i = minPaintIndex - 1; i >= 0; i--) {
JTemplate template = openedTemplate.get(i);
if (showJTemplateTab(template)) {
tabCount--;
}
minPaintIndex--;
if (tabCount == 0){
if (tabCount == 0) {
return;
}
}
@ -821,170 +588,15 @@ public class MultiTemplateTabPane extends JComponent {
List<JTemplate<?, ?>> showTemplates = getOpenedJTemplatesByOperator(jTemplate.getTemplateTabOperatorType());
int num = Math.min(showTemplates.size(), templateNum);
realWidth = (int) (maxwidth / (num));
if (realWidth > MAXWIDTH) {
realWidth = MAXWIDTH;
} else if (realWidth < MINWIDTH) {
tabWidth = (int) (maxwidth / (num));
if (tabWidth > scale(MAXWIDTH)) {
tabWidth = scale(MAXWIDTH);
} else if (tabWidth < scale(MINWIDTH)) {
//平均下来每个的宽度小于最小宽度
realWidth = MINWIDTH;
}
}
/**
* 计算过长度之后的每个tab的能接受的文字的英文字符数
*
* @return
*/
private int calculateStringMaxLength() {
return realWidth - 3 * GAP - ICON_WIDTH - SMALLGAP - CLOSE.getIconWidth();
}
private int getStringWidth(String str) {
return GraphHelper.getFontMetrics(this.getFont()).stringWidth(str);
}
/**
* 画选中的tab
*
* @param g2d
* @param sheeticon
* @param templateStartX
* @param sheetName
* @param closeIcon
* @return
*/
private int paintSelectedTab(Graphics2D g2d, Icon sheeticon, double templateStartX, String sheetName, Icon closeIcon) {
double[] x = {templateStartX, templateStartX, templateStartX + realWidth, templateStartX + realWidth, templateStartX};
double[] y = {1, getHeight() + 1, getHeight() + 1, 1, 1};
RoundRectangle2D.Double rect1 = new RoundRectangle2D.Double(templateStartX, 1, this.getWidth(), this.getHeight(), 7, 7);
g2d.setPaint(new GradientPaint(1, 1, getBackground(), (float) (getWidth() -1.0d), 1, getBackground()));
//选了30度和60度的特殊角度的x,y作为经过的两个点的坐标
double specialLocation1 = 2.5;
double specialLocation2 = 4.330127;
GeneralPath generalPath = new GeneralPath(Path2D.WIND_EVEN_ODD, x.length);
generalPath.moveTo((float) x[0] + CORNOR_RADIUS, (float) y[0]);
generalPath.curveTo(((float) x[0] + CORNOR_RADIUS - specialLocation1), (y[0] + CORNOR_RADIUS - specialLocation2), ((float) x[0] + CORNOR_RADIUS - specialLocation2), (y[0] + CORNOR_RADIUS - specialLocation1), x[0], y[0] + CORNOR_RADIUS);
for (int index = 1; index <= 2; index++) {
generalPath.lineTo((float) x[index], (float) y[index]);
}
generalPath.lineTo((float) x[3], (float) y[3] + CORNOR_RADIUS);
generalPath.curveTo(((float) x[3] - CORNOR_RADIUS + specialLocation1), ((float) y[3] + CORNOR_RADIUS - specialLocation2), ((float) x[3] - CORNOR_RADIUS + specialLocation2), ((float) y[3] + CORNOR_RADIUS - specialLocation1), (float) x[3] - CORNOR_RADIUS, (float) y[3]);
generalPath.lineTo((float) x[0] + CORNOR_RADIUS, (float) y[0]);
generalPath.closePath();
g2d.fill(generalPath);
// g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// g2d.setPaint(Color.red);
// g2d.draw(new Arc2D.Double(x[0], y[0], CORNOR_RADIUS * 2, CORNOR_RADIUS * 2, 90, 90, 0));
// g2d.draw(new Line2D.Double(x[0], y[0] + CORNOR_RADIUS, x[1], y[1]));
// g2d.draw(new Line2D.Double(x[1], y[1], x[2], y[2]));
// g2d.draw(new Line2D.Double(x[2], y[2], x[3], y[3] + CORNOR_RADIUS));
// g2d.draw(new Arc2D.Double(x[3] - CORNOR_RADIUS * 2, y[3], CORNOR_RADIUS * 2, CORNOR_RADIUS * 2, 90, -90, 0));
// g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
int sheetIconY = (getHeight() - sheeticon.getIconHeight()) / 2;
sheeticon.paintIcon(this, g2d, (int) templateStartX + GAP, sheetIconY);
// 画字符
g2d.setPaint(getForeground());
g2d.drawString(sheetName, (int) templateStartX + sheeticon.getIconWidth() + 2 * GAP, getHeight() - GAP * 2);
int closePosition = (int) templateStartX + realWidth - CLOSE.getIconWidth() - SMALLGAP;
int closeY = (getHeight() - closeIcon.getIconHeight()) / 2;
if (!DesignerMode.isVcsMode()) {
closeIcon.paintIcon(this, g2d, closePosition, closeY);
tabWidth = scale(MINWIDTH);
}
return closePosition;
}
/**
* 画没有选中的tab
*
* @param g2d
* @param sheeticon
* @param templateStartX
* @param sheetName
* @param closeIcon
* @param isLeft
* @return
*/
private int paintUnSelectedTab(Graphics2D g2d, Icon sheeticon, double templateStartX, String sheetName, Icon closeIcon, boolean isLeft, int mouseOveredIndex, int selfIndex) {
double[] x = {templateStartX, templateStartX, templateStartX + realWidth, templateStartX + realWidth, templateStartX};
double[] y = {-1, getHeight() - 1, getHeight() - 1, -1, -1};
if (selfIndex == mouseOveredIndex) {
g2d.setPaint(new GradientPaint(1, 1, getBackground(), 1, (float) (getHeight() - 1.0D), getBackground()));
} else {
g2d.setPaint(new GradientPaint(1, 1, getBackground(), 1, (float) (getHeight() - 1.0D), getBackground()));
}
GeneralPath generalPath = new GeneralPath(Path2D.WIND_EVEN_ODD, x.length);
unSelectedClosedPath(generalPath, isLeft, x, y);
g2d.fill(generalPath);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setPaint(UIConstants.TEMPLATE_TAB_PANE_BACKGROUND);
//TODO hzzz delete
// if (isLeft) {
// g2d.draw(new Arc2D.Double(x[0], y[0], CORNOR_RADIUS * 2, CORNOR_RADIUS * 2, 90, 90, 0));
// } else {
// g2d.draw(new Arc2D.Double(x[0] - CORNOR_RADIUS * 2, y[0], CORNOR_RADIUS * 2, CORNOR_RADIUS * 2, 90, -90, 0));
// }
// g2d.draw(new Line2D.Double(x[0], y[0] + CORNOR_RADIUS, x[1], y[1] + 1));
// g2d.draw(new Line2D.Double(x[1], y[1], x[2], y[2]));
g2d.draw(new Line2D.Double(x[2], y[2], x[3], y[3] + CORNOR_RADIUS));
// if (isLeft) {
// g2d.draw(new Arc2D.Double(x[3], y[3], CORNOR_RADIUS * 2, CORNOR_RADIUS * 2, 90, 90, 0));
// } else {
// g2d.draw(new Arc2D.Double(x[3] - CORNOR_RADIUS * 2, y[3], CORNOR_RADIUS * 2, CORNOR_RADIUS * 2, 90, -90, 0));
// }
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
int sheetIconY = (getHeight() - sheeticon.getIconHeight()) / 2;
sheeticon.paintIcon(this, g2d, (int) templateStartX + GAP, sheetIconY);
// 画字符
g2d.setPaint(getForeground());
g2d.drawString(sheetName, (int) templateStartX + sheeticon.getIconWidth() + 2 * GAP, getHeight() - GAP * 2);
int closeY = (getHeight() - closeIcon.getIconHeight()) / 2;
int closePosition = (int) templateStartX + realWidth - CLOSE.getIconWidth() - SMALLGAP;
if (!DesignerMode.isVcsMode()) {
closeIcon.paintIcon(this, g2d, closePosition, closeY);
}
return closePosition;
}
private void unSelectedClosedPath(GeneralPath generalPath, boolean isLeft, double[] x, double[] y) {
if (isLeft) {
generalPath.moveTo((float) x[0] + CORNOR_RADIUS, (float) y[0]);
generalPath.curveTo(((float) x[0] + CORNOR_RADIUS - SPECIAL_LOCATION_1), (y[0] + CORNOR_RADIUS - SPECIAL_LOCATION_2), ((float) x[0] + CORNOR_RADIUS - SPECIAL_LOCATION_2), (y[0] + CORNOR_RADIUS - SPECIAL_LOCATION_1), x[0], y[0] + CORNOR_RADIUS);
} else {
generalPath.moveTo((float) x[0] - CORNOR_RADIUS, (float) y[0]);
generalPath.curveTo(((float) x[0] - CORNOR_RADIUS + SPECIAL_LOCATION_1), (y[0] + CORNOR_RADIUS - SPECIAL_LOCATION_2), ((float) x[0] - CORNOR_RADIUS + SPECIAL_LOCATION_2), (y[0] + CORNOR_RADIUS - SPECIAL_LOCATION_1), x[0], y[0] + CORNOR_RADIUS);
}
for (int index = 1; index <= 2; index++) {
generalPath.lineTo((float) x[index], (float) y[index]);
}
generalPath.lineTo((float) x[3], (float) y[3] + CORNOR_RADIUS);
if (isLeft) {
generalPath.curveTo(((float) x[3] + CORNOR_RADIUS - SPECIAL_LOCATION_1), ((float) y[3] + CORNOR_RADIUS - SPECIAL_LOCATION_2), ((float) x[3] + CORNOR_RADIUS - SPECIAL_LOCATION_2), ((float) y[3] - CORNOR_RADIUS + SPECIAL_LOCATION_1), (float) x[3] + CORNOR_RADIUS, (float) y[3]);
generalPath.lineTo((float) x[0] + CORNOR_RADIUS, (float) y[0]);
} else {
generalPath.curveTo(((float) x[3] - CORNOR_RADIUS + SPECIAL_LOCATION_1), ((float) y[3] + CORNOR_RADIUS - SPECIAL_LOCATION_2), ((float) x[3] - CORNOR_RADIUS + SPECIAL_LOCATION_2), ((float) y[3] + CORNOR_RADIUS - SPECIAL_LOCATION_1), (float) x[3] - CORNOR_RADIUS, (float) y[3]);
generalPath.lineTo((float) x[0] - CORNOR_RADIUS, (float) y[0]);
}
generalPath.closePath();
}
public void setIsCloseCurrent(boolean isCloseCurrent) {
this.isCloseCurrent = isCloseCurrent;
@ -1107,19 +719,21 @@ public class MultiTemplateTabPane extends JComponent {
/**
* 计算下一个可以展示的模板index
*
* @param currentIndex
* @return
*/
public int calNextShowJTemplateIndex(int currentIndex) {
JTemplate jTemplate= HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
JTemplate jTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
return MultiTemplateTabUtils.calShowTemplateIndex(currentIndex, openedTemplate, jTemplate.getTemplateTabOperatorType());
}
private boolean isOverCloseIcon(int evtX) {
boolean isOverCloseIcon = false;
// todo
for (int i = 0; i < startX.length; i++) {
if (evtX >= startX[i] && evtX <= startX[i] + CLOSE.getIconWidth()) {
if (evtX >= startX[i] && evtX <= startX[i] + clodeIcon.getIconWidth()) {
isOverCloseIcon = true;
break;
}
@ -1129,15 +743,15 @@ public class MultiTemplateTabPane extends JComponent {
private boolean isOverListDown(int evtX) {
int maxWidth = getWidth() - LIST_BUTTON_WIDTH;
int maxWidth = getWidth() - scale(TRAILING_WIDTH) - scale(LEADING_WIDTH);
return evtX >= (maxWidth + SMALLGAP) && evtX <= (getWidth() - SMALLGAP);
}
private int getTemplateIndex(int evtX) {
int textX = 0;
int textX = scale(LEADING_WIDTH);
for (int i = minPaintIndex; i <= maxPaintIndex; i++) {
int textWidth = showJTemplateTab(openedTemplate.get(i)) ? realWidth : 0;
int textWidth = showJTemplateTab(openedTemplate.get(i)) ? tabWidth : 0;
if (evtX >= textX && evtX < textX + textWidth) {
return i;
}
@ -1169,35 +783,7 @@ public class MultiTemplateTabPane extends JComponent {
}
}
private class UIListDownItemUI extends BasicMenuItemUI {
@Override
protected void paintBackground(Graphics g, JMenuItem menuItem, Color bgColor) {
if (menuItem.getIcon() == null) {
super.paintBackground(g, menuItem, bgColor);
return;
}
ButtonModel model = menuItem.getModel();
Color oldColor = g.getColor();
int menuWidth = menuItem.getWidth();
int menuHeight = menuItem.getHeight();
g.setColor(getBackground());
g.fillRect(0, 0, menuWidth, menuHeight);
boolean itemIsSelected = menuItem instanceof JMenu && model.isSelected();
if (menuItem.isOpaque()) {
if (model.isArmed() || itemIsSelected) {
GUIPaintUtils.fillPaint((Graphics2D) g, GAP, 0, menuWidth - GAP, menuHeight, true, Constants.NULL, UIConstants.FLESH_BLUE, UIConstants.ARC);
} else {
GUIPaintUtils.fillPaint((Graphics2D) g, GAP, 0, menuWidth - GAP, menuHeight, true, Constants.NULL, menuItem.getBackground(), UIConstants.ARC);
}
g.setColor(oldColor);
} else if (model.isArmed() || itemIsSelected) {
GUIPaintUtils.fillPaint((Graphics2D) g, GAP, 0, menuWidth - GAP, menuHeight, true, Constants.NULL, UIConstants.FLESH_BLUE, UIConstants.ARC);
g.setColor(oldColor);
}
}
}
private class MultiTemplateTabMouseListener implements MouseListener {
private class MultiTemplateTabMouseListener extends MouseAdapter {
private boolean oldLightWeightPopupEnabled;
@ -1222,32 +808,12 @@ public class MultiTemplateTabPane extends JComponent {
ToolTipManager.sharedInstance().setEnabled(false);
ToolTipManager.sharedInstance().setEnabled(true);
ToolTipManager.sharedInstance().setLightWeightPopupEnabled(this.oldLightWeightPopupEnabled);
listDownMode = LIST_DOWN;
closeIconIndex = -1;
mouseOveredIndex = -1;
hoverMoreAction = false;
MultiTemplateTabPane.this.repaint();
}
/**
* 鼠标释放
*
* @param e 鼠标事件
*/
@Override
public void mouseReleased(MouseEvent e) {
// do nothing
}
/**
* 点击
*
* @param e 鼠标事件
*/
@Override
public void mouseClicked(MouseEvent e) {
// do nothing
}
/**
* 按下
*
@ -1264,8 +830,9 @@ public class MultiTemplateTabPane extends JComponent {
//是否点击关闭按钮 如果点击了关闭按钮,则将点击的模板关闭,不需要切换,如果没有点击关闭按钮,则切换到点击的模板处
boolean isOverCloseIcon = isOverCloseIcon(evtX);
if (isOverListDown(evtX)) {
listDownMode = isOverListDown(evtX) ? MOUSE_PRESS_LIST_DOWN : LIST_DOWN;
hoverMoreAction = isOverListDown(evtX);
if (hoverMoreAction) {
if (!isShowList) {
showListDown();
}
@ -1274,7 +841,6 @@ public class MultiTemplateTabPane extends JComponent {
} else if (isOverCloseIcon) {
//关闭按钮的图标变化
closeIconIndex = getTemplateIndex(evtX);
clodeMode = MOUSE_PRESS_CLOSE;
//关闭close图标所在的模板{
JTemplate<?, ?> template = openedTemplate.get(closeIconIndex);
if (template.isOpening()) {
@ -1298,7 +864,7 @@ public class MultiTemplateTabPane extends JComponent {
} else {
//没有点击关闭和ListDown按钮,则切换到点击的模板处
closeIconIndex = -1;
clodeMode = CLOSE;
clodeIcon = new LazyIcon("clear");
switchJTemplate(getTemplateIndex(evtX));
isShowList = false;
}
@ -1308,6 +874,7 @@ public class MultiTemplateTabPane extends JComponent {
/**
* 切换到指定模板
*
* @param jTemplate
*/
public void switchJTemplate(JTemplate jTemplate) {
@ -1319,9 +886,10 @@ public class MultiTemplateTabPane extends JComponent {
/**
* 切换到指定index
*
* @param switchIndex
*/
private void switchJTemplate(int switchIndex){
private void switchJTemplate(int switchIndex) {
int tempSelectedIndex = selectedIndex;
if (selectedIndex != switchIndex && switchIndex != -1) {
openedTemplate.get(selectedIndex).stopEditing();
@ -1344,17 +912,7 @@ public class MultiTemplateTabPane extends JComponent {
return JTemplate.isValid(currentTemplate) && ComparatorUtils.equals(template.getPath(), currentTemplate.getPath());
}
private class MultiTemplateTabMouseMotionListener implements MouseMotionListener {
/**
* 鼠标拖拽
*
* @param e 鼠标事件
*/
@Override
public void mouseDragged(MouseEvent e) {
// do nothing
}
private class MultiTemplateTabMouseMotionListener extends MouseMotionAdapter {
/**
* 鼠标移动
*
@ -1364,51 +922,106 @@ public class MultiTemplateTabPane extends JComponent {
public void mouseMoved(MouseEvent e) {
int evtX = e.getX();
mouseOveredIndex = getTemplateIndex(evtX);
//看是否需要显示toolTip
if (mouseOveredIndex != -1 && isNeedToolTips[mouseOveredIndex - minPaintIndex]) {
setToolTipText(openedTemplate.get(mouseOveredIndex).getEditingFILE().getName());
} else {
setToolTipText(null);
}
listDownMode = isOverListDown(evtX) ? MOUSE_OVER_LIST_DOWN : LIST_DOWN;
boolean isOverCloseIcon = isOverCloseIcon(evtX);
clodeMode = isOverCloseIcon ? MOUSE_OVER_CLOSE : CLOSE;
closeIconIndex = isOverCloseIcon ? mouseOveredIndex : -1;
setToolTipText(openedTemplate.get(mouseOveredIndex).getEditingFILE().getName());
hoverMoreAction = isOverListDown(evtX);
closeIconIndex = isOverCloseIcon(evtX) ? mouseOveredIndex : -1;
MultiTemplateTabPane.this.repaint();
}
}
/**
* 判断是否显示在tab栏上
*
* @param jTemplate
* @return
*/
private boolean showJTemplateTab(JTemplate jTemplate){
private boolean showJTemplateTab(JTemplate jTemplate) {
JTemplate current = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
return ComparatorUtils.equals(current.getTemplateTabOperatorType(), jTemplate.getTemplateTabOperatorType());
}
/**
* 获取tab操作类型的模板
*
* @param operator
* @return
*/
public List<JTemplate<?, ?>> getOpenedJTemplatesByOperator(String operator) {
public List<JTemplate<?, ?>> getOpenedJTemplatesByOperator(String operator) {
return openedTemplate.stream().filter((jTemplate) -> ComparatorUtils.equals(jTemplate.getTemplateTabOperatorType(), operator))
.collect(Collectors.toList());
}
/**
* 根据tab操作类型进行分类
*
* @return
*/
public Map<String, List<JTemplate<?, ?>>> getOpenedJTemplatesByCategory() {
return openedTemplate.stream()
.collect(Collectors.groupingBy(JTemplate::getTemplateTabOperatorType));
return openedTemplate.stream()
.collect(Collectors.groupingBy(JTemplate::getTemplateTabOperatorType));
}
/**
* 返回当前tab数量
*
* @return tab数量
*/
public int getTabCount() {
return openedTemplate.size();
}
/**
* 获取选中的tab索引
*
* @return tab索引
*/
public int getSelectedIndex() {
return selectedIndex;
}
/**
* 获取每个tab宽度
*
* @return tab宽度
*/
public int getTabWidth() {
return tabWidth;
}
/**
* 是否悬浮在更多按钮上
*
* @return 是否悬浮
*/
public boolean isHoverMoreAction() {
return hoverMoreAction;
}
/**
* 是否悬浮在关闭按钮上0
*
* @param i 索引
* @return 是否悬浮在关闭按钮上
*/
public boolean isCloseCurrent(int i) {
return i == closeIconIndex;
}
/**
* 获取悬浮索引
*
* @return 悬浮在第几个tab
*/
public int getHoverIndex() {
return mouseOveredIndex;
}
/**
* 获取可视范围内的标签范围
*
* @return 标签范围
*/
public Pair<Integer, Integer> getViewRange() {
return new Pair<>(minPaintIndex, maxPaintIndex);
}
}

72
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<T> 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<UIToggleButton> labelButtonList;
protected int totalButtonSize;
protected int selectedIndex = -1;
private List<T> 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<T> 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<T> extends Column implements GlobalNameObserver, UIOb
return false;
}
};
initButton(labelButton);
initButton(labelButton, index);
}
initLayout(getCols());
}
@ -98,6 +103,7 @@ public class UIButtonGroup<T> 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<T> extends Column implements GlobalNameObserver, UIOb
return false;
}
};
initButton(labelButton);
initButton(labelButton, index);
}
initLayout(getCols());
}
@ -133,8 +139,8 @@ public class UIButtonGroup<T> 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<T> extends Column implements GlobalNameObserver, UIOb
}
};
initButton(labelButton);
initButton(labelButton, index);
}
initLayout(getCols());
}
@ -169,8 +175,13 @@ public class UIButtonGroup<T> 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<T> 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<T> extends Column implements GlobalNameObserver, UIOb
}
public void setForToolBarButtonGroup(boolean isToolBarComponent) {
this.isToolBarComponent = isToolBarComponent;
if (isToolBarComponent) {
for (UIToggleButton uiToggleButton : labelButtonList) {
uiToggleButton.set4ToolbarButton();

280
designer-base/src/main/java/com/fr/design/gui/ibutton/UICombinationButton.java

@ -1,143 +1,155 @@
package com.fr.design.gui.ibutton;
import java.awt.BorderLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
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;
/**
* 双按钮组件
*
* @author vito
* @since 11.0
* <p>
* created by vito on 2023/12/28
**/
public class UICombinationButton extends JPanel {
private static final String UI_CLASS_ID = "CombinationButtonUI";
protected UIButton leftButton;
protected UIButton rightButton;
private Consumer<MouseEvent> leftClickLister;
private Consumer<MouseEvent> rightClickLister;
protected void leftButtonClickEvent() {
// 左边按钮点击事件
}
protected void rightButtonClickEvent() {
// 右边按钮点击事件
}
public UICombinationButton() {
this(new UIButton(), new UIButton());
}
/**
* 添加左按钮监听器
*
* @param lister 监听
*/
public void addLeftClickLister(Consumer<MouseEvent> lister) {
this.leftClickLister = lister;
}
/**
* 添加右按钮监听器
*
* @param lister 监听
*/
public void addRightClickLister(Consumer<MouseEvent> 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);
}
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);
}
protected void showPopWindow(JPopupMenu menu) {
GUICoreUtils.showPopupMenu(menu, this, 0, getY() + getHeight() - 3);
}
}

1
designer-base/src/main/java/com/fr/design/gui/ibutton/UIHeadGroup.java

@ -61,6 +61,7 @@ public class UIHeadGroup extends Row {
* @see JComponent#getUIClassID
* @see UIDefaults#getUI
*/
@Override
public String getUIClassID() {
return UI_CLASS_ID;
}

2
designer-base/src/main/java/com/fr/design/gui/ibutton/UITabGroup.java

@ -33,7 +33,7 @@ public class UITabGroup extends UIButtonGroup<Integer> {
@Override
protected int[] getCols() {
int buttons = labelButtonList.size();
int buttons = totalButtonSize;
if (buttons < ROW_MAX_LIMIT) {
return new int[]{buttons};
}

1
designer-base/src/main/java/com/fr/design/gui/itoolbar/UIToolbar.java

@ -18,7 +18,6 @@ public class UIToolbar extends JToolBar {
setFloatable(false);
setRollover(true);
setLayout(new FlowLayout(align, 4, 0));
// setUI(uiToolBarUI);
setBorderPainted(false);
}

47
designer-base/src/main/java/com/fr/design/mainframe/CenterRegionContainerPane.java

@ -1,13 +1,13 @@
package com.fr.design.mainframe;
import com.formdev.flatlaf.util.ScaledEmptyBorder;
import com.fr.design.DesignState;
import com.fr.design.base.mode.DesignModeContext;
import com.fr.design.constants.UIConstants;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.file.MultiTemplateTabPane;
import com.fr.design.file.NewTemplatePane;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.itoolbar.UILargeToolbar;
import com.fr.design.gui.ibutton.UICombinationButton;
import com.fr.design.gui.itoolbar.UIToolbar;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.toolbar.ToolBarMenuDock;
@ -16,14 +16,11 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.BorderFactory;
import javax.swing.UIManager;
import javax.swing.border.MatteBorder;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Insets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
@ -47,7 +44,7 @@ public class CenterRegionContainerPane extends JPanel {
private JComponent toolbarComponent;//cpt 字体 等工具栏
private JPanel eastPane;//=largeToolbar+eastCenterPane
private UILargeToolbar largeToolbar;//预览
private UICombinationButton largeToolbar;//预览
private JPanel eastCenterPane;//=combineUp + templateTabPane
@ -70,37 +67,28 @@ public class CenterRegionContainerPane extends JPanel {
public CenterRegionContainerPane() {
toolbarPane = new JPanel() {
@Override
public Dimension getPreferredSize() {
Dimension dim = super.getPreferredSize();
// dim.height = TOOLBAR_HEIGHT;
return dim;
}
};
toolbarPane.setBorder(BorderFactory.createEmptyBorder(0, 0, 10, 0));
toolbarPane = new JPanel();
toolbarPane.setBorder(new ScaledEmptyBorder(6, 0, 10, 0));
toolbarPane.setLayout(FRGUIPaneFactory.createBorderLayout());
toolbarPane.setBackground(UIManager.getColor("Center.SpaceColor"));
eastPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
eastPane.add(largeToolbar = getToolBarMenuDock().createLargeToolbar(), BorderLayout.WEST);
largeToolbar = getToolBarMenuDock().createLargeToolbar();
eastCenterPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
combineUpTooBar();
eastCenterPane.add(combineUp, BorderLayout.NORTH);
templateTabPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
templateTabPane.add(newWorkBookPane = getToolBarMenuDock().getNewTemplatePane(), BorderLayout.WEST);
templateTabPane.add(MultiTemplateTabPane.getInstance(), BorderLayout.CENTER);
eastCenterPane.add(templateTabPane, BorderLayout.CENTER);
newWorkBookPane = getToolBarMenuDock().getNewTemplatePane();
eastCenterPane.add(templateTabPane, BorderLayout.NORTH);
eastCenterPane.add(combineUp, BorderLayout.CENTER);
eastPane.add(eastCenterPane, BorderLayout.CENTER);
toolbarPane.add(eastPane, BorderLayout.NORTH);
this.setLayout(new BorderLayout());
this.add(centerTemplateCardPane = new DesktopCardPane(), BorderLayout.CENTER);
centerTemplateCardPane.setBorder(new ScaledEmptyBorder(0, 10, 10, 10));
this.add(toolbarPane, BorderLayout.NORTH);
this.setBackground(UIManager.getColor("Center.SpaceColor"));
this.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10));
this.setBorder(new ScaledEmptyBorder(0, 0, 10, 0));
}
public ToolBarMenuDock getToolBarMenuDock() {
@ -112,10 +100,9 @@ public class CenterRegionContainerPane extends JPanel {
*/
private void combineUpTooBar() {
combineUp = new UIToolbar(FlowLayout.LEFT);
combineUp.setBorder(new MatteBorder(new Insets(0, LEFT_ALIGN_GAP, 1, 0), UIConstants.LINE_COLOR));
combineUp.setBorder(new ScaledEmptyBorder(10, 10, 10, 10));
combineUp.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 2));
setUpUpToolBar(null);
}
@ -135,6 +122,7 @@ public class CenterRegionContainerPane extends JPanel {
* @param toolbar4Form 目标组件
*/
private void setUpUpToolBar(@Nullable JComponent[] toolbar4Form) {
combineUp.add(largeToolbar);
UIButton[] fixButtons = getToolBarMenuDock().createUp();
for (UIButton fixButton : fixButtons) {
combineUp.add(fixButton);
@ -233,19 +221,20 @@ public class CenterRegionContainerPane extends JPanel {
// 颜色,字体那些按钮的工具栏
toolbarPane.add(toolbarComponent = ad.resetToolBar(toolbarComponent, plus), BorderLayout.CENTER);
toolbarComponent.setBorder(new ScaledEmptyBorder(0, 10, 10, 10));
JPanel customNorthPane = strategy.customNorthPane(toolbarPane, plus);
if (!isExist(customNorthPane)) {
this.removeNorth();
this.add(customNorthPane, BorderLayout.NORTH);
}
if (strategy.hasTemplateTabPane(plus)) {
eastCenterPane.add(templateTabPane, BorderLayout.CENTER);
eastCenterPane.add(templateTabPane, BorderLayout.NORTH);
} else {
eastCenterPane.remove(templateTabPane);
}
if (strategy.hasCombineUp(plus)) {
eastCenterPane.add(combineUp, BorderLayout.NORTH);
eastCenterPane.add(combineUp, BorderLayout.CENTER);
} else {
eastCenterPane.remove(combineUp);
}
@ -274,11 +263,11 @@ public class CenterRegionContainerPane extends JPanel {
private void resetByDesignMode() {
if (DesignModeContext.isDuchampMode()) {
eastPane.remove(largeToolbar);
// eastPane.remove(largeToolbar);
//移除新建模板按钮
templateTabPane.remove(newWorkBookPane);
} else {
eastPane.add(largeToolbar, BorderLayout.WEST);
// eastPane.add(largeToolbar, BorderLayout.WEST);
templateTabPane.add(newWorkBookPane, BorderLayout.WEST);
}

2
designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java

@ -177,7 +177,7 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
private TemplateThemeConfig.ThemeConfigChangeListener themeConfigChangeListener;
public JTemplate() {
initAndStartPlugin();
// initAndStartPlugin();
startListenThemeConfig();
}

6
designer-base/src/main/java/com/fr/design/mainframe/JVirtualTemplate.java

@ -1,6 +1,6 @@
package com.fr.design.mainframe;
import com.fr.base.BaseUtils;
import com.fine.theme.icon.LazyIcon;
import com.fr.design.DesignModelAdapter;
import com.fr.design.designer.TargetComponent;
import com.fr.design.file.HistoryTemplateListPane;
@ -246,9 +246,9 @@ public class JVirtualTemplate extends JTemplate {
@Override
public Icon getIcon() {
if (getPath().endsWith("cpt")) {
return BaseUtils.readIcon("/com/fr/design/images/buttonicon/newcpts.png");
return new LazyIcon("cpt_icon");
} else {
return BaseUtils.readIcon("/com/fr/web/images/form/new_form3.png");
return new LazyIcon("frm_icon");
}
}

11
designer-base/src/main/resources/com/fine/theme/icon/clear_hover.svg

@ -0,0 +1,11 @@
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="14" height="14" rx="7" fill="#B8BFCB"/>
<g clip-path="url(#clip0_5140_94134)">
<path d="M6.46967 6.99995L3.81802 9.6516C3.67157 9.79804 3.67157 10.0355 3.81802 10.1819C3.96447 10.3284 4.2019 10.3284 4.34835 10.1819L7 7.53028L9.65165 10.1819C9.7981 10.3284 10.0355 10.3284 10.182 10.1819C10.3284 10.0355 10.3284 9.79804 10.182 9.6516L7.53033 6.99995L10.182 4.3483C10.3284 4.20185 10.3284 3.96441 10.182 3.81797C10.0355 3.67152 9.7981 3.67152 9.65165 3.81797L7 6.46962L4.34835 3.81797C4.2019 3.67152 3.96447 3.67152 3.81802 3.81797C3.67157 3.96441 3.67157 4.20185 3.81802 4.3483L6.46967 6.99995Z" fill="#0A1C38" fill-opacity="0.9"/>
</g>
<defs>
<clipPath id="clip0_5140_94134">
<rect x="1" y="1" width="12" height="12" rx="6" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 875 B

3
designer-base/src/main/resources/com/fine/theme/icon/toolbar/more.svg

@ -0,0 +1,3 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M28 16C28 22.6274 22.6274 28 16 28C9.37258 28 4 22.6274 4 16C4 9.37258 9.37258 4 16 4C22.6274 4 28 9.37258 28 16ZM30 16C30 23.732 23.732 30 16 30C8.26801 30 2 23.732 2 16C2 8.26801 8.26801 2 16 2C23.732 2 30 8.26801 30 16ZM10.5 17.5C11.3284 17.5 12 16.8284 12 16C12 15.1716 11.3284 14.5 10.5 14.5C9.67157 14.5 9 15.1716 9 16C9 16.8284 9.67157 17.5 10.5 17.5ZM16 17.5C16.8284 17.5 17.5 16.8284 17.5 16C17.5 15.1716 16.8284 14.5 16 14.5C15.1716 14.5 14.5 15.1716 14.5 16C14.5 16.8284 15.1716 17.5 16 17.5ZM23 16C23 16.8284 22.3284 17.5 21.5 17.5C20.6716 17.5 20 16.8284 20 16C20 15.1716 20.6716 14.5 21.5 14.5C22.3284 14.5 23 15.1716 23 16Z" fill="#0A1C38" fill-opacity="0.9"/>
</svg>

After

Width:  |  Height:  |  Size: 828 B

3
designer-base/src/main/resources/com/fine/theme/icon/toolbar/more_disable.svg

@ -0,0 +1,3 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M28 16C28 22.6274 22.6274 28 16 28C9.37258 28 4 22.6274 4 16C4 9.37258 9.37258 4 16 4C22.6274 4 28 9.37258 28 16ZM30 16C30 23.732 23.732 30 16 30C8.26801 30 2 23.732 2 16C2 8.26801 8.26801 2 16 2C23.732 2 30 8.26801 30 16ZM10.5 17.5C11.3284 17.5 12 16.8284 12 16C12 15.1716 11.3284 14.5 10.5 14.5C9.67157 14.5 9 15.1716 9 16C9 16.8284 9.67157 17.5 10.5 17.5ZM16 17.5C16.8284 17.5 17.5 16.8284 17.5 16C17.5 15.1716 16.8284 14.5 16 14.5C15.1716 14.5 14.5 15.1716 14.5 16C14.5 16.8284 15.1716 17.5 16 17.5ZM23 16C23 16.8284 22.3284 17.5 21.5 17.5C20.6716 17.5 20 16.8284 20 16C20 15.1716 20.6716 14.5 21.5 14.5C22.3284 14.5 23 15.1716 23 16Z" fill="#0A1C38" fill-opacity="0.29"/>
</svg>

After

Width:  |  Height:  |  Size: 829 B

10
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,9 @@ 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
GradientBarUI=com.fine.theme.light.ui.FineGradientBarUI
TemplateTabPaneUI=com.fine.theme.light.ui.FineTemplateTabPaneUI

126
designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLightLaf.properties

@ -60,7 +60,7 @@ Component.defaultVGap=10
@disabledForeground = tint(@foreground,55%)
# component background
@buttonBackground = lighten(@background,5%)
@buttonBackground = #FFF
@componentBackground = @background
@menuBackground = @background
@ -136,33 +136,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.border =com.fine.theme.light.ui.FineButtonBorder
Button.arc = 6
Button.minimumWidth = 72
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
@ -180,10 +197,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
@ -289,8 +325,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
@ -778,19 +814,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
@ -798,6 +834,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
@ -834,21 +873,36 @@ 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.borderColor = $border.divider
TemplateTabPane.closeHoverBackground = $hover.deep
TemplateTabPane.tabInsets = 4,6,4,6
TemplateTabPane.borderWidth = 1
TemplateTabPane.tabArc = 5
TemplateTabPane.separatorHeight = 14
TemplateTabPane.icon.hoverBackground = #B8BFCB
#---- Table ----
Table.rowHeight = 20
@ -1038,6 +1092,7 @@ ToolBar.arrowKeysOnlyNavigation = true
ToolBar.hoverButtonGroupArc = 8
ToolBar.floatable = false
ToolBar.gripColor = @icon
ToolBar.background = #fff
ToolBar.dockingBackground = darken($ToolBar.background,5%)
ToolBar.dockingForeground = $Component.borderColor
ToolBar.floatingBackground = $ToolBar.background
@ -1178,6 +1233,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

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

42
designer-base/src/test/java/com/fr/design/gui/storybook/components/JTestTemplate.java

@ -0,0 +1,42 @@
package com.fr.design.gui.storybook.components;
import com.fine.theme.icon.LazyIcon;
import com.fr.design.mainframe.JNullTemplate;
import com.fr.file.FILE;
import com.fr.file.MemFILE;
import javax.swing.Icon;
/**
* @author vito
* @since 11.0
* Created on 2023/12/18
*/
public class JTestTemplate extends JNullTemplate {
private String name;
private FILE file;
public JTestTemplate(String name) {
this.name = name;
this.file = new MemFILE(name);
}
public String getTemplateName() {
return name;
}
@Override
public Icon getIcon() {
return new LazyIcon("save");
}
public String getTemplateTabOperatorType(){
return "DefaultTabOperator";
}
@Override
public FILE getEditingFILE() {
return file;
}
}

36
designer-base/src/test/java/com/fr/design/gui/storybook/components/TemplateTabStoryBoard.java

@ -0,0 +1,36 @@
package com.fr.design.gui.storybook.components;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.file.MultiTemplateTabPane;
import com.fr.design.gui.storybook.Story;
import com.fr.design.gui.storybook.StoryBoard;
import com.fr.value.NullableLazyValue;
/**
* 新建模版Tab
*
* @author vito
* @since 11.0
* Created on 2023/11/27
*/
@Story
public class TemplateTabStoryBoard extends StoryBoard {
final static NullableLazyValue<Void> init = NullableLazyValue.createValue(() -> {
HistoryTemplateListCache.getInstance().setCurrentEditingTemplate(new JTestTemplate("ghjffdhsakjfjdks.cpt"));
HistoryTemplateListCache.getInstance().setCurrentEditingTemplate(new JTestTemplate("模版1.cpt"));
HistoryTemplateListCache.getInstance().setCurrentEditingTemplate(new JTestTemplate("模版.cpt"));
HistoryTemplateListCache.getInstance().setCurrentEditingTemplate(new JTestTemplate("模版1.cpt"));
HistoryTemplateListCache.getInstance().setCurrentEditingTemplate(new JTestTemplate("模版模版模版模版.cpt"));
return null;
});
public TemplateTabStoryBoard() {
super("新建模版Tab");
init.getValue();
add(MultiTemplateTabPane.getInstance());
}
}

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

3
designer-form/src/main/java/com/fr/design/mainframe/JForm.java

@ -1,5 +1,6 @@
package com.fr.design.mainframe;
import com.fine.theme.icon.LazyIcon;
import com.fr.base.PaperSize;
import com.fr.base.Parameter;
import com.fr.base.Releasable;
@ -1067,7 +1068,7 @@ public class JForm extends JTemplate<Form, FormUndoState> implements BaseJForm<F
* @return 图表
*/
public Icon getIcon() {
return IconUtils.readIcon("/com/fr/web/images/form/new_form3.png");
return new LazyIcon("frm_icon");
}
@Override

3
designer-realize/src/main/java/com/fr/design/mainframe/JWorkBook.java

@ -1,5 +1,6 @@
package com.fr.design.mainframe;
import com.fine.theme.icon.LazyIcon;
import com.fr.base.DynamicUnitList;
import com.fr.base.Parameter;
import com.fr.base.ScreenResolution;
@ -1152,7 +1153,7 @@ public class JWorkBook extends JTemplate<WorkBook, WorkBookUndoState> {
@Override
public Icon getIcon() {
return IconUtils.readIcon("/com/fr/design/images/buttonicon/newcpts.png");
return new LazyIcon("cpt_icon");
}
/**

3
designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/CellPresentPane.java

@ -1,7 +1,6 @@
package com.fr.design.mainframe.cell.settingpane;
import com.fr.base.present.Present;
import com.fr.design.constants.UIConstants;
import com.fr.design.mainframe.theme.utils.DefaultThemedTemplateCellElementCase;
import com.fr.design.present.PresentPane;
@ -29,7 +28,6 @@ public class CellPresentPane extends AbstractCellAttrPane {
presentPane = new PresentPane();
JPanel content = new JPanel(new BorderLayout());
content.add(presentPane, BorderLayout.CENTER);
presentPane.setBorder(UIConstants.CELL_ATTR_PRESENTBORDER);
presentPane.addTabChangeListener(new ItemListener() {
@Override
@ -42,7 +40,6 @@ public class CellPresentPane extends AbstractCellAttrPane {
@Override
public String getIconPath() {
// return "com/fr/design/images/data/source/dataDictionary.png";
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Present");
}

4
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);

124
designer-realize/src/main/java/com/fr/start/MainDesigner.java

@ -14,7 +14,6 @@ import com.fr.design.actions.server.TemplateThemeManagerAction;
import com.fr.design.actions.server.WidgetManagerAction;
import com.fr.design.base.mode.DesignModeContext;
import com.fr.design.carton.SwitchForSwingChecker;
import com.fr.design.constants.UIConstants;
import com.fr.design.deeplink.DeepLinkManager;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.file.HistoryTemplateListPane;
@ -22,11 +21,10 @@ import com.fr.design.file.MultiTemplateTabPane;
import com.fr.design.fun.MenuHandler;
import com.fr.design.fun.OemProcessor;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ibutton.UIPreviewButton;
import com.fr.design.gui.ibutton.UICombinationButton;
import com.fr.design.gui.ibutton.UISaveForbiddenButton;
import com.fr.design.gui.imenu.UIMenuItem;
import com.fr.design.gui.imenu.UIPopupMenu;
import com.fr.design.gui.itoolbar.UILargeToolbar;
import com.fr.design.mainframe.ActiveKeyGenerator;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.InformationCollector;
@ -79,13 +77,9 @@ import com.fr.workspace.WorkContext;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.border.MatteBorder;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.ArrayList;
import java.util.concurrent.LinkedBlockingQueue;
@ -106,7 +100,7 @@ public class MainDesigner extends BaseDesigner {
private UIButton undo;
private UIButton redo;
private UIButton[] upToolBar;
private UIPreviewButton run;
private UICombinationButton run;
public MainDesigner(String[] args) {
super(args);
@ -268,15 +262,8 @@ public class MainDesigner extends BaseDesigner {
* @return 返回大图标对应的工具栏
*/
@Override
public UILargeToolbar createLargeToolbar() {
UILargeToolbar largeToolbar = super.createLargeToolbar();
largeToolbar.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 4));
largeToolbar.add(generateEmptyGap(1));
createRunButton(largeToolbar);
largeToolbar.add(run);
largeToolbar.add(generateEmptyGap(GAP));
largeToolbar.addSeparator(new Dimension(2, 42));
largeToolbar.setBorder(new MatteBorder(new Insets(0, 0, 1, 0), UIConstants.LINE_COLOR));
public UICombinationButton createLargeToolbar() {
UICombinationButton largeToolbar = createRunButton();
return largeToolbar;
}
@ -315,15 +302,12 @@ public class MainDesigner extends BaseDesigner {
saveButton = new UIButton(new LazyIcon("save"));
saveButton.setToolTipText(KeySetUtils.SAVE_TEMPLATE.getMenuKeySetName());
saveButton.set4ToolbarButton();
saveButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JTemplate<?, ?> jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
jt.stopEditing();
jt.saveDirectly();
jt.requestFocus();
SharableManager.saveTemplate(jt);
}
saveButton.addActionListener(e -> {
JTemplate<?, ?> jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
jt.stopEditing();
jt.saveDirectly();
jt.requestFocus();
SharableManager.saveTemplate(jt);
});
}
@ -332,13 +316,10 @@ public class MainDesigner extends BaseDesigner {
undo = new UIButton(new LazyIcon("undo"));
undo.setToolTipText(KeySetUtils.UNDO.getMenuKeySetName());
undo.set4ToolbarButton();
undo.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JTemplate<?, ?> jt = HistoryTemplateListPane.getInstance().getCurrentEditingTemplate();
if (jt != null) {
jt.undo();
}
undo.addActionListener(e -> {
JTemplate<?, ?> jt = HistoryTemplateListPane.getInstance().getCurrentEditingTemplate();
if (jt != null) {
jt.undo();
}
});
}
@ -347,65 +328,44 @@ public class MainDesigner extends BaseDesigner {
redo = new UIButton(new LazyIcon("redo"));
redo.setToolTipText(KeySetUtils.REDO.getMenuKeySetName());
redo.set4ToolbarButton();
redo.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JTemplate<?, ?> jt = HistoryTemplateListPane.getInstance().getCurrentEditingTemplate();
if (jt != null) {
jt.redo();
}
redo.addActionListener(e -> {
JTemplate<?, ?> jt = HistoryTemplateListPane.getInstance().getCurrentEditingTemplate();
if (jt != null) {
jt.redo();
}
});
}
private void createRunButton(UILargeToolbar largeToolbar) {
run = new UIPreviewButton(new UISaveForbiddenButton(UIConstants.PAGE_BIG_ICON) {
@Override
public Dimension getPreferredSize() {
return new Dimension(34, 34);
private UICombinationButton createRunButton() {
run = new UICombinationButton(new UISaveForbiddenButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Preview"), new LazyIcon("add")),
new UISaveForbiddenButton(new LazyIcon("triangle_down")));
run.addLeftClickLister(mouseEvent -> {
JTemplate<?, ?> jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
if (jt == null || jt.isSaving()) {
return;
}
}, new UISaveForbiddenButton(UIConstants.PREVIEW_DOWN) {
@Override
public Dimension getPreferredSize() {
return new Dimension(34, 10);
}
}
) {
@Override
protected void upButtonClickEvent() {
JTemplate<?, ?> jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
if (jt == null || jt.isSaving()) {
return;
}
WebPreviewUtils.preview(jt);
WebPreviewUtils.preview(jt);
});
run.addRightClickLister(mouseEvent -> {
final JTemplate<?, ?> jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
if (jt == null) {
return;
}
@Override
protected void downButtonClickEvent() {
final JTemplate<?, ?> jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
if (jt == null) {
return;
}
UIPopupMenu menu = new UIPopupMenu();
UIPopupMenu menu = new UIPopupMenu();
UIMenuItem[] items = jt.createMenuItem4Preview();
for (int i = 0; i < items.length; i++) {
menu.add(items[i]);
}
GUICoreUtils.showPopupMenu(menu, MultiTemplateTabPane.getInstance(), MultiTemplateTabPane.getInstance().getX() - PREVIEW_DOWN_X_GAP, MultiTemplateTabPane.getInstance().getY() - 1 + MultiTemplateTabPane.getInstance().getHeight());
UIMenuItem[] items = jt.createMenuItem4Preview();
for (UIMenuItem item : items) {
menu.add(item);
}
@Override
public Dimension getPreferredSize() {
// TODO Auto-generated method stub
return new Dimension(34, 46);
}
};
GUICoreUtils.showPopupMenu(menu, run, run.getX(), run.getY() - 1 + run.getHeight());
});
run.setPrimary();
run.setExtraPainted(false);
run.set4Toolbar();
run.getUpButton().setToolTipText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Preview"));
run.getDownButton().setToolTipText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Dropdown_More_Preview"));
run.getLeftButton().setToolTipText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Preview"));
run.getRightButton().setToolTipText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Dropdown_More_Preview"));
return run;
}
@Override
@ -425,7 +385,7 @@ public class MainDesigner extends BaseDesigner {
redo.setEnabled(false);
}
run.getUpButton().setIcon(jt.getPreviewLargeIcon());
// run.getLeftButton().setIcon(jt.getPreviewLargeIcon());
}

Loading…
Cancel
Save