Browse Source

REPORT-99485 设计器模版tab和工具栏绘制

newui
vito 1 year ago
parent
commit
357866ce9c
  1. 1
      designer-base/src/main/java/com/fine/theme/light/ui/FineLightIconSet.java
  2. 407
      designer-base/src/main/java/com/fine/theme/light/ui/FineTemplateTabPaneUI.java
  3. 2
      designer-base/src/main/java/com/fine/theme/light/ui/laf/FineLaf.java
  4. 2
      designer-base/src/main/java/com/fine/theme/utils/FineUIUtils.java
  5. 690
      designer-base/src/main/java/com/fr/design/file/MultiTemplateTabPane.java
  6. 1
      designer-base/src/main/java/com/fr/design/gui/ibutton/UIHeadGroup.java
  7. 1
      designer-base/src/main/java/com/fr/design/gui/itoolbar/UIToolbar.java
  8. 47
      designer-base/src/main/java/com/fr/design/mainframe/CenterRegionContainerPane.java
  9. 2
      designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java
  10. 6
      designer-base/src/main/java/com/fr/design/mainframe/JVirtualTemplate.java
  11. 11
      designer-base/src/main/resources/com/fine/theme/icon/clear_hover.svg
  12. 3
      designer-base/src/main/resources/com/fine/theme/icon/toolbar/more.svg
  13. 3
      designer-base/src/main/resources/com/fine/theme/icon/toolbar/more_disable.svg
  14. 3
      designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLaf.properties
  15. 7
      designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLightLaf.properties
  16. 42
      designer-base/src/test/java/com/fr/design/gui/storybook/components/JTestTemplate.java
  17. 36
      designer-base/src/test/java/com/fr/design/gui/storybook/components/TemplateTabStoryBoard.java
  18. 3
      designer-form/src/main/java/com/fr/design/mainframe/JForm.java
  19. 3
      designer-realize/src/main/java/com/fr/design/mainframe/JWorkBook.java
  20. 124
      designer-realize/src/main/java/com/fr/start/MainDesigner.java

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

@ -139,6 +139,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),

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 iconTextGap = 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
- iconTextGap * 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 + iconTextGap, 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);
}
}

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";

2
designer-base/src/main/java/com/fine/theme/utils/FineUIUtils.java

@ -231,7 +231,7 @@ public class FineUIUtils {
float t2x = t * 2;
Path2D path2D = new Path2D.Float(Path2D.WIND_EVEN_ODD);
path2D.append(createTopRoundRectangle(x, y, width, height, arc), false);
path2D.append(createTopRoundRectangle(x + t, y + t, width - t2x, height - t2x, arc - t), false);
path2D.append(createTopRoundRectangle(x + t, y + t, width - t2x, height - t, arc - t), false);
g2.fill(path2D);
}

690
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,9 +107,10 @@ 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) {
@ -162,27 +124,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 +183,7 @@ public class MultiTemplateTabPane extends JComponent {
/**
* 判断模板是否可以关闭两个条件1是否满足CloseOption里面的条件在左侧在右侧等2是否和当前正在编辑模板属于同一种模板tab操作类型
*
* @param closeJTemplate
* @param tplIndex
* @param i
@ -369,7 +324,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 +372,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 +394,7 @@ public class MultiTemplateTabPane extends JComponent {
/**
* 关闭指定的非当前编辑模板
*
* @param templates
* @param operatorType
*/
@ -471,91 +428,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 +470,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 +529,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 +547,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 +559,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 +585,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]);
tabWidth = scale(MINWIDTH);
}
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);
}
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 +716,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 +740,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 +780,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 +805,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 +827,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 +838,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 +861,7 @@ public class MultiTemplateTabPane extends JComponent {
} else {
//没有点击关闭和ListDown按钮,则切换到点击的模板处
closeIconIndex = -1;
clodeMode = CLOSE;
clodeIcon = new LazyIcon("clear");
switchJTemplate(getTemplateIndex(evtX));
isShowList = false;
}
@ -1308,6 +871,7 @@ public class MultiTemplateTabPane extends JComponent {
/**
* 切换到指定模板
*
* @param jTemplate
*/
public void switchJTemplate(JTemplate jTemplate) {
@ -1319,9 +883,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 +909,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 +919,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);
}
}

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

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

3
designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLaf.properties

@ -48,4 +48,5 @@ 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

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

@ -892,9 +892,13 @@ TemplateTabPane.hoverColor = $fill.hover
TemplateTabPane.contentAreaColor = $fill.hover
TemplateTabPane.background = $fill.disabled
TemplateTabPane.selectedBackground = #fff
TemplateTabPane.tabSeparatorColor = $border.divider
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
@ -1085,6 +1089,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

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

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");
}
/**

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