From 357866ce9c4a0fd8c1a679ecf08849de97dc8c1b Mon Sep 17 00:00:00 2001 From: vito Date: Thu, 28 Dec 2023 22:27:18 +0800 Subject: [PATCH] =?UTF-8?q?REPORT-99485=20=E8=AE=BE=E8=AE=A1=E5=99=A8?= =?UTF-8?q?=E6=A8=A1=E7=89=88tab=E5=92=8C=E5=B7=A5=E5=85=B7=E6=A0=8F?= =?UTF-8?q?=E7=BB=98=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fine/theme/light/ui/FineLightIconSet.java | 1 + .../theme/light/ui/FineTemplateTabPaneUI.java | 407 +++++++++++ .../com/fine/theme/light/ui/laf/FineLaf.java | 2 +- .../com/fine/theme/utils/FineUIUtils.java | 2 +- .../fr/design/file/MultiTemplateTabPane.java | 690 ++++-------------- .../fr/design/gui/ibutton/UIHeadGroup.java | 1 + .../com/fr/design/gui/itoolbar/UIToolbar.java | 1 - .../mainframe/CenterRegionContainerPane.java | 47 +- .../com/fr/design/mainframe/JTemplate.java | 2 +- .../fr/design/mainframe/JVirtualTemplate.java | 6 +- .../com/fine/theme/icon/clear_hover.svg | 11 + .../com/fine/theme/icon/toolbar/more.svg | 3 + .../fine/theme/icon/toolbar/more_disable.svg | 3 + .../theme/light/ui/laf/FineLaf.properties | 3 +- .../light/ui/laf/FineLightLaf.properties | 7 +- .../storybook/components/JTestTemplate.java | 42 ++ .../components/TemplateTabStoryBoard.java | 36 + .../java/com/fr/design/mainframe/JForm.java | 3 +- .../com/fr/design/mainframe/JWorkBook.java | 3 +- .../main/java/com/fr/start/MainDesigner.java | 124 ++-- 20 files changed, 732 insertions(+), 662 deletions(-) create mode 100644 designer-base/src/main/java/com/fine/theme/light/ui/FineTemplateTabPaneUI.java create mode 100644 designer-base/src/main/resources/com/fine/theme/icon/clear_hover.svg create mode 100644 designer-base/src/main/resources/com/fine/theme/icon/toolbar/more.svg create mode 100644 designer-base/src/main/resources/com/fine/theme/icon/toolbar/more_disable.svg create mode 100644 designer-base/src/test/java/com/fr/design/gui/storybook/components/JTestTemplate.java create mode 100644 designer-base/src/test/java/com/fr/design/gui/storybook/components/TemplateTabStoryBoard.java diff --git a/designer-base/src/main/java/com/fine/theme/light/ui/FineLightIconSet.java b/designer-base/src/main/java/com/fine/theme/light/ui/FineLightIconSet.java index 28b9996671..877eb5eafa 100644 --- a/designer-base/src/main/java/com/fine/theme/light/ui/FineLightIconSet.java +++ b/designer-base/src/main/java/com/fine/theme/light/ui/FineLightIconSet.java @@ -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), diff --git a/designer-base/src/main/java/com/fine/theme/light/ui/FineTemplateTabPaneUI.java b/designer-base/src/main/java/com/fine/theme/light/ui/FineTemplateTabPaneUI.java new file mode 100644 index 0000000000..6a80036019 --- /dev/null +++ b/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 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 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); + } +} diff --git a/designer-base/src/main/java/com/fine/theme/light/ui/laf/FineLaf.java b/designer-base/src/main/java/com/fine/theme/light/ui/laf/FineLaf.java index 7ab6d6c722..10d6456488 100644 --- a/designer-base/src/main/java/com/fine/theme/light/ui/laf/FineLaf.java +++ b/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"; diff --git a/designer-base/src/main/java/com/fine/theme/utils/FineUIUtils.java b/designer-base/src/main/java/com/fine/theme/utils/FineUIUtils.java index 8a1e135097..0448fa82f0 100644 --- a/designer-base/src/main/java/com/fine/theme/utils/FineUIUtils.java +++ b/designer-base/src/main/java/com/fine/theme/utils/FineUIUtils.java @@ -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); } diff --git a/designer-base/src/main/java/com/fr/design/file/MultiTemplateTabPane.java b/designer-base/src/main/java/com/fr/design/file/MultiTemplateTabPane.java index 670e3ca15f..f93cd22434 100644 --- a/designer-base/src/main/java/com/fr/design/file/MultiTemplateTabPane.java +++ b/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; *

* 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> 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> getOpenedJTemplatesByOperator(String operator) { + public List> getOpenedJTemplatesByOperator(String operator) { return openedTemplate.stream().filter((jTemplate) -> ComparatorUtils.equals(jTemplate.getTemplateTabOperatorType(), operator)) .collect(Collectors.toList()); } /** * 根据tab操作类型进行分类 + * * @return */ public Map>> 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 getViewRange() { + return new Pair<>(minPaintIndex, maxPaintIndex); + } } diff --git a/designer-base/src/main/java/com/fr/design/gui/ibutton/UIHeadGroup.java b/designer-base/src/main/java/com/fr/design/gui/ibutton/UIHeadGroup.java index 4fa5cc4eba..4f6ee08cc8 100644 --- a/designer-base/src/main/java/com/fr/design/gui/ibutton/UIHeadGroup.java +++ b/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; } diff --git a/designer-base/src/main/java/com/fr/design/gui/itoolbar/UIToolbar.java b/designer-base/src/main/java/com/fr/design/gui/itoolbar/UIToolbar.java index 7b30e45d96..618f4c5510 100644 --- a/designer-base/src/main/java/com/fr/design/gui/itoolbar/UIToolbar.java +++ b/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); } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/CenterRegionContainerPane.java b/designer-base/src/main/java/com/fr/design/mainframe/CenterRegionContainerPane.java index 96265efcf1..9f36dfddd2 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/CenterRegionContainerPane.java +++ b/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); } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java b/designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java index e3742f8a31..685a31843a 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java @@ -177,7 +177,7 @@ public abstract class JTemplate> private TemplateThemeConfig.ThemeConfigChangeListener themeConfigChangeListener; public JTemplate() { - initAndStartPlugin(); +// initAndStartPlugin(); startListenThemeConfig(); } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/JVirtualTemplate.java b/designer-base/src/main/java/com/fr/design/mainframe/JVirtualTemplate.java index 911c0dc17a..04975208de 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/JVirtualTemplate.java +++ b/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"); } } diff --git a/designer-base/src/main/resources/com/fine/theme/icon/clear_hover.svg b/designer-base/src/main/resources/com/fine/theme/icon/clear_hover.svg new file mode 100644 index 0000000000..6981454e9e --- /dev/null +++ b/designer-base/src/main/resources/com/fine/theme/icon/clear_hover.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/designer-base/src/main/resources/com/fine/theme/icon/toolbar/more.svg b/designer-base/src/main/resources/com/fine/theme/icon/toolbar/more.svg new file mode 100644 index 0000000000..42f49767c8 --- /dev/null +++ b/designer-base/src/main/resources/com/fine/theme/icon/toolbar/more.svg @@ -0,0 +1,3 @@ + + + diff --git a/designer-base/src/main/resources/com/fine/theme/icon/toolbar/more_disable.svg b/designer-base/src/main/resources/com/fine/theme/icon/toolbar/more_disable.svg new file mode 100644 index 0000000000..6570607cd1 --- /dev/null +++ b/designer-base/src/main/resources/com/fine/theme/icon/toolbar/more_disable.svg @@ -0,0 +1,3 @@ + + + diff --git a/designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLaf.properties b/designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLaf.properties index fd9df53c87..41d855e279 100644 --- a/designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLaf.properties +++ b/designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLaf.properties @@ -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 \ No newline at end of file +GradientBarUI=com.fine.theme.light.ui.FineGradientBarUI +TemplateTabPaneUI=com.fine.theme.light.ui.FineTemplateTabPaneUI \ No newline at end of file diff --git a/designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLightLaf.properties b/designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLightLaf.properties index 0184ae3b18..527fd4cc67 100644 --- a/designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLightLaf.properties +++ b/designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLightLaf.properties @@ -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 diff --git a/designer-base/src/test/java/com/fr/design/gui/storybook/components/JTestTemplate.java b/designer-base/src/test/java/com/fr/design/gui/storybook/components/JTestTemplate.java new file mode 100644 index 0000000000..72a97c5d3f --- /dev/null +++ b/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; + } +} diff --git a/designer-base/src/test/java/com/fr/design/gui/storybook/components/TemplateTabStoryBoard.java b/designer-base/src/test/java/com/fr/design/gui/storybook/components/TemplateTabStoryBoard.java new file mode 100644 index 0000000000..31e2406682 --- /dev/null +++ b/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 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()); + } + + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/JForm.java b/designer-form/src/main/java/com/fr/design/mainframe/JForm.java index 97488e7d83..34603c59e0 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/JForm.java +++ b/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 implements BaseJForm { @Override public Icon getIcon() { - return IconUtils.readIcon("/com/fr/design/images/buttonicon/newcpts.png"); + return new LazyIcon("cpt_icon"); } /** diff --git a/designer-realize/src/main/java/com/fr/start/MainDesigner.java b/designer-realize/src/main/java/com/fr/start/MainDesigner.java index 21b6c7eed4..8ab1ea9eb2 100644 --- a/designer-realize/src/main/java/com/fr/start/MainDesigner.java +++ b/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()); }