Leo.Qin
11 months ago
33 changed files with 1740 additions and 860 deletions
@ -0,0 +1,42 @@ |
|||||||
|
package com.fine.theme.light.ui; |
||||||
|
|
||||||
|
import com.fine.theme.utils.FineUIUtils; |
||||||
|
import com.formdev.flatlaf.ui.FlatButtonBorder; |
||||||
|
|
||||||
|
import java.awt.Component; |
||||||
|
import java.awt.Graphics; |
||||||
|
import java.awt.Graphics2D; |
||||||
|
import java.awt.Paint; |
||||||
|
|
||||||
|
import static com.fine.theme.light.ui.FineButtonUI.isPartRoundButton; |
||||||
|
|
||||||
|
/** |
||||||
|
* 按钮边框 |
||||||
|
* |
||||||
|
* @author vito |
||||||
|
* @since 11.0 |
||||||
|
* Created on 2023/12/20 |
||||||
|
*/ |
||||||
|
public class FineButtonBorder extends FlatButtonBorder { |
||||||
|
|
||||||
|
public FineButtonBorder() { |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { |
||||||
|
if (isPartRoundButton(c)) { |
||||||
|
Graphics2D g2 = (Graphics2D) g.create(); |
||||||
|
Paint borderPaint = getBorderColor(c); |
||||||
|
if (borderPaint == null) { |
||||||
|
return; |
||||||
|
} |
||||||
|
g2.setPaint(borderPaint); |
||||||
|
FineUIUtils.paintPartRoundButtonBorder(c, g2, x, y, width, height, borderWidth, (float) getArc(c)); |
||||||
|
} else { |
||||||
|
super.paintBorder(c, g, x, y, width, height); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
@ -0,0 +1,114 @@ |
|||||||
|
package com.fine.theme.light.ui; |
||||||
|
|
||||||
|
import com.fine.theme.utils.FineClientProperties; |
||||||
|
import com.fine.theme.utils.FineUIUtils; |
||||||
|
import com.formdev.flatlaf.ui.FlatButtonUI; |
||||||
|
import com.formdev.flatlaf.ui.FlatUIUtils; |
||||||
|
|
||||||
|
import javax.swing.AbstractButton; |
||||||
|
import javax.swing.JButton; |
||||||
|
import javax.swing.JComponent; |
||||||
|
import javax.swing.plaf.ComponentUI; |
||||||
|
import java.awt.Color; |
||||||
|
import java.awt.Component; |
||||||
|
import java.awt.Graphics; |
||||||
|
import java.awt.Graphics2D; |
||||||
|
import java.awt.geom.Path2D; |
||||||
|
|
||||||
|
import static com.formdev.flatlaf.FlatClientProperties.BUTTON_TYPE; |
||||||
|
|
||||||
|
/** |
||||||
|
* 按钮UI |
||||||
|
* |
||||||
|
* @author vito |
||||||
|
* @since 11.0 |
||||||
|
* Created on 2023/12/20 |
||||||
|
*/ |
||||||
|
public class FineButtonUI extends FlatButtonUI { |
||||||
|
|
||||||
|
/** |
||||||
|
* @param shared |
||||||
|
* @since 2 |
||||||
|
*/ |
||||||
|
protected FineButtonUI(boolean shared) { |
||||||
|
super(shared); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 是否左圆角矩形 |
||||||
|
* |
||||||
|
* @param c 组件 |
||||||
|
* @return 是否左圆角矩形 |
||||||
|
*/ |
||||||
|
public static boolean isLeftRoundButton(Component c) { |
||||||
|
return c instanceof JButton |
||||||
|
&& FineClientProperties.BUTTON_TYPE_LEFT_ROUND_RECT.equals(getButtonTypeStr((JButton) c)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 是否右圆角矩形 |
||||||
|
* |
||||||
|
* @param c 组件 |
||||||
|
* @return 是否右圆角矩形 |
||||||
|
*/ |
||||||
|
public static boolean isRightRoundButton(Component c) { |
||||||
|
return c instanceof JButton |
||||||
|
&& FineClientProperties.BUTTON_TYPE_RIGHT_ROUND_RECT.equals(getButtonTypeStr((JButton) c)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 是否部分圆角矩形 |
||||||
|
* |
||||||
|
* @param c 组件 |
||||||
|
* @return 是否部分圆角矩形 |
||||||
|
*/ |
||||||
|
public static boolean isPartRoundButton(Component c) { |
||||||
|
return isLeftRoundButton(c) || isRightRoundButton(c); |
||||||
|
} |
||||||
|
|
||||||
|
protected void paintBackground(Graphics g, JComponent c) { |
||||||
|
if (isPartRoundButton(c)) { |
||||||
|
Color background = getBackground(c); |
||||||
|
if (background == null) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
Graphics2D g2 = (Graphics2D) g.create(); |
||||||
|
try { |
||||||
|
FlatUIUtils.setRenderingHints(g2); |
||||||
|
float arc = FlatUIUtils.getBorderArc(c); |
||||||
|
int width = c.getWidth(); |
||||||
|
int height = c.getHeight(); |
||||||
|
|
||||||
|
g2.setColor(FlatUIUtils.deriveColor(background, getBackgroundBase(c, false))); |
||||||
|
Path2D path2DLeft; |
||||||
|
if (isLeftRoundButton(c)) { |
||||||
|
path2DLeft = FineUIUtils.createLeftRoundRectangle(0, 0, width, height, arc); |
||||||
|
} else { |
||||||
|
path2DLeft = FineUIUtils.createRightRoundRectangle(0, 0, width, height, arc); |
||||||
|
} |
||||||
|
g2.fill(path2DLeft); |
||||||
|
} finally { |
||||||
|
g2.dispose(); |
||||||
|
} |
||||||
|
} else { |
||||||
|
super.paintBackground(g, c); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 创建UI |
||||||
|
*/ |
||||||
|
public static ComponentUI createUI(JComponent c) { |
||||||
|
return new FineButtonUI(false); |
||||||
|
} |
||||||
|
|
||||||
|
static String getButtonTypeStr(AbstractButton c) { |
||||||
|
Object value = c.getClientProperty(BUTTON_TYPE); |
||||||
|
if (value instanceof String) { |
||||||
|
return (String) value; |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,90 @@ |
|||||||
|
package com.fine.theme.light.ui; |
||||||
|
|
||||||
|
import com.fine.theme.utils.FineClientProperties; |
||||||
|
import com.fine.theme.utils.FineUIUtils; |
||||||
|
import com.formdev.flatlaf.ui.FlatPanelUI; |
||||||
|
import com.formdev.flatlaf.ui.FlatUIUtils; |
||||||
|
import com.fr.design.gui.ibutton.UICombinationButton; |
||||||
|
|
||||||
|
import javax.swing.JComponent; |
||||||
|
import javax.swing.plaf.ComponentUI; |
||||||
|
import java.awt.Color; |
||||||
|
import java.awt.Graphics; |
||||||
|
import java.beans.PropertyChangeEvent; |
||||||
|
|
||||||
|
import static com.formdev.flatlaf.ui.FlatStylingSupport.Styleable; |
||||||
|
|
||||||
|
/** |
||||||
|
* 双组件按钮UI |
||||||
|
* |
||||||
|
* @author vito |
||||||
|
* @since 11.0 |
||||||
|
* Created on 2023/12/21 |
||||||
|
*/ |
||||||
|
public class FineCombinationButtonUI extends FlatPanelUI { |
||||||
|
@Styleable(dot = true) |
||||||
|
protected Color background; |
||||||
|
|
||||||
|
@Styleable(dot = true) |
||||||
|
protected int arc; |
||||||
|
|
||||||
|
@Styleable(dot = true) |
||||||
|
protected Color borderColor; |
||||||
|
|
||||||
|
/** |
||||||
|
* @param shared |
||||||
|
* @since 2 |
||||||
|
*/ |
||||||
|
protected FineCombinationButtonUI(boolean shared) { |
||||||
|
super(shared); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 创建UI |
||||||
|
* |
||||||
|
* @param c 组件 |
||||||
|
* @return ComponentUI |
||||||
|
*/ |
||||||
|
public static ComponentUI createUI(JComponent c) { |
||||||
|
return new FineCombinationButtonUI(false); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void installUI(JComponent c) { |
||||||
|
super.installUI(c); |
||||||
|
background = FineUIUtils.getUIColor("CombinationButton.background", "desktop"); |
||||||
|
borderColor = FineUIUtils.getUIColor("CombinationButton.borderColor", "CombinationButton.secondary.background"); |
||||||
|
arc = FineUIUtils.getUIInt("CombinationButton.arc", "Component.arc"); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void uninstallUI(JComponent c) { |
||||||
|
super.uninstallUI(c); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void paint(Graphics g, JComponent c) { |
||||||
|
paintBackground(g, c); |
||||||
|
super.paint(g, c); |
||||||
|
} |
||||||
|
|
||||||
|
protected void paintBackground(Graphics g, JComponent c) { |
||||||
|
FlatUIUtils.setRenderingHints(g); |
||||||
|
g.setColor(background); |
||||||
|
g.fillRoundRect(0, 0, c.getWidth(), c.getHeight(), arc, arc); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void propertyChange(PropertyChangeEvent e) { |
||||||
|
super.propertyChange(e); |
||||||
|
switch (e.getPropertyName()) { |
||||||
|
case FineClientProperties.STYLE_CLASS: |
||||||
|
UICombinationButton b = (UICombinationButton) e.getSource(); |
||||||
|
b.setPrimary(); |
||||||
|
b.repaint(); |
||||||
|
break; |
||||||
|
default: |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,407 @@ |
|||||||
|
package com.fine.theme.light.ui; |
||||||
|
|
||||||
|
import com.fine.theme.icon.LazyIcon; |
||||||
|
import com.fine.theme.utils.FineClientProperties; |
||||||
|
import com.fine.theme.utils.FineUIUtils; |
||||||
|
import com.formdev.flatlaf.ui.FlatUIUtils; |
||||||
|
import com.fr.base.GraphHelper; |
||||||
|
import com.fr.base.vcs.DesignerMode; |
||||||
|
import com.fr.design.file.MultiTemplateTabPane; |
||||||
|
import com.fr.stable.collections.combination.Pair; |
||||||
|
|
||||||
|
import javax.swing.Icon; |
||||||
|
import javax.swing.JComponent; |
||||||
|
import javax.swing.plaf.ComponentUI; |
||||||
|
import javax.swing.plaf.PanelUI; |
||||||
|
import java.awt.Color; |
||||||
|
import java.awt.Dimension; |
||||||
|
import java.awt.FontMetrics; |
||||||
|
import java.awt.GradientPaint; |
||||||
|
import java.awt.Graphics; |
||||||
|
import java.awt.Graphics2D; |
||||||
|
import java.awt.Insets; |
||||||
|
import java.awt.geom.Path2D; |
||||||
|
import java.awt.geom.Point2D; |
||||||
|
import java.awt.geom.Rectangle2D; |
||||||
|
|
||||||
|
import static com.fine.theme.utils.FineUIScale.scale; |
||||||
|
import static com.fine.theme.utils.FineUIUtils.paintRoundTabBorder; |
||||||
|
import static com.formdev.flatlaf.ui.FlatStylingSupport.Styleable; |
||||||
|
|
||||||
|
/** |
||||||
|
* 文件Tab栏UI |
||||||
|
* |
||||||
|
* @author vito |
||||||
|
* @since 11.0 |
||||||
|
* Created on 2023/12/27 |
||||||
|
*/ |
||||||
|
public class FineTemplateTabPaneUI extends PanelUI { |
||||||
|
private MultiTemplateTabPane tabPane; |
||||||
|
|
||||||
|
private static final String ELLIPSIS = "..."; |
||||||
|
private static final int ICON_TEXT_GAP = 4; |
||||||
|
private static final int LEADING_WIDTH = 0; |
||||||
|
private static final int TRAILING_WIDTH = 34; |
||||||
|
|
||||||
|
|
||||||
|
@Styleable(dot = true) |
||||||
|
protected Color background; |
||||||
|
|
||||||
|
@Styleable(dot = true) |
||||||
|
protected Color selectedBackground; |
||||||
|
|
||||||
|
@Styleable(dot = true) |
||||||
|
protected Color hoverColor; |
||||||
|
|
||||||
|
@Styleable(dot = true) |
||||||
|
protected Color closeIconHoverBackground; |
||||||
|
|
||||||
|
@Styleable(dot = true) |
||||||
|
protected Color closeHoverBackground; |
||||||
|
|
||||||
|
@Styleable(dot = true) |
||||||
|
protected Color borderColor; |
||||||
|
|
||||||
|
@Styleable(dot = true) |
||||||
|
protected int tabHeight; |
||||||
|
|
||||||
|
@Styleable(dot = true) |
||||||
|
protected int separatorHeight; |
||||||
|
|
||||||
|
@Styleable(dot = true) |
||||||
|
protected int borderWidth; |
||||||
|
|
||||||
|
@Styleable(dot = true) |
||||||
|
protected int tabArc; |
||||||
|
|
||||||
|
@Styleable(dot = true) |
||||||
|
protected Insets tabInsets; |
||||||
|
|
||||||
|
protected Icon fileIcon; |
||||||
|
protected Icon moreAction; |
||||||
|
protected Icon addAction; |
||||||
|
protected Icon moreHoverAction; |
||||||
|
|
||||||
|
|
||||||
|
private Icon closeIcon; |
||||||
|
|
||||||
|
private Icon closeHoverIcon; |
||||||
|
|
||||||
|
private int leadingWidth; |
||||||
|
private int trailingWidth; |
||||||
|
|
||||||
|
protected FineTemplateTabPaneUI() { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 创建UI |
||||||
|
* |
||||||
|
* @param c 组件 |
||||||
|
* @return ComponentUI |
||||||
|
*/ |
||||||
|
public static ComponentUI createUI(JComponent c) { |
||||||
|
return new FineTemplateTabPaneUI(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void installUI(JComponent c) { |
||||||
|
super.installUI(c); |
||||||
|
this.tabPane = (MultiTemplateTabPane) c; |
||||||
|
closeIcon = new LazyIcon("clear"); |
||||||
|
closeHoverIcon = new LazyIcon("clear_hover"); |
||||||
|
addAction = new LazyIcon("add_worksheet"); |
||||||
|
moreAction = new LazyIcon("tool_more"); |
||||||
|
moreHoverAction = new LazyIcon("clear_hover"); |
||||||
|
fileIcon = new LazyIcon("cpt_icon"); |
||||||
|
FineClientProperties.setStyle(tabPane, "Default"); |
||||||
|
leadingWidth = scale(LEADING_WIDTH); |
||||||
|
trailingWidth = scale(TRAILING_WIDTH); |
||||||
|
|
||||||
|
borderWidth = FineUIUtils.getUIInt("TemplateTabPane.borderWidth", "TemplateTabPane.borderWidth"); |
||||||
|
tabArc = FineUIUtils.getUIInt("TemplateTabPane.tabArc", "TemplateTabPane.tabArc"); |
||||||
|
background = FineUIUtils.getUIColor("TemplateTabPane.background", "TabbedPane.background"); |
||||||
|
selectedBackground = FineUIUtils.getUIColor("TemplateTabPane.selectedBackground", "TemplateTabPane.selectedBackground"); |
||||||
|
closeHoverBackground = FineUIUtils.getUIColor("TemplateTabPane.closeHoverBackground", "TemplateTabPane.closeHoverBackground"); |
||||||
|
borderColor = FineUIUtils.getUIColor("TemplateTabPane.borderColor", "TabbedPane.tabSeparatorColor"); |
||||||
|
hoverColor = FineUIUtils.getUIColor("TemplateTabPane.hoverColor", "TemplateTabPane.hoverColor"); |
||||||
|
closeIconHoverBackground = FineUIUtils.getUIColor("TemplateTabPane.icon.hoverBackground ", "TemplateTabPane.icon.hoverBackground "); |
||||||
|
// ---- scaled ----
|
||||||
|
tabInsets = FineUIUtils.getAndScaleUIInsets("TemplateTabPane.tabInsets", new Insets(4, 6, 4, 6)); |
||||||
|
tabHeight = FineUIUtils.getAndScaleInt("TemplateTabPane.tabHeight", "TabbedPane.tabHeight"); |
||||||
|
separatorHeight = FineUIUtils.getAndScaleInt("TemplateTabPane.separatorHeight", "TemplateTabPane.separatorHeight"); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void uninstallUI(JComponent c) { |
||||||
|
super.uninstallUI(c); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public void update(Graphics g, JComponent c) { |
||||||
|
super.update(g, c); |
||||||
|
double maxWidth = c.getWidth() - leadingWidth - trailingWidth; |
||||||
|
Graphics2D g2d = (Graphics2D) g; |
||||||
|
paintDefaultBackground(g2d); |
||||||
|
paintPaneUnderLine(c.getWidth(), g2d); |
||||||
|
paintTabs(g2d, maxWidth); |
||||||
|
} |
||||||
|
|
||||||
|
private void paintDefaultBackground(Graphics2D g2d) { |
||||||
|
//画默认背景
|
||||||
|
g2d.setPaint(new GradientPaint(0, 0, tabPane.getBackground(), 1, (float) (tabHeight), tabPane.getBackground())); |
||||||
|
g2d.fillRect(0, 0, tabPane.getWidth(), tabHeight); |
||||||
|
} |
||||||
|
|
||||||
|
private void paintPaneUnderLine(float w, Graphics2D g2d) { |
||||||
|
g2d.setPaint(borderColor); |
||||||
|
float h = (float) tabHeight; |
||||||
|
int t = scale(borderWidth); |
||||||
|
Path2D border = new Path2D.Float(Path2D.WIND_EVEN_ODD); |
||||||
|
border.append(FlatUIUtils.createComponentRectangle(0, 0, w, h, 0), false); |
||||||
|
border.append(FlatUIUtils.createComponentRectangle(0, 0, w, h - t, 0), false); |
||||||
|
g2d.fill(border); |
||||||
|
} |
||||||
|
|
||||||
|
private void paintTabs(Graphics2D g2d, double maxWidth) { |
||||||
|
|
||||||
|
int maxStringlength = calculateStringMaxLength(); |
||||||
|
if (tabPane.getSelectedIndex() >= tabPane.getTabCount()) { |
||||||
|
tabPane.setSelectedIndex(tabPane.getTabCount() - 1); |
||||||
|
} |
||||||
|
if (tabPane.getSelectedIndex() < 0) { |
||||||
|
tabPane.setSelectedIndex(0); |
||||||
|
} |
||||||
|
double templateStartX = leadingWidth; |
||||||
|
|
||||||
|
|
||||||
|
//从可以开始展示在tab面板上的tab开始画
|
||||||
|
Pair<Integer, Integer> viewRange = tabPane.getViewRange(); |
||||||
|
for (int i = viewRange.getFirst(); i <= viewRange.getSecond(); i++) { |
||||||
|
Icon icon = tabPane.getTemplateIconByIndex(i); |
||||||
|
String name = tabPane.getTemplateShowNameByIndex(i); |
||||||
|
//如果tab名字的长度大于最大能显示的英文字符长度,则进行省略号处理
|
||||||
|
if (getStringWidth(name) > maxStringlength) { |
||||||
|
name = getEllipsisName(name, maxStringlength); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
Icon tabcloseIcon = tabPane.isCloseCurrent(i) ? closeHoverIcon : closeIcon; |
||||||
|
if (i == tabPane.getSelectedIndex()) { |
||||||
|
paintSelectedTab(g2d, icon, templateStartX, name, tabcloseIcon); |
||||||
|
} else { |
||||||
|
paintUnSelectedTab(g2d, icon, templateStartX, name, tabcloseIcon, |
||||||
|
tabPane.getHoverIndex(), i); |
||||||
|
} |
||||||
|
templateStartX += tabPane.getTabWidth(); |
||||||
|
} |
||||||
|
|
||||||
|
paintSeparators(g2d); |
||||||
|
|
||||||
|
if (!DesignerMode.isVcsMode()) { |
||||||
|
paintTrailingAction(g2d, maxWidth); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void paintSeparators(Graphics2D g2d) { |
||||||
|
g2d.setPaint(borderColor); |
||||||
|
float x = leadingWidth; |
||||||
|
Pair<Integer, Integer> viewRange = tabPane.getViewRange(); |
||||||
|
for (int i = viewRange.getFirst(); i <= viewRange.getSecond(); i++) { |
||||||
|
if (i != tabPane.getSelectedIndex() |
||||||
|
&& i + 1 != tabPane.getSelectedIndex()) { |
||||||
|
paintSeparator(g2d, x); |
||||||
|
} |
||||||
|
x += tabPane.getTabWidth(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void paintLeadingAction(Graphics2D g2d, double tabPaneWidth) { |
||||||
|
int x = (leadingWidth - addAction.getIconWidth()) / 2; |
||||||
|
int y = (tabHeight - addAction.getIconHeight()) / 2; |
||||||
|
if (tabPane.isHoverMoreAction()) { |
||||||
|
closeHoverIcon.paintIcon(tabPane, g2d, x, y); |
||||||
|
} else { |
||||||
|
addAction.paintIcon(tabPane, g2d, x, y); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private void paintTrailingAction(Graphics2D g2d, double tabPaneWidth) { |
||||||
|
int x = leadingWidth + (int) tabPaneWidth + (trailingWidth - moreAction.getIconWidth()) / 2; |
||||||
|
int y = (tabHeight - moreAction.getIconHeight()) / 2; |
||||||
|
if (tabPane.isHoverMoreAction()) { |
||||||
|
closeHoverIcon.paintIcon(tabPane, g2d, x, y); |
||||||
|
} else { |
||||||
|
moreAction.paintIcon(tabPane, g2d, x, y); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 判断tab文字的长度大于能装下的最大文字长度,要用省略号 |
||||||
|
* |
||||||
|
* @param name |
||||||
|
* @param maxStringlength |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
private String getEllipsisName(String name, int maxStringlength) { |
||||||
|
|
||||||
|
int ellipsisWidth = getStringWidth(ELLIPSIS); |
||||||
|
int leftkeyPoint = 0; |
||||||
|
int rightKeyPoint = name.length() - 1; |
||||||
|
int leftStrWidth = 0; |
||||||
|
int rightStrWidth = 0; |
||||||
|
while (leftStrWidth + rightStrWidth + ellipsisWidth < maxStringlength) { |
||||||
|
if (leftStrWidth <= rightStrWidth) { |
||||||
|
leftkeyPoint++; |
||||||
|
} else { |
||||||
|
rightKeyPoint--; |
||||||
|
} |
||||||
|
leftStrWidth = getStringWidth(name.substring(0, leftkeyPoint)); |
||||||
|
rightStrWidth = getStringWidth(name.substring(rightKeyPoint)); |
||||||
|
|
||||||
|
if (leftStrWidth + rightStrWidth + ellipsisWidth > maxStringlength) { |
||||||
|
if (leftStrWidth <= rightStrWidth) { |
||||||
|
rightKeyPoint++; |
||||||
|
} else { |
||||||
|
leftkeyPoint--; |
||||||
|
} |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
return name.substring(0, leftkeyPoint) + ELLIPSIS + name.substring(rightKeyPoint); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 计算过长度之后的每个tab的能接受的文字的英文字符数 |
||||||
|
* |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
private int calculateStringMaxLength() { |
||||||
|
return tabPane.getTabWidth() |
||||||
|
- tabInsets.left - tabInsets.right |
||||||
|
- ICON_TEXT_GAP * 2 |
||||||
|
- fileIcon.getIconWidth() - closeIcon.getIconWidth(); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
private int getStringWidth(String str) { |
||||||
|
FontMetrics fm = GraphHelper.getFontMetrics(tabPane.getFont()); |
||||||
|
int size = 0; |
||||||
|
for (int i = 0; i < str.length(); i++) { |
||||||
|
size += fm.charWidth(str.codePointAt(i)); |
||||||
|
} |
||||||
|
return size; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* 画选中的tab |
||||||
|
* |
||||||
|
* @param g2d |
||||||
|
* @param sheeticon |
||||||
|
* @param templateStartX |
||||||
|
* @param sheetName |
||||||
|
* @param closeIcon |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
private void paintSelectedTab(Graphics2D g2d, Icon sheeticon, double templateStartX, String sheetName, Icon closeIcon) { |
||||||
|
Object[] oriRenderingHints = FlatUIUtils.setRenderingHints(g2d); |
||||||
|
// 绘制选中背景
|
||||||
|
g2d.setPaint(selectedBackground); |
||||||
|
Path2D tabShape = FineUIUtils.createTopRoundRectangle(templateStartX, 0, |
||||||
|
tabPane.getTabWidth(), tabHeight, tabArc); |
||||||
|
g2d.fill(tabShape); |
||||||
|
// 绘制选中边框
|
||||||
|
g2d.setPaint(borderColor); |
||||||
|
paintRoundTabBorder(g2d, templateStartX, 0, |
||||||
|
tabPane.getTabWidth(), tabHeight, borderWidth, (float) tabArc); |
||||||
|
FlatUIUtils.resetRenderingHints(g2d, oriRenderingHints); |
||||||
|
// 绘制图标
|
||||||
|
int sheetIconY = (tabHeight - sheeticon.getIconHeight()) / 2; |
||||||
|
sheeticon.paintIcon(tabPane, g2d, (int) templateStartX + tabInsets.left, sheetIconY); |
||||||
|
// 绘制字符
|
||||||
|
g2d.setPaint(tabPane.getForeground()); |
||||||
|
Point2D.Double textPoint = calTextPoint(templateStartX, sheeticon.getIconWidth()); |
||||||
|
g2d.drawString(sheetName, (int) textPoint.x, (int) textPoint.y); |
||||||
|
int closePosition = (int) templateStartX + tabPane.getTabWidth() |
||||||
|
- this.closeIcon.getIconWidth() - tabInsets.right; |
||||||
|
int closeY = (tabHeight - closeIcon.getIconHeight()) / 2; |
||||||
|
if (!DesignerMode.isVcsMode()) { |
||||||
|
closeIcon.paintIcon(tabPane, g2d, closePosition, closeY); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private Point2D.Double calTextPoint(double x, int iconWidth) { |
||||||
|
FontMetrics fm = tabPane.getFontMetrics(tabPane.getFont()); |
||||||
|
int ascent = fm.getAscent(); |
||||||
|
int gap = (tabHeight - tabInsets.top - tabInsets.bottom - ascent) / 2; |
||||||
|
double y = tabInsets.top + ascent + gap; |
||||||
|
return new Point2D.Double(x + iconWidth + tabInsets.left + ICON_TEXT_GAP, y); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* 画没有选中的tab |
||||||
|
* |
||||||
|
* @param g2d |
||||||
|
* @param sheeticon |
||||||
|
* @param templateStartX |
||||||
|
* @param sheetName |
||||||
|
* @param closeIcon |
||||||
|
*/ |
||||||
|
private void paintUnSelectedTab(Graphics2D g2d, Icon sheeticon, double templateStartX, String sheetName, Icon closeIcon, int mouseOveredIndex, int selfIndex) { |
||||||
|
if (selfIndex == mouseOveredIndex) { |
||||||
|
g2d.setPaint(hoverColor); |
||||||
|
} else { |
||||||
|
g2d.setPaint(background); |
||||||
|
} |
||||||
|
|
||||||
|
Object[] oriRenderingHints = FlatUIUtils.setRenderingHints(g2d); |
||||||
|
|
||||||
|
Path2D tabShape = FineUIUtils.createTopRoundRectangle(templateStartX, 0, |
||||||
|
tabPane.getTabWidth(), tabHeight - scale(borderWidth), tabArc); |
||||||
|
g2d.fill(tabShape); |
||||||
|
|
||||||
|
|
||||||
|
FlatUIUtils.resetRenderingHints(g2d, oriRenderingHints); |
||||||
|
|
||||||
|
int sheetIconY = (tabHeight - sheeticon.getIconHeight()) / 2; |
||||||
|
sheeticon.paintIcon(tabPane, g2d, (int) templateStartX + tabInsets.left, sheetIconY); |
||||||
|
// 画字符
|
||||||
|
g2d.setPaint(tabPane.getForeground()); |
||||||
|
Point2D.Double textPoint = calTextPoint(templateStartX, sheeticon.getIconWidth()); |
||||||
|
g2d.drawString(sheetName, (int) textPoint.x, (int) textPoint.y); |
||||||
|
int closeY = (tabHeight - closeIcon.getIconHeight()) / 2; |
||||||
|
int closePosition = (int) templateStartX + tabPane.getTabWidth() |
||||||
|
- this.closeIcon.getIconWidth() - tabInsets.right; |
||||||
|
if (!DesignerMode.isVcsMode()) { |
||||||
|
closeIcon.paintIcon(tabPane, g2d, closePosition, closeY); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void paintSeparator(Graphics2D g2d, float templateStartX) { |
||||||
|
float x = templateStartX + tabPane.getTabWidth(); |
||||||
|
float gap = (tabHeight - separatorHeight) / 2.0f; |
||||||
|
g2d.fill(new Rectangle2D.Float(x, gap, scale(borderWidth), tabHeight - gap * 2)); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public Dimension getPreferredSize(JComponent c) { |
||||||
|
return new Dimension(c.getWidth(), tabHeight); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Dimension getMinimumSize(JComponent c) { |
||||||
|
return new Dimension(0, tabHeight); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Dimension getMaximumSize(JComponent c) { |
||||||
|
return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE); |
||||||
|
} |
||||||
|
} |
@ -1,143 +1,155 @@ |
|||||||
package com.fr.design.gui.ibutton; |
package com.fr.design.gui.ibutton; |
||||||
|
|
||||||
import java.awt.BorderLayout; |
import com.fr.design.utils.gui.GUICoreUtils; |
||||||
import java.awt.event.MouseAdapter; |
|
||||||
import java.awt.event.MouseEvent; |
|
||||||
|
|
||||||
import javax.swing.Icon; |
import javax.swing.Icon; |
||||||
import javax.swing.JFrame; |
|
||||||
import javax.swing.JPanel; |
import javax.swing.JPanel; |
||||||
import javax.swing.JPopupMenu; |
import javax.swing.JPopupMenu; |
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.awt.event.MouseAdapter; |
||||||
|
import java.awt.event.MouseEvent; |
||||||
|
import java.util.function.Consumer; |
||||||
|
|
||||||
import com.fr.design.constants.UIConstants; |
import static com.fine.theme.utils.FineClientProperties.BUTTON_TYPE_LEFT_ROUND_RECT; |
||||||
import com.fr.stable.Constants; |
import static com.fine.theme.utils.FineClientProperties.BUTTON_TYPE_RIGHT_ROUND_RECT; |
||||||
import com.fr.design.utils.gui.GUICoreUtils; |
import static com.fine.theme.utils.FineClientProperties.STYLE_PRIMARY; |
||||||
|
import static com.fine.theme.utils.FineClientProperties.setStyle; |
||||||
|
import static com.formdev.flatlaf.FlatClientProperties.BUTTON_TYPE; |
||||||
|
|
||||||
|
/** |
||||||
|
* 双按钮组件 |
||||||
|
* |
||||||
|
* @author vito |
||||||
|
* @since 11.0 |
||||||
|
* <p> |
||||||
|
* created by vito on 2023/12/28 |
||||||
|
**/ |
||||||
|
public class UICombinationButton extends JPanel { |
||||||
|
private static final String UI_CLASS_ID = "CombinationButtonUI"; |
||||||
|
|
||||||
|
protected UIButton leftButton; |
||||||
|
protected UIButton rightButton; |
||||||
|
|
||||||
|
|
||||||
|
private Consumer<MouseEvent> leftClickLister; |
||||||
|
private Consumer<MouseEvent> rightClickLister; |
||||||
|
|
||||||
|
protected void leftButtonClickEvent() { |
||||||
|
// 左边按钮点击事件
|
||||||
|
} |
||||||
|
|
||||||
|
protected void rightButtonClickEvent() { |
||||||
|
// 右边按钮点击事件
|
||||||
|
} |
||||||
|
|
||||||
|
public UICombinationButton() { |
||||||
|
this(new UIButton(), new UIButton()); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* 添加左按钮监听器 |
||||||
|
* |
||||||
|
* @param lister 监听 |
||||||
|
*/ |
||||||
|
public void addLeftClickLister(Consumer<MouseEvent> lister) { |
||||||
|
this.leftClickLister = lister; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 添加右按钮监听器 |
||||||
|
* |
||||||
|
* @param lister 监听 |
||||||
|
*/ |
||||||
|
public void addRightClickLister(Consumer<MouseEvent> lister) { |
||||||
|
this.rightClickLister = lister; |
||||||
|
} |
||||||
|
|
||||||
|
public UICombinationButton(UIButton left, UIButton right) { |
||||||
|
leftButton = left; |
||||||
|
leftButton.putClientProperty(BUTTON_TYPE, BUTTON_TYPE_LEFT_ROUND_RECT); |
||||||
|
rightButton = right; |
||||||
|
rightButton.putClientProperty(BUTTON_TYPE, BUTTON_TYPE_RIGHT_ROUND_RECT); |
||||||
|
leftButton.addMouseListener(new MouseAdapter() { |
||||||
|
@Override |
||||||
|
public void mouseClicked(MouseEvent e) { |
||||||
|
if (leftClickLister != null) { |
||||||
|
leftClickLister.accept(e); |
||||||
|
} else { |
||||||
|
leftButtonClickEvent(); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
rightButton.addMouseListener(new MouseAdapter() { |
||||||
|
|
||||||
|
@Override |
||||||
|
public void mouseClicked(MouseEvent e) { |
||||||
|
if (rightClickLister != null) { |
||||||
|
rightClickLister.accept(e); |
||||||
|
} else { |
||||||
|
rightButtonClickEvent(); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
this.setLayout(new BorderLayout()); |
||||||
|
this.add(leftButton, BorderLayout.WEST); |
||||||
|
this.add(rightButton, BorderLayout.EAST); |
||||||
|
} |
||||||
|
|
||||||
|
public UICombinationButton(String left, Icon right) { |
||||||
|
this(); |
||||||
|
leftButton.setText(left); |
||||||
|
rightButton.setIcon(right); |
||||||
|
} |
||||||
|
|
||||||
|
public UICombinationButton(String left, String right) { |
||||||
|
this(); |
||||||
|
leftButton.setText(left); |
||||||
|
rightButton.setText(right); |
||||||
|
} |
||||||
|
|
||||||
|
public UICombinationButton(Icon left, Icon right) { |
||||||
|
this(); |
||||||
|
leftButton.setIcon(left); |
||||||
|
rightButton.setIcon(right); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getUIClassID() { |
||||||
|
return UI_CLASS_ID; |
||||||
|
} |
||||||
|
|
||||||
|
public void setPrimary() { |
||||||
|
setStyle(leftButton, STYLE_PRIMARY); |
||||||
|
setStyle(rightButton, STYLE_PRIMARY); |
||||||
|
} |
||||||
|
|
||||||
|
public UIButton getLeftButton() { |
||||||
|
return leftButton; |
||||||
|
} |
||||||
|
|
||||||
|
public void setExtraPainted(boolean isExtraPainted) { |
||||||
|
// if (!isExtraPainted) {
|
||||||
|
// leftButton.setBackground(null);
|
||||||
|
// rightButton.setBackground(null);
|
||||||
|
// leftButton.setOpaque(false);
|
||||||
|
// rightButton.setOpaque(false);
|
||||||
|
// }
|
||||||
|
} |
||||||
|
|
||||||
|
public UIButton getRightButton() { |
||||||
|
return rightButton; |
||||||
|
} |
||||||
|
|
||||||
|
public void set4Toolbar() { |
||||||
|
leftButton.setNormalPainted(false); |
||||||
|
rightButton.setNormalPainted(false); |
||||||
|
leftButton.setBorderPaintedOnlyWhenPressed(true); |
||||||
|
rightButton.setBorderPaintedOnlyWhenPressed(true); |
||||||
|
} |
||||||
|
|
||||||
public class UICombinationButton extends JPanel{ |
protected void showPopWindow(JPopupMenu menu) { |
||||||
protected UIButton leftButton; |
GUICoreUtils.showPopupMenu(menu, this, 0, getY() + getHeight() - 3); |
||||||
protected UIButton rightButton; |
} |
||||||
|
|
||||||
protected void leftButtonClickEvent() { |
|
||||||
// 左边按钮点击事件
|
|
||||||
} |
|
||||||
|
|
||||||
protected void rightButtonClickEvent() { |
|
||||||
// 右边按钮点击事件
|
|
||||||
} |
|
||||||
|
|
||||||
public UICombinationButton() { |
|
||||||
this(new UIButton(), new UIButton()); |
|
||||||
} |
|
||||||
|
|
||||||
public UICombinationButton(UIButton left, UIButton right) { |
|
||||||
leftButton = left; |
|
||||||
rightButton = right; |
|
||||||
|
|
||||||
leftButton.setRoundBorder(true, Constants.RIGHT); |
|
||||||
rightButton.setRoundBorder(true, Constants.LEFT); |
|
||||||
|
|
||||||
leftButton.addMouseListener(new MouseAdapter() { |
|
||||||
@Override |
|
||||||
public void mousePressed(MouseEvent e) { |
|
||||||
rightButton.getModel().setPressed(true); |
|
||||||
rightButton.getModel().setSelected(true); |
|
||||||
rightButton.repaint(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void mouseReleased(MouseEvent e) { |
|
||||||
rightButton.getModel().setPressed(false); |
|
||||||
rightButton.getModel().setSelected(false); |
|
||||||
rightButton.repaint(); |
|
||||||
} |
|
||||||
@Override |
|
||||||
public void mouseClicked(MouseEvent e) { |
|
||||||
leftButtonClickEvent(); |
|
||||||
} |
|
||||||
}); |
|
||||||
rightButton.addMouseListener(new MouseAdapter() { |
|
||||||
@Override |
|
||||||
public void mousePressed(MouseEvent e) { |
|
||||||
leftButton.getModel().setPressed(true); |
|
||||||
leftButton.getModel().setSelected(true); |
|
||||||
leftButton.repaint(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void mouseReleased(MouseEvent e) { |
|
||||||
leftButton.getModel().setPressed(false); |
|
||||||
leftButton.getModel().setSelected(false); |
|
||||||
leftButton.repaint(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void mouseClicked(MouseEvent e) { |
|
||||||
rightButtonClickEvent(); |
|
||||||
} |
|
||||||
}); |
|
||||||
|
|
||||||
this.setLayout(new BorderLayout()); |
|
||||||
this.add(leftButton, BorderLayout.CENTER); |
|
||||||
this.add(rightButton, BorderLayout.EAST); |
|
||||||
} |
|
||||||
|
|
||||||
public UICombinationButton(String left, Icon right) { |
|
||||||
this(); |
|
||||||
leftButton.setText(left); |
|
||||||
rightButton.setIcon(right); |
|
||||||
} |
|
||||||
|
|
||||||
public UICombinationButton(String left, String right) { |
|
||||||
this(); |
|
||||||
leftButton.setText(left); |
|
||||||
rightButton.setText(right); |
|
||||||
} |
|
||||||
|
|
||||||
public UICombinationButton(Icon left, Icon right) { |
|
||||||
this(); |
|
||||||
leftButton.setIcon(left); |
|
||||||
rightButton.setIcon(right); |
|
||||||
} |
|
||||||
|
|
||||||
public UIButton getLeftButton() { |
|
||||||
return leftButton; |
|
||||||
} |
|
||||||
|
|
||||||
public void setExtraPainted(boolean isExtraPainted) { |
|
||||||
if(!isExtraPainted) { |
|
||||||
leftButton.setBackground(null); |
|
||||||
rightButton.setBackground(null); |
|
||||||
leftButton.setOpaque(false); |
|
||||||
rightButton.setOpaque(false); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public UIButton getRightButton() { |
|
||||||
return rightButton; |
|
||||||
} |
|
||||||
|
|
||||||
public void set4Toolbar() { |
|
||||||
leftButton.setNormalPainted(false); |
|
||||||
rightButton.setNormalPainted(false); |
|
||||||
leftButton.setBorderPaintedOnlyWhenPressed(true); |
|
||||||
rightButton.setBorderPaintedOnlyWhenPressed(true); |
|
||||||
} |
|
||||||
|
|
||||||
protected void showPopWindow(JPopupMenu menu) { |
|
||||||
GUICoreUtils.showPopupMenu(menu, this, 0, getY() + getHeight() - 3); |
|
||||||
} |
|
||||||
|
|
||||||
public static void main(String... args) { |
|
||||||
JFrame jf = new JFrame("test"); |
|
||||||
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); |
|
||||||
JPanel content = (JPanel)jf.getContentPane(); |
|
||||||
content.setLayout(null); |
|
||||||
|
|
||||||
UICombinationButton bb = new UICombinationButton("123455", UIConstants.ARROW_DOWN_ICON); |
|
||||||
bb.setBounds(20, 20, bb.getPreferredSize().width, bb.getPreferredSize().height); |
|
||||||
content.add(bb); |
|
||||||
GUICoreUtils.centerWindow(jf); |
|
||||||
jf.setSize(400, 400); |
|
||||||
jf.setVisible(true); |
|
||||||
} |
|
||||||
} |
} |
After Width: | Height: | Size: 875 B |
After Width: | Height: | Size: 828 B |
After Width: | Height: | Size: 829 B |
@ -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; |
||||||
|
} |
||||||
|
} |
@ -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()); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
Loading…
Reference in new issue