Browse Source

fix: CalendarUI 和 ButtonUI 解耦,增加 storybook

fbp/release
lemon 2 months ago
parent
commit
8751091a6e
  1. 161
      designer-base/src/main/java/com/fine/theme/light/ui/FineCalendarPaneUI.java
  2. 54
      designer-base/src/main/java/com/fine/theme/light/ui/FineDayLabelUI.java
  3. 1
      designer-base/src/main/java/com/fr/design/gui/date/CalendarNumberField.java
  4. 58
      designer-base/src/main/java/com/fr/design/gui/date/UICalendarPanel.java
  5. 61
      designer-base/src/main/java/com/fr/design/gui/date/UIDayLabel.java
  6. 2
      designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLaf.properties
  7. 5
      designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLightLaf.properties
  8. 32
      designer-base/src/test/java/com/fr/design/gui/storybook/components/UICalendarPaneStoryBoard.java

161
designer-base/src/main/java/com/fine/theme/light/ui/FineCalendarPaneUI.java

@ -0,0 +1,161 @@
package com.fine.theme.light.ui;
import com.fine.theme.utils.FineUIScale;
import com.formdev.flatlaf.ui.FlatRoundBorder;
import com.formdev.flatlaf.ui.FlatUIUtils;
import com.fr.design.gui.date.UICalendarPanel;
import com.fr.design.gui.date.UIDayLabel;
import javax.swing.JComponent;
import javax.swing.UIManager;
import javax.swing.border.LineBorder;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.PanelUI;
import java.awt.Color;
import java.awt.Component;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
/**
* {@link UICalendarPanel} UI 样式
* @author lemon
* @since 12.0
* Created on 2024/09/22
*/
public class FineCalendarPaneUI extends PanelUI {
protected Color defaultBackground;
protected Color selectedBackground;
protected Color hoverBackground;
protected Color pressedBackground;
protected Color otherMonthForeground;
protected int arc;
/**
* @param shared
* @since 2
*/
protected FineCalendarPaneUI() {
super();
}
/**
* 创建UI
*
* @param c 组件
* @return ComponentUI
*/
public static ComponentUI createUI(JComponent c) {
return FlatUIUtils.createSharedUI(FineCalendarPaneUI.class, FineCalendarPaneUI::new);
}
/**
*
* @param c the component where this UI delegate is being installed
*
*/
public void installUI(JComponent c) {
super.installUI(c);
selectedBackground = UIManager.getColor("Calendar.day.selectedBackground");
hoverBackground = UIManager.getColor("Calendar.day.hoverBackground");
pressedBackground = UIManager.getColor("Calendar.day.pressedBackground");
defaultBackground = UIManager.getColor("Calendar.background");
otherMonthForeground = UIManager.getColor("Calendar.dayOtherMonth.foreground");
arc = UIManager.getInt("Calendar.day.arc");
//renderer this
c.setBackground(defaultBackground);
c.setBorder(new LineBorder(FlatUIUtils.getUIColor("defaultBorderColor", Color.BLACK)));
}
@Override
public void uninstallUI(JComponent c) {
super.uninstallUI(c);
}
/**
* UICalendarPanel paint, 目前只对 {@link UIDayLabel} 样式自定义其余使用默认样式
* @param g the <code>Graphics</code> context in which to paint
* @param c the component being painted;
* this argument is often ignored,
* but might be used if the UI object is stateless
* and shared by multiple components
*
*/
public void paint(Graphics g, JComponent c) {
if (c instanceof UICalendarPanel) {
UICalendarPanel calendar = (UICalendarPanel) c;
paintComponent(calendar);
}
}
private void paintComponent(JComponent component) {
if (component instanceof UIDayLabel) {
paintDayLabel((UIDayLabel) component);
return;
}
for (Component c : component.getComponents()) {
paintComponent((JComponent) c);
}
}
private void paintDayLabel(UIDayLabel label) {
if (!label.isSmallLabel()) {
return;
}
label.setBorder(new DayLabelRoundedBorder());
if (!label.isCurrentMonth()) {
label.setForeground(otherMonthForeground);
}
}
private Color getBackgroundColor(UIDayLabel dayLabel) {
if (dayLabel.isSelected()) {
return selectedBackground;
}
if (dayLabel.isHovered()) {
return hoverBackground;
}
if (dayLabel.isPressed()) {
return pressedBackground;
}
return defaultBackground;
}
/**
* {@link UIDayLabel} border 样式
*/
private class DayLabelRoundedBorder extends FlatRoundBorder {
public DayLabelRoundedBorder() {
}
@Override
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
Graphics2D g2 = (Graphics2D)g.create();
try {
FlatUIUtils.setRenderingHints(g2);
g2.setColor(getBackgroundColor((UIDayLabel) c));
g2.fillRoundRect(0, 0, width , height, arc, arc);
// 避免文字被背景色覆盖
UIDayLabel dayLabel = (UIDayLabel) c;
g2.setColor(dayLabel.getForeground());
FontMetrics metrics = g2.getFontMetrics(dayLabel.getFont());
int x1 = (width - metrics.stringWidth(dayLabel.getText())) / 2;
int y1 = ((height - metrics.getHeight()) / 2) + metrics.getAscent();
g2.drawString(dayLabel.getText(), x1, y1);
} finally {
g2.dispose();
}
}
}
}

54
designer-base/src/main/java/com/fine/theme/light/ui/FineDayLabelUI.java

@ -1,54 +0,0 @@
package com.fine.theme.light.ui;
import com.fr.design.gui.date.UIDayLabel;
import javax.swing.AbstractButton;
import javax.swing.JComponent;
import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
import java.awt.Color;
/**
* {@link UIDayLabel} UI 样式
* @author lemon
* @since 12.0
* Created on 2024/09/22
*/
public class FineDayLabelUI extends FineButtonUI {
protected Color selectedBackground;
/**
* @param shared
* @since 2
*/
protected FineDayLabelUI(boolean shared) {
super(shared);
}
/**
* 创建UI
*
* @param c 组件
* @return ComponentUI
*/
public static ComponentUI createUI(JComponent c) {
return new FineDayLabelUI(false);
}
@Override
protected void installDefaults(AbstractButton b) {
super.installDefaults(b);
selectedBackground = UIManager.getColor("Calendar.day.selectedBackground");
}
@Override
protected Color getBackground(JComponent c) {
if (c instanceof UIDayLabel) {
return ((UIDayLabel) c).isSelected() ? selectedBackground : super.getBackground(c);
}
return super.getBackground(c);
}
}

1
designer-base/src/main/java/com/fr/design/gui/date/CalendarNumberField.java

@ -36,7 +36,6 @@ public class CalendarNumberField extends UINumberField {
setValue(getIntValue());
}
});
this.setFont(DesignUtils.getDefaultGUIFont());
}
public void setValue(int value) {

58
designer-base/src/main/java/com/fr/design/gui/date/UICalendarPanel.java

@ -5,29 +5,22 @@ import com.fine.theme.icon.LazyIcon;
import com.fine.theme.light.ui.FineRoundBorder;
import com.fine.theme.utils.FineUIStyle;
import com.fine.theme.utils.FineUIUtils;
import com.formdev.flatlaf.ui.FlatUIUtils;
import com.formdev.flatlaf.util.ScaledEmptyBorder;
import com.fr.design.border.FineBorderFactory;
import com.fr.design.carton.MonthlyCartonFile;
import com.fr.design.carton.SwitchForSwingChecker;
import com.fr.design.constants.UIConstants;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.utils.DesignUtils;
import com.fr.general.GeneralUtils;
import com.fr.stable.Constants;
import com.fr.stable.StableUtils;
import com.fr.stable.StringUtils;
import javax.swing.Box;
import javax.swing.Icon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.border.LineBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.EventListenerList;
@ -60,9 +53,10 @@ import static com.fine.theme.utils.FineUIStyle.STYLE_TEXT;
import static com.fine.theme.utils.FineUIStyle.setStyle;
public class UICalendarPanel extends JPanel {
private static final String UI_CLASS_ID = "CalendarPaneUI";
private static final Font FONT_UI = DesignUtils.getDefaultGUIFont().applySize(scale(12));
private static final Font FONT_BLACK = new Font(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Black_Font"), Font.PLAIN, scale(12));
// private static final Font FONT_UI = DesignUtils.getDefaultGUIFont().applySize(scale(12));
// private static final Font FONT_BLACK = new Font(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Black_Font"), Font.PLAIN, scale(12));
private static final int WEEKDAY_COUNT = 7;
private static final int TOTAL_DAYS_COUNT = 42;
protected final Insets defaultInsets = new Insets(0, 6, 0, 6);
@ -124,10 +118,6 @@ public class UICalendarPanel extends JPanel {
calendar = Calendar.getInstance();
dayBttListener = createDayBttListener();
//renderer this
setBackground(FlatUIUtils.getUIColor("fill.normal", Color.WHITE));
setBorder(new LineBorder(FlatUIUtils.getUIColor("defaultBorderColor", Color.BLACK)));
setLayout(FRGUIPaneFactory.createBorderLayout());
add(BorderLayout.NORTH, createNorthPane());
add(BorderLayout.CENTER, createCenterPane());
@ -153,7 +143,6 @@ public class UICalendarPanel extends JPanel {
UIButton monthMinus = createSkipButton(Calendar.MONTH, -1, new LazyIcon("left_arrow"));
pNorth.add(monthMinus);
monthLabel = new UILabel("", UILabel.CENTER);
monthLabel.setFont(FONT_UI);
pNorth.add(Box.createHorizontalGlue());
pNorth.add(monthLabel);
pNorth.add(Box.createHorizontalGlue());
@ -180,7 +169,6 @@ public class UICalendarPanel extends JPanel {
for (int i = 1; i <= WEEKDAY_COUNT; i++) {
UILabel label = new UILabel();
label.setHorizontalAlignment(UILabel.CENTER);
label.setFont(FONT_BLACK);
label.setText(strWeeks[i]);
label.setPreferredSize(createScaleDimension(WEEK_LABEL_WIDTH, WEEK_LABEL_HEIGHT));
pWeeks.add(label);
@ -211,7 +199,6 @@ public class UICalendarPanel extends JPanel {
sPane.setOpaque(false);
sPane.setLayout(new BorderLayout());
UILabel timeLabel = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Time") + ":");
timeLabel.setFont(FONT_UI);
hms = new HMSPane();
UIButton okButton = new UIButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_OK")) {
@ -223,7 +210,6 @@ public class UICalendarPanel extends JPanel {
return new Insets(0, 0, 0, 0);
}
};
okButton.setFont(FONT_UI);
okButton.setVerticalAlignment(SwingConstants.CENTER);
okButton.addActionListener(new ActionListener() {
@ -313,9 +299,6 @@ public class UICalendarPanel extends JPanel {
} else {
label.addMouseListener(dayBttListener);
}
if (!isCurrentMonth) {
FineUIStyle.setStyle(label, FineUIStyle.GRAY_BUTTON);
}
}
/**
* 更新日期
@ -366,11 +349,12 @@ public class UICalendarPanel extends JPanel {
isCurrentMonth = !isCurrentMonth;
}
setUIDayLabel(label, isCurrentMonth, setupCalendar, logSet);
label.setCurrentMonth(isCurrentMonth);
days.add(label);
//当前选择的日期
if (setupCalendar.get(Calendar.DAY_OF_MONTH) == selectedCalendar.get(Calendar.DAY_OF_MONTH) && isCurrentMonth) {
label.getModel().setSelected(true);
days.setSelectedIndex(i);
label.setSelected(true);
this.selectedDate = label.getDate();
this.calendar.setTime(this.selectedDate);
}
@ -409,6 +393,10 @@ public class UICalendarPanel extends JPanel {
if (isEnabled()) {
UIDayLabel com = (UIDayLabel) e.getComponent();
days.setSelectedIndex(com.getIndex());
com.setHovered(false);
com.setPressed(true);
com.getParent().validate();
com.getParent().repaint();
}
}
@ -427,18 +415,25 @@ public class UICalendarPanel extends JPanel {
public void mouseEntered(MouseEvent e) {
if (isEnabled()) {
UIDayLabel com = (UIDayLabel) e.getComponent();
com.setHovered(true);
if (com.getIndex() == days.selectedIndex) {
return;
}
days.setFloatIndex(com.getIndex());
com.getParent().validate();
com.getParent().repaint();
}
}
public void mouseExited(MouseEvent e) {
if (isEnabled()) {
UIDayLabel com = (UIDayLabel) e.getComponent();
com.setHovered(false);
com.setPressed(false);
days.setFloatIndex(-1);
days.repaint();
com.getParent().validate();
com.getParent().repaint();
}
}
};
@ -648,21 +643,8 @@ public class UICalendarPanel extends JPanel {
}
}
public static void main(String[] args) {
JFrame frame = new JFrame();
UICalendarPanel calendarPanel = new UICalendarPanel();
final UITextField field = new UITextField();
field.setPreferredSize(new Dimension(120, 25));
calendarPanel.addDateChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
Date selectedDate = (Date) e.getSource();
SimpleDateFormat f = new SimpleDateFormat("yyyy/MM/dd");
field.setText(f.format(selectedDate));
}
});
frame.getContentPane().setLayout(FRGUIPaneFactory.createCenterFlowLayout());
frame.getContentPane().add(field);
frame.getContentPane().add(calendarPanel);
frame.setVisible(true);
@Override
public String getUIClassID() {
return UI_CLASS_ID;
}
}

61
designer-base/src/main/java/com/fr/design/gui/date/UIDayLabel.java

@ -1,14 +1,10 @@
package com.fr.design.gui.date;
import com.fine.theme.utils.FineUIStyle;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.utils.DesignUtils;
import java.awt.Insets;
import java.text.SimpleDateFormat;
import java.util.Date;
import static com.fine.theme.utils.FineUIScale.scale;
@ -18,11 +14,35 @@ import static com.fine.theme.utils.FineUIScale.scale;
* @since 12.0
* Created on 2024/09/22
*/
public class UIDayLabel extends UIButton {
private static final String UI_CLASS_ID = "DayLabelUI";
public class UIDayLabel extends UILabel {
private Date date = null;
private int index;
private boolean pressed = false;
private boolean hovered = false;
private boolean selected = false;
private boolean currentMonth = false;
private boolean smallLabel = false;
public boolean isHovered() {
return hovered;
}
public boolean isPressed() {
return pressed;
}
public boolean isSelected() {
return selected;
}
public boolean isCurrentMonth() {
return currentMonth;
}
public boolean isSmallLabel() {
return smallLabel;
}
/**
* 日期格式TODAY/TIP用
@ -38,12 +58,11 @@ public class UIDayLabel extends UIButton {
}
public UIDayLabel(Date date, boolean isSmallLabel) {
FineUIStyle.setStyle(this, FineUIStyle.ORIGINAL_BUTTON);
setOpaque(false);
setHorizontalAlignment(UILabel.CENTER);
setFont(DesignUtils.getDefaultGUIFont().applySize(scale(12)));
setMargin(new Insets(0, 0, 0, 0));
this.date = date;
if (isSmallLabel) {
this.smallLabel = isSmallLabel;
if (smallLabel) {
setText(dayFormat.format(date));
} else {
setText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Today") + ":" + dateFormat.format(new Date()));
@ -55,6 +74,23 @@ public class UIDayLabel extends UIButton {
return date;
}
public void setHovered(boolean hovered) {
this.hovered = hovered;
}
public void setPressed(boolean pressed) {
this.pressed = pressed;
}
public void setSelected(boolean selected) {
this.selected = selected;
}
public void setCurrentMonth(boolean currentMonth) {
this.currentMonth = currentMonth;
}
public void setDate(Date date) {
this.date = date;
}
@ -67,9 +103,4 @@ public class UIDayLabel extends UIButton {
return this.index;
}
@Override
public String getUIClassID() {
return UI_CLASS_ID;
}
}

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

@ -7,7 +7,7 @@ ColorChooserUI=com.formdev.flatlaf.ui.FlatColorChooserUI
ComboBoxUI=com.fine.theme.light.ui.FineComboBoxUI
DesktopIconUI=com.formdev.flatlaf.ui.FlatDesktopIconUI
DesktopPaneUI=com.formdev.flatlaf.ui.FlatDesktopPaneUI
DayLabelUI=com.fine.theme.light.ui.FineDayLabelUI
CalendarPaneUI=com.fine.theme.light.ui.FineCalendarPaneUI
EditorPaneUI=com.formdev.flatlaf.ui.FlatEditorPaneUI
FileChooserUI=com.formdev.flatlaf.ui.FlatFileChooserUI
FormattedTextFieldUI=com.formdev.flatlaf.ui.FlatFormattedTextFieldUI

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

@ -411,7 +411,12 @@ Label.warningColor = #F1393C
Label.secondaryColor = #0A1C38A8
# ---- Calendar ----
Calendar.background = $fill.normal
Calendar.day.selectedBackground = #2576EF
Calendar.day.hoverBackground = #E6E9EF
Calendar.day.pressedBackground = #DADEE7
Calendar.dayOtherMonth.foreground = fade(@foreground, 29%)
Calendar.day.arc = 6
#---- HelpButton ----

32
designer-base/src/test/java/com/fr/design/gui/storybook/components/UICalendarPaneStoryBoard.java

@ -0,0 +1,32 @@
package com.fr.design.gui.storybook.components;
import com.fine.theme.light.ui.FineRoundBorder;
import com.fr.design.gui.date.UICalendarPanel;
import com.fr.design.gui.date.UIDatePicker;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.storybook.StoryBoard;
import javax.swing.*;
import java.awt.*;
import java.util.Date;
import static com.fine.swing.ui.layout.Layouts.*;
public class UICalendarPaneStoryBoard extends StoryBoard {
public UICalendarPaneStoryBoard() {
super("日期控件");
UICalendarPanel calendarPanel = new UICalendarPanel(true);
calendarPanel.setSelectedDate(new Date());
add(
cell(new UILabel("日期下拉框")).with(this::h3),
row(cell(new UIDatePicker(2)).with(this::setFixSize), flex()),
cell(new UILabel("日期")).with(this::h3),
row(cell(calendarPanel), flex())
);
}
private void setFixSize(JComponent component) {
component.setPreferredSize(new Dimension(240, component.getHeight()));
component.setBorder(new FineRoundBorder());
}
}
Loading…
Cancel
Save