Browse Source

Pull request #13384: REPORT-107973 主页及组件视觉样式翻新

Merge in DESIGN/design from ~LEO.QIN/design:newui to newui

* commit 'db8656de54f873fd08ebc512809d926c3f75ad4b':
  REPORT-107973 添加注释、格式化
  REPORT-107973 主页及组件视觉样式翻新 【问题原因】rt 【改动思路】为新增key添加默认值
  REPORT-107973 主页及组件视觉样式翻新 【问题原因】rt 【改动思路】翻新渐变色滑块
  REPORT-107973 弹窗样式翻新
  REPORT-107973 主页及组件视觉样式翻新 【问题原因】rt 【改动思路】翻新带标签带滑块
newui
Leo.Qin-覃宇攀 6 months ago
parent
commit
bc251bca0a
  1. 294
      designer-base/src/main/java/com/fine/theme/light/ui/FineGradientBarUI.java
  2. 7
      designer-base/src/main/java/com/fine/theme/light/ui/FineInputUI.java
  3. 2
      designer-base/src/main/java/com/fine/theme/light/ui/FineLightIconSet.java
  4. 19
      designer-base/src/main/java/com/fine/theme/light/ui/FinePopupMenuBorder.java
  5. 57
      designer-base/src/main/java/com/fine/theme/light/ui/FinePopupMenuUI.java
  6. 344
      designer-base/src/main/java/com/fine/theme/light/ui/FineSliderUI.java
  7. 16
      designer-base/src/main/java/com/fine/theme/light/ui/FineTooltipUI.java
  8. 10
      designer-base/src/main/java/com/fine/theme/light/ui/laf/FineLaf.java
  9. 17
      designer-base/src/main/java/com/fine/theme/utils/FineUIUtils.java
  10. 24
      designer-base/src/main/java/com/fr/design/data/datapane/management/search/pane/FineSearchPane.java
  11. 13
      designer-base/src/main/java/com/fr/design/foldablepane/HeaderPane.java
  12. 8
      designer-base/src/main/java/com/fr/design/gui/frpane/UINumberDragPane.java
  13. 17
      designer-base/src/main/java/com/fr/design/gui/imenu/UIPopupEastAttrMenu.java
  14. 31
      designer-base/src/main/java/com/fr/design/gui/imenu/UIPopupMenu.java
  15. 25
      designer-base/src/main/java/com/fr/design/gui/ispinner/UISpinner.java
  16. 6
      designer-base/src/main/java/com/fr/design/gui/itextfield/UITextField.java
  17. 7
      designer-base/src/main/java/com/fr/design/mainframe/EastRegionContainerPane.java
  18. 7
      designer-base/src/main/java/com/fr/design/mainframe/JFormSliderPane.java
  19. 17
      designer-base/src/main/java/com/fr/design/mainframe/widget/accessibles/BaseAccessibleEditor.java
  20. 6
      designer-base/src/main/java/com/fr/design/style/background/gradient/FixedGradientBar.java
  21. 128
      designer-base/src/main/java/com/fr/design/style/background/gradient/GradientBar.java
  22. 43
      designer-base/src/main/java/com/fr/design/style/background/gradient/SelectColorPointBtn.java
  23. 7
      designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLaf.properties
  24. 31
      designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLightLaf.properties
  25. 25
      designer-base/src/test/java/com/fr/design/gui/storybook/components/SliderStoryBoard.java
  26. 1
      designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/GroupPane.java

294
designer-base/src/main/java/com/fine/theme/light/ui/FineGradientBarUI.java

@ -0,0 +1,294 @@
package com.fine.theme.light.ui;
import com.fine.theme.utils.FineUIUtils;
import com.fr.design.style.background.gradient.GradientBar;
import com.fr.design.style.background.gradient.SelectColorPointBtn;
import com.fr.stable.AssistUtils;
import com.fr.stable.os.OperatingSystem;
import javax.swing.JComponent;
import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.LinearGradientPaint;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionAdapter;
import java.awt.geom.Path2D;
import java.awt.geom.Point2D;
import java.util.Collections;
import java.util.List;
/**
* 渐变色滑块 UI类
*
* @author Leo.Qin
* @since 11.0
* Created on 2023/12/19
*/
public class FineGradientBarUI extends ComponentUI {
private int directionalShapeSize;
private int recHeight;
private int width;
private int height;
private int borderWidth;
private Color borderColor;
private Color thumbBorderColor;
private Color hoverThumbColor;
private Color pressedThumbColor;
private MouseMotionAdapter mouseMotionListener;
GradientBar gradientBar;
private List<SelectColorPointBtn> list;
private SelectColorPointBtn p1;
private SelectColorPointBtn p2;
private MouseListener mouseListener;
private double offset = 0.0001;
boolean[] hoverStatus;
/**
* 创建UI
*
* @param c 组件
* @return UI
*/
public static ComponentUI createUI(JComponent c) {
return new FineGradientBarUI();
}
@Override
public void installUI(JComponent c) {
super.installUI(c);
installDefaults(c);
gradientBar = (GradientBar) c;
list = gradientBar.getList();
p1 = gradientBar.getSelectColorPointBtnP1();
p2 = gradientBar.getSelectColorPointBtnP2();
hoverStatus = new boolean[list.size()];
mouseMotionListener = new TrackMotionListener();
mouseListener = new TrackMouseListener();
gradientBar.addMouseMotionListener(mouseMotionListener);
gradientBar.addMouseListener(mouseListener);
}
private void installDefaults(JComponent c) {
directionalShapeSize = FineUIUtils.getAndScaleInt("GradientBar.thumbWidth", 12);
recHeight = FineUIUtils.getAndScaleInt("GradientBar.recHeight", 30);
width = FineUIUtils.getAndScaleInt("GradientBar.recWidth", 160);
height = recHeight + directionalShapeSize;
borderWidth = FineUIUtils.getAndScaleInt("GradientBar.borderWidth", 1);
borderColor = UIManager.getColor("GradientBar.borderColor");
thumbBorderColor = UIManager.getColor("GradientBar.thumbBorderColor");
hoverThumbColor = UIManager.getColor("GradientBar.hoverThumbColor");
pressedThumbColor = UIManager.getColor("GradientBar.pressedThumbColor");
}
private class TrackMouseListener extends MouseAdapter {
@Override
public void mouseExited(MouseEvent e) {
for (int i = 0; i < list.size(); i++) {
SelectColorPointBtn selectColorPointBtn = list.get(i);
selectColorPointBtn.setHover(false);
hoverStatus[i] = false;
}
gradientBar.repaint();
}
@Override
public void mouseEntered(MouseEvent e) {
checkHoverStatus(e);
}
@Override
public void mousePressed(MouseEvent e) {
for (SelectColorPointBtn btn : list) {
boolean hover = isOverBtn(e, btn);
btn.setPressed(hover);
}
gradientBar.repaint();
}
@Override
public void mouseReleased(MouseEvent e) {
for (SelectColorPointBtn btn : list) {
btn.setPressed(false);
}
gradientBar.repaint();
}
}
private class TrackMotionListener extends MouseMotionAdapter {
int index;
@Override
public void mouseDragged(MouseEvent e) {
if (!gradientBar.isDraggable()) {
return;
}
index = getSelectedIndex(e, index);
int halfSize = directionalShapeSize / 2;
boolean x = e.getX() <= gradientBar.getWidth() - halfSize && e.getX() >= halfSize;
if (x) {
list.get(index).setX(e.getX());
list.get(index).setStartPosition((double) (e.getX() - halfSize) / (gradientBar.getWidth() - directionalShapeSize));
gradientBar.repaint();
}
}
private int getSelectedIndex(MouseEvent e, int index) {
int oldIndex = index;
for (int i = 0; i < list.size(); i++) {
if (list.get(i).contains(e.getX(), e.getY())) {
index = i;
break;
}
}
if (OperatingSystem.isLinux() && AssistUtils.equals(oldIndex, index)) {
if (Math.abs(p1.getX() - e.getX()) > Math.abs(p2.getX() - e.getX())) {
index = 1;
} else {
index = 0;
}
}
return index;
}
@Override
public void mouseMoved(MouseEvent e) {
checkHoverStatus(e);
}
}
private void checkHoverStatus(MouseEvent e) {
boolean repaint = false;
for (int i = 0; i < list.size(); i++) {
SelectColorPointBtn btn = list.get(i);
boolean hover = isOverBtn(e, btn);
if (hoverStatus[i] != hover) {
repaint = true;
hoverStatus[i] = hover;
btn.setHover(hover);
}
}
if (repaint) {
gradientBar.repaint();
}
}
private boolean isOverBtn(MouseEvent e, SelectColorPointBtn btn) {
return btn.contains(e.getX(), e.getY());
}
@Override
public void paint(Graphics g, JComponent c) {
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_NORMALIZE);
GradientBar component = (GradientBar) c;
List<SelectColorPointBtn> btnList = component.getList();
Collections.sort(btnList);
paintBorder(g2, component);
paintContent(g2, component);
paintButton(g2, btnList);
}
/**
* 实际绘制区域x范围directionalShapeSize / 2, width - directionalShapeSize)
*/
private void paintContent(Graphics2D g2d, GradientBar c) {
List<SelectColorPointBtn> btnList = c.getList();
int halfSize = directionalShapeSize / 2;
Point2D start = new Point2D.Float(halfSize, 0);
Point2D end = new Point2D.Float(c.getWidth() - halfSize, 0);
Collections.sort(btnList);
Color[] colors = new Color[btnList.size()];
for (int i = 0; i < btnList.size(); i++) {
colors[i] = btnList.get(i).getColorInner();
}
float[] dist = new float[btnList.size()];
for (int i = 0; i < btnList.size(); i++) {
if (btnList.get(i).getStartPosition() < 0) {
dist[i] = 0;
} else if (btnList.get(i).getStartPosition() > 1) {
dist[i] = 1;
} else {
dist[i] = (float) btnList.get(i).getStartPosition();
}
btnList.get(i).setX(dist[i] * (c.getWidth() - directionalShapeSize) + (double) directionalShapeSize / 2);
}
float dist1 = dist[btnList.size() - 1];
float dist2 = dist[btnList.size() - 2];
if (AssistUtils.equals(dist1, dist2)) {
dist[btnList.size() - 1] = (float) (dist2 + offset);
}
LinearGradientPaint paint = new LinearGradientPaint(start, end, dist, colors);
g2d.setPaint(paint);
g2d.fillRect(halfSize + borderWidth, borderWidth, c.getWidth() - directionalShapeSize - borderWidth * 2, recHeight - borderWidth * 2);
}
private void paintBorder(Graphics2D g2d, GradientBar c) {
int halfSize = directionalShapeSize / 2;
if (borderColor == null) {
return;
}
g2d.setColor(borderColor);
g2d.fillRect(halfSize, 0, c.getWidth() - directionalShapeSize, recHeight);
}
private void paintButton(Graphics2D g2d, List<SelectColorPointBtn> list) {
for (SelectColorPointBtn selectColorPointBtn : list) {
Path2D directionalThumbShape = FineSliderUI.createDirectionalThumbShape((float) selectColorPointBtn.getX() - (float) directionalShapeSize / 2, (float) selectColorPointBtn.getY(), directionalShapeSize, directionalShapeSize, 0);
if (selectColorPointBtn.isHover() && hoverThumbColor != null) {
g2d.setColor(hoverThumbColor);
g2d.fill(directionalThumbShape);
} else if (selectColorPointBtn.isPressed() && pressedThumbColor != null) {
g2d.setColor(pressedThumbColor);
g2d.fill(directionalThumbShape);
} else if (thumbBorderColor != null) {
g2d.setColor(thumbBorderColor);
g2d.fill(directionalThumbShape);
}
selectColorPointBtn.updatePath(directionalThumbShape);
Path2D innerThumbShape = FineSliderUI.createDirectionalThumbShape((float) selectColorPointBtn.getX() - (float) directionalShapeSize / 2 + borderWidth, (float) selectColorPointBtn.getY() + borderWidth, directionalShapeSize - borderWidth * 2, directionalShapeSize - borderWidth * 2, 0);
g2d.setColor(selectColorPointBtn.getColorInner());
g2d.fill(innerThumbShape);
}
}
@Override
public Dimension getPreferredSize(JComponent c) {
return new Dimension(width, height);
}
}

7
designer-base/src/main/java/com/fine/theme/light/ui/FineInputUI.java

@ -1,6 +1,6 @@
package com.fine.theme.light.ui;
import com.fine.theme.utils.FineUIScale;
import com.fine.theme.utils.FineUIUtils;
import com.formdev.flatlaf.ui.FlatButtonUI;
import com.formdev.flatlaf.ui.FlatPanelUI;
@ -12,7 +12,7 @@ import javax.swing.plaf.ComponentUI;
import java.beans.PropertyChangeEvent;
/**
* Input输入框 UI类
* Input输入框类组件 UI类
*
* @author Leo.Qin
* @since 11.0
@ -22,6 +22,7 @@ public class FineInputUI extends FlatPanelUI {
private static final String ENABLED = "enabled";
private static final String EDITABLE = "editable";
private final int defaultArc = 5;
public FineInputUI(boolean shared) {
super(shared);
@ -44,7 +45,7 @@ public class FineInputUI extends FlatPanelUI {
@Override
protected void installDefaults(JPanel p) {
super.installDefaults(p);
arc = FineUIScale.scale(UIManager.getInt("Input.arc"));
arc = FineUIUtils.getAndScaleInt("Input.arc", defaultArc);
}
@Override

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

@ -41,7 +41,7 @@ public class FineLightIconSet extends AbstractIconSet {
// 数据集相关Icon
new SvgIconSource("database", "com/fine/theme/icon/dataset/database.svg", true),
new SvgIconSource("preview", "com/fine/theme/icon/dataset/preview.svg", true),
new SvgIconSource("connection", "com/fine/theme/icon/dataset/connection.svg", true),
new SvgIconSource("connection", "com/fine/theme/icon/dataset/connection.svg"),
new SvgIconSource("class_table_data", "com/fine/theme/icon/dataset/class_table_data.svg", true),
new SvgIconSource("data_table", "com/fine/theme/icon/dataset/data_table.svg", true),
new SvgIconSource("multi", "com/fine/theme/icon/dataset/multi.svg", true),

19
designer-base/src/main/java/com/fine/theme/light/ui/FinePopupMenuBorder.java

@ -0,0 +1,19 @@
package com.fine.theme.light.ui;
import com.fine.theme.utils.FineUIUtils;
import com.formdev.flatlaf.ui.FlatPopupMenuBorder;
/**
* PopupMenu Border类
*
* @author Leo.Qin
* @since 11.0
* Created on 2023/12/25
*/
public class FinePopupMenuBorder extends FlatPopupMenuBorder {
@Override
public int getArc() {
return FineUIUtils.getAndScaleInt("PopupMenu.arc", 5);
}
}

57
designer-base/src/main/java/com/fine/theme/light/ui/FinePopupMenuUI.java

@ -0,0 +1,57 @@
package com.fine.theme.light.ui;
import com.fine.theme.utils.FineUIUtils;
import com.formdev.flatlaf.ui.FlatPopupMenuUI;
import javax.swing.JComponent;
import javax.swing.plaf.ComponentUI;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.RoundRectangle2D;
/**
* PopupMenu UI类
*
* @author Leo.Qin
* @since 11.0
* Created on 2023/12/25
*/
public class FinePopupMenuUI extends FlatPopupMenuUI {
private int arc;
private final int DEFAULT_ARC = 5;
/**
* 创建UI
*
* @param c 组件
* @return UI
*/
public static ComponentUI createUI(JComponent c) {
return new FinePopupMenuUI();
}
@Override
public void installDefaults() {
super.installDefaults();
arc = FineUIUtils.getAndScaleInt("PopupMenu.arc", DEFAULT_ARC);
}
@Override
public void paint(Graphics g, JComponent c) {
// 绘制圆角矩形作为弹窗背景
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
RoundRectangle2D roundRect = new RoundRectangle2D.Double(0, 0, c.getWidth(), c.getHeight(), arc, arc);
g2d.setColor(c.getBackground());
g2d.fill(roundRect);
// 绘制组件内容
super.paint(g, c);
}
@Override
public void update(Graphics g, JComponent c) {
paint(g, c);
}
}

344
designer-base/src/main/java/com/fine/theme/light/ui/FineSliderUI.java

@ -0,0 +1,344 @@
package com.fine.theme.light.ui;
import com.fine.theme.utils.FineUIUtils;
import com.formdev.flatlaf.ui.FlatSliderUI;
import com.formdev.flatlaf.ui.FlatUIUtils;
import com.formdev.flatlaf.util.HiDPIUtils;
import com.formdev.flatlaf.util.UIScale;
import com.fr.stable.AssistUtils;
import javax.swing.JComponent;
import javax.swing.JSlider;
import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Path2D;
import java.awt.geom.RoundRectangle2D;
import java.util.Dictionary;
import java.util.Enumeration;
/**
* 滑块slider UI类
*
* @author Leo.Qin
* @since 11.0
* Created on 2023/12/15
*/
public class FineSliderUI extends FlatSliderUI {
private final int DEFAULT_LABEL_HEIGHT = 13;
private Color defaultForeground;
private int defaultLabelHeight;
/**
* 创建UI
*/
public static ComponentUI createUI(JComponent c) {
return new FineSliderUI();
}
@Override
protected void installDefaults(JSlider slider) {
super.installDefaults(slider);
defaultForeground = UIManager.getColor("Slider.foreground");
defaultLabelHeight = FineUIUtils.getAndScaleInt("Slider.labelHeight", DEFAULT_LABEL_HEIGHT);
}
@Override
protected void calculateLabelRect() {
if (slider.getPaintLabels()) {
calLabelRectWhenPaint();
} else {
calLabelRectWhenNotPaint();
}
}
private void calLabelRectWhenPaint() {
labelRect.y = 0;
if (slider.getOrientation() == JSlider.HORIZONTAL) {
labelRect.x = tickRect.x - trackBuffer;
labelRect.width = tickRect.width + (trackBuffer * 2);
labelRect.height = getHeightOfTallestLabel();
} else {
if (isLeftToRight(slider)) {
labelRect.x = tickRect.x + tickRect.width;
labelRect.width = getWidthOfWidestLabel();
} else {
labelRect.width = getWidthOfWidestLabel();
labelRect.x = tickRect.x - labelRect.width;
}
labelRect.height = tickRect.height + (trackBuffer * 2);
}
}
private void calLabelRectWhenNotPaint() {
labelRect.y = 0;
if (slider.getOrientation() == JSlider.HORIZONTAL) {
labelRect.x = tickRect.x;
labelRect.width = tickRect.width;
labelRect.height = 0;
} else {
if (isLeftToRight(slider)) {
labelRect.x = tickRect.x + tickRect.width;
} else {
labelRect.x = tickRect.x;
}
labelRect.width = 0;
labelRect.height = tickRect.height;
}
}
@Override
protected void calculateTrackRect() {
if (slider.getOrientation() == JSlider.HORIZONTAL) {
calHorizontalTrackRect();
} else {
calVerticalTrackRect();
}
}
private void calVerticalTrackRect() {
int centerSpacing;
centerSpacing = thumbRect.width;
if (isLeftToRight(slider)) {
if (slider.getPaintTicks()) {
centerSpacing += getTickLength();
}
if (slider.getPaintLabels()) {
centerSpacing += getWidthOfWidestLabel();
}
} else {
if (slider.getPaintTicks()) {
centerSpacing -= getTickLength();
}
if (slider.getPaintLabels()) {
centerSpacing -= getWidthOfWidestLabel();
}
}
trackRect.x = contentRect.x + getWidthOfWidestLabel() + (contentRect.width - centerSpacing - 1) / 2;
trackRect.y = contentRect.y + trackBuffer;
trackRect.width = thumbRect.width;
trackRect.height = contentRect.height - (trackBuffer * 2);
}
private void calHorizontalTrackRect() {
int centerSpacing;
centerSpacing = thumbRect.height;
if (slider.getPaintTicks()) {
centerSpacing += getTickLength();
}
if (slider.getPaintLabels()) {
centerSpacing += getHeightOfTallestLabel();
}
trackRect.x = contentRect.x + trackBuffer;
trackRect.y = contentRect.y + getHeightOfTallestLabel() + (contentRect.height - centerSpacing - 1) / 2;
trackRect.width = contentRect.width - (trackBuffer * 2);
trackRect.height = thumbRect.height;
}
@Override
protected int getHeightOfTallestLabel() {
Dictionary dictionary = slider.getLabelTable();
int tallest = 0;
if (dictionary != null) {
Enumeration keys = dictionary.keys();
while (keys.hasMoreElements()) {
JComponent label = (JComponent) dictionary.get(keys.nextElement());
tallest = Math.max(label.getPreferredSize().height, tallest);
}
}
return Math.min(tallest, defaultLabelHeight);
}
@Override
protected int getWidthOfWidestLabel() {
Dictionary dictionary = slider.getLabelTable();
int widest = 0;
if (dictionary != null) {
Enumeration keys = dictionary.keys();
while (keys.hasMoreElements()) {
JComponent label = (JComponent) dictionary.get(keys.nextElement());
widest = Math.max(label.getPreferredSize().width, widest);
}
}
return Math.min(widest, defaultLabelHeight);
}
/**
* Convenience function for determining ComponentOrientation. Helps us
* avoid having Munge directives throughout the code.
*/
static boolean isLeftToRight(Component c) {
return c.getComponentOrientation().isLeftToRight();
}
@Override
public void paintThumb(Graphics g) {
Color thumbColor = getThumbColor();
Color color = stateColor(slider, thumbHover, thumbPressed, thumbColor, disabledThumbColor, null, hoverThumbColor, pressedThumbColor);
color = FlatUIUtils.deriveColor(color, thumbColor);
Color foreground = slider.getForeground();
Color borderColor = (thumbBorderColor != null && foreground == defaultForeground) ? stateColor(slider, false, false, thumbBorderColor, disabledThumbBorderColor, focusedThumbBorderColor, null, null) : null;
Color focusedColor = FlatUIUtils.deriveColor(this.focusedColor, (foreground != defaultForeground) ? foreground : focusBaseColor);
paintThumb(g, slider, thumbRect, isRoundThumb(), color, borderColor, focusedColor, thumbBorderWidth, focusWidth);
}
/**
* Paints the thumb.
*
* @param g the graphics context
* @param slider the slider
* @param thumbRect the thumb rectangle
* @param roundThumb whether the thumb should be round
* @param thumbColor the thumb color
* @param thumbBorderColor the thumb border color
* @param focusedColor the focused color
* @param thumbBorderWidth the thumb border width
* @param focusWidth the focus width
*/
public static void paintThumb(Graphics g, JSlider slider, Rectangle thumbRect, boolean roundThumb, Color thumbColor, Color thumbBorderColor, Color focusedColor, float thumbBorderWidth, int focusWidth) {
double systemScaleFactor = UIScale.getSystemScaleFactor((Graphics2D) g);
int scaleFactor2 = 2;
if (systemScaleFactor != 1 && systemScaleFactor != scaleFactor2) {
// paint at scale 1x to avoid clipping on right and bottom edges at 125%, 150% or 175%
HiDPIUtils.paintAtScale1x((Graphics2D) g, thumbRect.x, thumbRect.y, thumbRect.width, thumbRect.height, (g2d, x2, y2, width2, height2, scaleFactor) -> {
paintThumbImpl(g, slider, x2, y2, width2, height2, roundThumb, thumbColor, thumbBorderColor, focusedColor, (float) (thumbBorderWidth * scaleFactor), (float) (focusWidth * scaleFactor));
});
return;
}
paintThumbImpl(g, slider, thumbRect.x, thumbRect.y, thumbRect.width, thumbRect.height, roundThumb, thumbColor, thumbBorderColor, focusedColor, thumbBorderWidth, focusWidth);
}
private static void paintThumbImpl(Graphics g, JSlider slider, int x, int y, int width, int height, boolean roundThumb, Color thumbColor, Color thumbBorderColor, Color focusedColor, float thumbBorderWidth, float focusWidth) {
int fw = Math.round(UIScale.scale(focusWidth));
int tx = x + fw;
int ty = y + fw;
int tw = width - fw - fw;
int th = height - fw - fw;
boolean focused = FlatUIUtils.isPermanentFocusOwner(slider);
if (roundThumb) {
paintRoundThumb(g, x, y, width, height, thumbColor, thumbBorderColor, focusedColor, thumbBorderWidth, focused, tx, ty, tw, th);
} else {
paintDirectionalThumb(g, slider, x, y, width, height, thumbColor, thumbBorderColor, focusedColor, thumbBorderWidth, tw, th, focused, fw);
}
}
private static void paintDirectionalThumb(Graphics g, JSlider slider, int x, int y, int width, int height, Color thumbColor, Color thumbBorderColor, Color focusedColor, float thumbBorderWidth, int tw, int th, boolean focused, int fw) {
Graphics2D g2 = (Graphics2D) g.create();
try {
g2.translate(x, y);
if (slider.getOrientation() == JSlider.VERTICAL) {
if (slider.getComponentOrientation().isLeftToRight()) {
g2.translate(0, height);
g2.rotate(Math.toRadians(270));
} else {
g2.translate(width, 0);
g2.rotate(Math.toRadians(90));
}
// rotate thumb width/height
int temp = tw;
tw = th;
th = temp;
}
paintDirectionalThumbImpl(thumbColor, thumbBorderColor, focusedColor, thumbBorderWidth, tw, th, focused, fw, g2);
} finally {
g2.dispose();
}
}
private static void paintDirectionalThumbImpl(Color thumbColor, Color thumbBorderColor, Color focusedColor, float thumbBorderWidth, int tw, int th, boolean focused, int fw, Graphics2D g2) {
// paint thumb focus border
if (focused) {
g2.setColor(focusedColor);
g2.fill(createDirectionalThumbShape(0, 0, tw + fw + fw, th + fw + fw, fw));
}
if (thumbBorderColor != null) {
// paint thumb border
g2.setColor(thumbBorderColor);
g2.fill(createDirectionalThumbShape(fw, fw, tw, th, 0));
// paint thumb background
float lw = UIScale.scale(thumbBorderWidth);
g2.setColor(thumbColor);
g2.fill(createDirectionalThumbShape(fw + lw, fw + lw, tw - lw - lw, th - lw - lw, 0));
} else {
// paint thumb background
g2.setColor(thumbColor);
g2.fill(createDirectionalThumbShape(fw, fw, tw, th, 0));
}
}
private static void paintRoundThumb(Graphics g, int x, int y, int width, int height, Color thumbColor, Color thumbBorderColor, Color focusedColor, float thumbBorderWidth, boolean focused, int tx, int ty, int tw, int th) {
// paint thumb focus border
if (focused) {
g.setColor(focusedColor);
((Graphics2D) g).fill(createRoundThumbShape(x, y, width, height));
}
if (thumbBorderColor != null) {
// paint thumb border
g.setColor(thumbBorderColor);
((Graphics2D) g).fill(createRoundThumbShape(tx, ty, tw, th));
// paint thumb background
float lw = UIScale.scale(thumbBorderWidth);
g.setColor(thumbColor);
((Graphics2D) g).fill(createRoundThumbShape(tx + lw, ty + lw, tw - lw - lw, th - lw - lw));
} else {
// paint thumb background
g.setColor(thumbColor);
((Graphics2D) g).fill(createRoundThumbShape(tx, ty, tw, th));
}
}
/**
* 无标签下创建圆形Thumb形状
*/
public static Shape createRoundThumbShape(float x, float y, float w, float h) {
if (AssistUtils.equals(w, h)) {
return new Ellipse2D.Float(x, y, w, h);
} else {
float arc = Math.min(w, h);
return new RoundRectangle2D.Float(x, y, w, h, arc, arc);
}
}
/**
* 有标签下创建Thumb形状
*/
public static Path2D createDirectionalThumbShape(float x, float y, float w, float h, float arc) {
float wh = w / 2;
Path2D path = new Path2D.Float(Path2D.WIND_NON_ZERO, 9);
path.moveTo(x + wh, y); // 移到反转后的位置
path.lineTo(x, y + wh); // 线到反转后的位置
path.lineTo(x, y + h - arc); // 线到反转后的位置
path.quadTo(x, y + h, x + arc, y + h); // 贝塞尔曲线到反转后的位置
path.lineTo(x + (w - arc), y + h); // 线到反转后的位置
path.quadTo(x + w, y + h, x + w, y + h - arc); // 贝塞尔曲线到反转后的位置
path.lineTo(x + w, y + wh); // 线到反转后的位置
path.closePath(); // 关闭路径
return path;
}
}

16
designer-base/src/main/java/com/fine/theme/light/ui/FineTooltipUI.java

@ -1,6 +1,7 @@
package com.fine.theme.light.ui;
import com.fine.theme.utils.FineUIScale;
import com.fine.theme.utils.FineUIUtils;
import com.formdev.flatlaf.ui.FlatToolTipUI;
import com.formdev.flatlaf.ui.FlatUIUtils;
import com.fr.base.BaseUtils;
@ -9,13 +10,13 @@ import com.fr.stable.Constants;
import javax.swing.JComponent;
import javax.swing.JToolTip;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.RenderingHints;
import java.util.List;
/**
@ -26,6 +27,8 @@ import java.util.List;
* Created on 2023/12/8
*/
public class FineTooltipUI extends FlatToolTipUI {
private final int defaultMaxWidth = 392;
private final int defaultArc = 5;
private int maxWidth;
private int arc;
private List<String> lines;
@ -39,9 +42,11 @@ public class FineTooltipUI extends FlatToolTipUI {
@Override
public void paint(Graphics g, JComponent c) {
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setColor(c.getBackground());
g.fillRoundRect(0, 0, c.getWidth(), c.getHeight(), arc, arc);
g2d.setColor(c.getBackground());
g2d.fillRoundRect(0, 0, c.getWidth(), c.getHeight(), arc, arc);
String text = ((JToolTip) c).getTipText();
if (text == null || text.isEmpty()) {
@ -49,7 +54,6 @@ public class FineTooltipUI extends FlatToolTipUI {
}
Insets insets = c.getInsets();
Graphics2D g2d = (Graphics2D) g;
FontMetrics fm = g2d.getFontMetrics();
int x = insets.left;
@ -69,8 +73,8 @@ public class FineTooltipUI extends FlatToolTipUI {
protected void installDefaults(JComponent c) {
super.installDefaults(c);
c.setOpaque(false);
arc = FineUIScale.scale(UIManager.getInt("ToolTip.arc"));
maxWidth = FineUIScale.scale(UIManager.getInt("ToolTip.maxWidth"));
arc = FineUIScale.scale(FineUIUtils.getAndScaleInt("ToolTip.arc", defaultArc));
maxWidth = FineUIUtils.getAndScaleInt("ToolTip.maxWidth", defaultMaxWidth);
}

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

@ -2,6 +2,8 @@ package com.fine.theme.light.ui.laf;
import com.formdev.flatlaf.FlatLaf;
import javax.swing.PopupFactory;
/**
* Fine designer new look and feel
* FineLaf.properties 定义公共属性如UI等
@ -25,4 +27,12 @@ public abstract class FineLaf extends FlatLaf {
public String getDescription() {
return "Fine New Look and Feel";
}
@Override
public void initialize() {
super.initialize();
// flat默认使用系统弹窗,3.3 版本之前无法实现圆角弹窗。
// popup弹窗不使用flat提供的工具,使用swing原生自带的
PopupFactory.setSharedInstance(new PopupFactory());
}
}

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

@ -6,12 +6,12 @@ import com.fr.value.AtomicClearableLazyValue;
import javax.swing.UIManager;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Composite;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Insets;
import java.awt.geom.RoundRectangle2D;
import java.lang.reflect.Field;
@ -142,6 +142,19 @@ public class FineUIUtils {
return (margin != null) ? margin : defaultInsets;
}
/**
* 通过key获取UI的边距如果没有则使用后备边距并根据dpi进行缩放
*
* @param key 边距key
* @param defaultInsets 后备边距
* @return 根据dpi缩放后的边距
*/
public static Insets getAndScaleUIInsets(String key, Insets defaultInsets) {
Insets margin = UIManager.getInsets(key);
Insets insets = (margin != null) ? margin : defaultInsets;
return FineUIScale.scale(insets);
}
/**
* 绘制混合图像含圆角背景色设置
*

24
designer-base/src/main/java/com/fr/design/data/datapane/management/search/pane/FineSearchPane.java

@ -2,7 +2,7 @@ package com.fr.design.data.datapane.management.search.pane;
import com.fine.theme.icon.LazyIcon;
import com.fine.theme.light.ui.FineInputUI;
import com.fine.theme.utils.FineUIScale;
import com.fine.theme.utils.FineUIUtils;
import com.fr.design.event.HoverAware;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ilable.UILabel;
@ -10,7 +10,6 @@ import com.fr.design.gui.itextfield.UITextField;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.event.DocumentListener;
import java.awt.BorderLayout;
import java.awt.Insets;
@ -28,14 +27,23 @@ import java.awt.event.MouseEvent;
*/
public class FineSearchPane extends JPanel implements HoverAware {
private final Insets defaultLabelInsets = new Insets(3, 6, 3, 4);
private final Insets defaultButtonInsets = new Insets(4, 4, 4, 4);
private UITextField searchTextField;
private UIButton clearButton;
private static final String UI_CLASS_ID = "InputUI";
@Override
public String getUIClassID() {
return UI_CLASS_ID;
}
private boolean hover;
public FineSearchPane() {
this.setLayout(new BorderLayout());
this.setUI(new FineInputUI(false));
initComponents();
}
@ -43,9 +51,8 @@ public class FineSearchPane extends JPanel implements HoverAware {
private void initComponents() {
// 左侧搜索图标
UILabel searchLabel = new UILabel(new LazyIcon("search"));
Insets labelInsets = UIManager.getInsets("SearchPanel.labelBorderInsets");
Insets scaledInsets = FineUIScale.scale(labelInsets);
searchLabel.setBorder(BorderFactory.createEmptyBorder(scaledInsets.top, scaledInsets.left, scaledInsets.bottom, scaledInsets.right));
Insets labelInsets = FineUIUtils.getAndScaleUIInsets("SearchPanel.labelBorderInsets", defaultLabelInsets);
searchLabel.setBorder(BorderFactory.createEmptyBorder(labelInsets.top, labelInsets.left, labelInsets.bottom, labelInsets.right));
// 中间输入框
searchTextField = new UITextField();
@ -68,9 +75,8 @@ public class FineSearchPane extends JPanel implements HoverAware {
// 右侧返回图标
clearButton = new UIButton(new LazyIcon("clear"));
clearButton.setUI(new FineInputUI.FineInputButtonUI(false));
Insets buttonInsets = UIManager.getInsets("SearchPanel.buttonBorderInsets");
Insets buttonScaledInsets = FineUIScale.scale(buttonInsets);
clearButton.setBorder(BorderFactory.createEmptyBorder(buttonScaledInsets.top, buttonScaledInsets.left, buttonScaledInsets.bottom, buttonScaledInsets.right));
Insets buttonInsets = FineUIUtils.getAndScaleUIInsets("SearchPanel.buttonBorderInsets", defaultButtonInsets);
clearButton.setBorder(BorderFactory.createEmptyBorder(buttonInsets.top, buttonInsets.left, buttonInsets.bottom, buttonInsets.right));
this.add(searchLabel, BorderLayout.WEST);
this.add(searchTextField, BorderLayout.CENTER);

13
designer-base/src/main/java/com/fr/design/foldablepane/HeaderPane.java

@ -2,6 +2,7 @@ package com.fr.design.foldablepane;
import com.fine.theme.icon.LazyIcon;
import com.fine.theme.utils.FineUIScale;
import com.fine.theme.utils.FineUIUtils;
import com.fr.base.GraphHelper;
import javax.swing.BorderFactory;
@ -24,6 +25,9 @@ import java.awt.Insets;
*/
public class HeaderPane extends JPanel {
private static final long serialVersionUID = 1L;
private final Insets defaultInsets = new Insets(0, 6, 0, 6);
private final int defaultWidth = 248;
private final int defaultHeight = 24;
private int headWidth;
private int headHeight;
private Color bgColor;
@ -88,12 +92,13 @@ public class HeaderPane extends JPanel {
this.isShow = true;
triangleDown = new LazyIcon("triangle_down");
triangleRight = new LazyIcon("triangle_right");
this.setPreferredSize(FineUIScale.scale(new Dimension(UIManager.getInt("HeaderPane.width"), UIManager.getInt("HeaderPane.height"))));
Insets insets = UIManager.getInsets("ExpandablePane.HeaderPane.borderInsets");
Insets scaledInsets = FineUIScale.scale(insets);
int width = FineUIUtils.getAndScaleInt("HeaderPane.width", defaultWidth);
int height = FineUIUtils.getAndScaleInt("HeaderPane.height", defaultHeight);
this.setPreferredSize(new Dimension(width, height));
Insets insets = FineUIUtils.getAndScaleUIInsets("ExpandablePane.HeaderPane.borderInsets", defaultInsets);
this.setForeground(UIManager.getColor("ExpandablePane.HeaderPane.foreground"));
this.setFont(getFont().deriveFont(Font.BOLD));
this.setBorder(BorderFactory.createEmptyBorder(scaledInsets.top, scaledInsets.left, scaledInsets.bottom, scaledInsets.right));
this.setBorder(BorderFactory.createEmptyBorder(insets.top, insets.left, insets.bottom, insets.right));
}
public HeaderPane(Color bgColor, String title, int headHeight) {

8
designer-base/src/main/java/com/fr/design/gui/frpane/UINumberDragPane.java

@ -3,8 +3,8 @@ package com.fr.design.gui.frpane;
import com.fr.design.beans.BasicBeanPane;
import com.fr.design.event.GlobalNameListener;
import com.fr.design.event.GlobalNameObserver;
import com.fr.design.gui.islider.UISlider;
import com.fr.design.gui.ispinner.UISpinner;
import com.fr.design.gui.style.NumberDragBar;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
@ -14,7 +14,7 @@ import java.awt.Dimension;
public class UINumberDragPane extends BasicBeanPane<Double> implements GlobalNameObserver {
private static final long serialVersionUID = -8681716725163358249L;
private NumberDragBar dragBar;
private UISlider dragBar;
private UISpinner spinner;
private boolean isEditing = false;
private String numberDargPaneName = "";
@ -33,7 +33,9 @@ public class UINumberDragPane extends BasicBeanPane<Double> implements GlobalNam
}
public UINumberDragPane(double minValue, double maxValue, double dierta) {
dragBar = new NumberDragBar((int) minValue, (int) maxValue);
dragBar = new UISlider((int) minValue, (int) maxValue);
dragBar.setPaintLabels(true);
dragBar.setMajorTickSpacing((int) maxValue);
spinner = createUISpinner(minValue, maxValue, dierta);
spinner.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_StyleAlignment_Text_Rotation"));
this.setLayout(new BorderLayout(4, 0));

17
designer-base/src/main/java/com/fr/design/gui/imenu/UIPopupEastAttrMenu.java

@ -1,28 +1,11 @@
package com.fr.design.gui.imenu;
import java.awt.Graphics;
import java.awt.Insets;
import javax.swing.JPopupMenu;
import com.fr.design.constants.UIConstants;
public class UIPopupEastAttrMenu extends JPopupMenu {
public UIPopupEastAttrMenu() {
super();
setBackground(UIConstants.NORMAL_BACKGROUND);
}
@Override
protected void paintBorder(Graphics g) {
g.setColor(UIConstants.POP_DIALOG_BORDER);
g.drawRect(0, 0, getWidth() - 1, getHeight() - 1);
}
@Override
public Insets getInsets() {
return new Insets(0, 1, 1, 1);
}
}

31
designer-base/src/main/java/com/fr/design/gui/imenu/UIPopupMenu.java

@ -1,11 +1,6 @@
package com.fr.design.gui.imenu;
import com.fr.design.constants.UIConstants;
import javax.swing.JPopupMenu;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
public class UIPopupMenu extends JPopupMenu{
private static final float DEFAULT_REC = 8f;
@ -15,32 +10,6 @@ public class UIPopupMenu extends JPopupMenu{
public static UIPopupMenu EMPTY = new UIPopupMenu();
public UIPopupMenu() {
super();
// setBackground(UIConstants.NORMAL_BACKGROUND);
}
@Override
protected void paintComponent(Graphics g) {
// Graphics2D g2d = (Graphics2D) g;
// Shape shape = new RoundRectangle2D.Double(0, 0, getWidth(), getHeight(), rec, rec);
// g2d.setClip(shape);
// g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
super.paintComponent(g);
}
@Override
protected void paintBorder(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(UIConstants.UIPOPUPMENU_LINE_COLOR);
// g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.drawRoundRect(0, 0, getWidth() - 1, getHeight() - 1, (int) rec, (int) rec);
}
@Override
public Insets getInsets() {
if(onlyText) {
return super.getInsets();
}
return new Insets(10, 2, 10, 10);
}
public void setOnlyText(boolean onlyText) {

25
designer-base/src/main/java/com/fr/design/gui/ispinner/UISpinner.java

@ -3,6 +3,7 @@ package com.fr.design.gui.ispinner;
import com.fine.theme.icon.LazyIcon;
import com.fine.theme.light.ui.FineInputUI;
import com.fine.theme.utils.FineUIScale;
import com.fine.theme.utils.FineUIUtils;
import com.fr.design.event.GlobalNameListener;
import com.fr.design.event.GlobalNameObserver;
import com.fr.design.event.HoverAware;
@ -44,6 +45,8 @@ import java.awt.event.MouseWheelListener;
*/
public class UISpinner extends JPanel implements UIObserver, GlobalNameObserver, HoverAware {
private final Insets defaultInsets = new Insets(0, 6, 0, 6);
private final int defaultButtonSize = 24;
protected double value;
private static final int DEFAULT_NUMBERFIELD_COLUMNS = 2;
private UINumberField textField;
@ -64,6 +67,13 @@ public class UISpinner extends JPanel implements UIObserver, GlobalNameObserver,
private boolean hover;
private static final String UI_CLASS_ID = "InputUI";
@Override
public String getUIClassID() {
return UI_CLASS_ID;
}
public UISpinner() {
}
@ -89,7 +99,6 @@ public class UISpinner extends JPanel implements UIObserver, GlobalNameObserver,
this.dierta = dierta;
initComponents();
iniListener();
setUI(FineInputUI.createUI(this));
}
private void iniListener() {
@ -272,6 +281,10 @@ public class UISpinner extends JPanel implements UIObserver, GlobalNameObserver,
textField = initNumberField();
textField.setMaxValue(maxValue);
textField.setMinValue(minValue);
Insets insets = FineUIUtils.getAndScaleUIInsets("InputTextField.borderInsets", defaultInsets);
textField.setBorder(BorderFactory.createEmptyBorder(insets.top, insets.left, insets.bottom, insets.right));
textField.setOpaque(false);
setValue(value);
preButton = createArrowButton(new LazyIcon("up_arrow_12"));
nextButton = createArrowButton(new LazyIcon("down_arrow_12"));
@ -283,9 +296,9 @@ public class UISpinner extends JPanel implements UIObserver, GlobalNameObserver,
arrowPane.add(nextButton);
arrowPane.setOpaque(false);
int buttonWidth = UIManager.getInt("InputButton.width");
int buttonHeight = UIManager.getInt("InputButton.height");
arrowPane.setPreferredSize(FineUIScale.scale(new Dimension(buttonWidth, buttonHeight)));
int buttonWidth = FineUIUtils.getAndScaleInt("InputButton.width", defaultButtonSize);
int buttonHeight = FineUIUtils.getAndScaleInt("InputButton.height", defaultButtonSize);
arrowPane.setPreferredSize(new Dimension(buttonWidth, buttonHeight));
add(arrowPane, BorderLayout.EAST);
componentInitListeners();
}
@ -370,10 +383,6 @@ public class UISpinner extends JPanel implements UIObserver, GlobalNameObserver,
return false;
}
};
Insets insets = UIManager.getInsets("InputTextField.borderInsets");
Insets scaledInsets = FineUIScale.scale(insets);
numberField.setBorder(BorderFactory.createEmptyBorder(scaledInsets.top, scaledInsets.left, scaledInsets.bottom, scaledInsets.right));
numberField.setOpaque(false);
return numberField;
}

6
designer-base/src/main/java/com/fr/design/gui/itextfield/UITextField.java

@ -1,6 +1,6 @@
package com.fr.design.gui.itextfield;
import com.fine.theme.utils.FineUIScale;
import com.fine.theme.utils.FineUIUtils;
import com.fr.common.inputevent.InputEventBaseOnOS;
import com.fr.design.event.GlobalNameListener;
import com.fr.design.event.GlobalNameObserver;
@ -14,7 +14,6 @@ import com.fr.stable.StringUtils;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.Document;
@ -33,6 +32,7 @@ import java.awt.event.MouseEvent;
* @since xxx
*/
public class UITextField extends JTextField implements UIObserver, GlobalNameObserver, HoverAware {
private final int defaultHeight = 24;
private boolean isBorderPainted = true;
private boolean isRoundBorder = true;
private int rectDirection = Constants.NULL;
@ -243,6 +243,6 @@ public class UITextField extends JTextField implements UIObserver, GlobalNameObs
@Override
public Dimension getPreferredSize() {
return new Dimension(super.getPreferredSize().width, FineUIScale.scale(UIManager.getInt("Input.height")));
return new Dimension(super.getPreferredSize().width, FineUIUtils.getAndScaleInt("Input.height", defaultHeight));
}
}

7
designer-base/src/main/java/com/fr/design/mainframe/EastRegionContainerPane.java

@ -3,6 +3,7 @@ package com.fr.design.mainframe;
import com.fine.theme.icon.LazyIcon;
import com.fine.theme.light.ui.RectangleButtonUI;
import com.fine.theme.utils.FineUIScale;
import com.fine.theme.utils.FineUIUtils;
import com.formdev.flatlaf.FlatDarkLaf;
import com.formdev.flatlaf.ui.FlatLineBorder;
import com.fr.base.FRContext;
@ -1171,6 +1172,7 @@ public class EastRegionContainerPane extends UIEastResizableContainer {
// 弹出属性面板的工具条
private class PopupToolPane extends JPanel {
private final UIButton popupButton;
private final Insets defaultInsets = new Insets(0, 10, 0, 10);
private String title;
private PropertyItem propertyItem;
private String buttonType;
@ -1263,9 +1265,8 @@ public class EastRegionContainerPane extends UIEastResizableContainer {
popupButton = createPopupButton(buttonType);
contentPane.add(popupButton, BorderLayout.EAST);
Insets insets = UIManager.getInsets("PopupToolPane.borderInsets");
Insets scaledInsets = FineUIScale.scale(insets);
contentPane.setBorder(new EmptyBorder(scaledInsets.top, scaledInsets.left, scaledInsets.bottom, scaledInsets.right));
Insets insets = FineUIUtils.getAndScaleUIInsets("PopupToolPane.borderInsets", defaultInsets);
contentPane.setBorder(new EmptyBorder(insets.top, insets.left, insets.bottom, insets.right));
setLayout(new BorderLayout());
add(contentPane, BorderLayout.CENTER);

7
designer-base/src/main/java/com/fr/design/mainframe/JFormSliderPane.java

@ -1,6 +1,7 @@
package com.fr.design.mainframe;
import com.fine.theme.icon.LazyIcon;
import com.fine.theme.utils.FineUIScale;
import com.formdev.flatlaf.FlatDarculaLaf;
import com.fr.base.BaseUtils;
import com.fr.design.gui.ibutton.UIButton;
@ -48,8 +49,6 @@ public class JFormSliderPane extends JPanel {
private static final int HUNDRED = 100;
private static final int TWO_HUNDRED = 200;
private static final int FOUR_HUNDRED = 400;
private static final int SHOWVALBUTTON_WIDTH = 40;
private static final int SHOWVALBUTTON_HEIGHTH = 20;
private static final String SUFFIX = "%";
private static final int TOOLTIP_Y = 30;
private static final Color BACK_COLOR = new Color(245, 245, 247);
@ -93,7 +92,6 @@ public class JFormSliderPane extends JPanel {
};
slider.setValue(HALF_HUNDRED);
slider.addChangeListener(listener);
slider.setPreferredSize(new Dimension(220, 20));
//去掉虚线框
slider.setFocusable(false);
slider.setToolTipText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Scale_Slider"));
@ -124,7 +122,8 @@ public class JFormSliderPane extends JPanel {
private void initShowValField() {
showValField = new UINumberField();
showValField.setValue(showValue);
showValField.setPreferredSize(new Dimension(SHOWVALBUTTON_WIDTH, SHOWVALBUTTON_HEIGHTH));
Dimension dimension = new Dimension(UIManager.getInt("FormSliderPane.showValueWidth"), UIManager.getInt("FormSliderPane.showValueHeight"));
showValField.setPreferredSize(FineUIScale.scale(dimension));
showValField.addKeyListener(new KeyListener() {
@Override
public void keyTyped(KeyEvent e) {

17
designer-base/src/main/java/com/fr/design/mainframe/widget/accessibles/BaseAccessibleEditor.java

@ -3,6 +3,7 @@ package com.fr.design.mainframe.widget.accessibles;
import com.fine.theme.icon.LazyIcon;
import com.fine.theme.light.ui.FineInputUI;
import com.fine.theme.utils.FineUIScale;
import com.fine.theme.utils.FineUIUtils;
import com.fr.design.Exception.ValidationException;
import com.fr.design.designer.properties.Decoder;
import com.fr.design.designer.properties.Encoder;
@ -39,6 +40,7 @@ import java.util.ArrayList;
*/
public class BaseAccessibleEditor extends BasicPane implements AccessibleEditor, HoverAware {
private final Insets defaultInsets = new Insets(0, 6, 0, 6);
private ArrayList<ChangeListener> listeners;
private boolean showButton;
protected Encoder encoder;
@ -47,6 +49,13 @@ public class BaseAccessibleEditor extends BasicPane implements AccessibleEditor,
protected ITextComponent txtValue;
private boolean hover;
private static final String UI_CLASS_ID = "InputUI";
@Override
public String getUIClassID() {
return UI_CLASS_ID;
}
public BaseAccessibleEditor(Encoder enc, Decoder dec, boolean showBtn) {
listeners = new ArrayList<ChangeListener>();
this.showButton = showBtn;
@ -56,12 +65,8 @@ public class BaseAccessibleEditor extends BasicPane implements AccessibleEditor,
initListener();
txtValue.setEditable(dec != null);
((JComponent) txtValue).setOpaque(false);
Insets insets = UIManager.getInsets("InputTextField.borderInsets");
Insets scaledInsets = FineUIScale.scale(insets);
((JComponent) txtValue).setBorder(BorderFactory.createEmptyBorder(scaledInsets.top, scaledInsets.left, scaledInsets.bottom, scaledInsets.right));
this.setUI(FineInputUI.createUI(this));
setPreferredSize(new Dimension(getPreferredSize().width, FineUIScale.scale(UIManager.getInt("Input.height"))));
Insets insets = FineUIUtils.getAndScaleUIInsets("InputTextField.borderInsets", defaultInsets);
((JComponent) txtValue).setBorder(BorderFactory.createEmptyBorder(insets.top, insets.left, insets.bottom, insets.right));
}
private void initListener() {

6
designer-base/src/main/java/com/fr/design/style/background/gradient/FixedGradientBar.java

@ -12,6 +12,7 @@ public class FixedGradientBar extends GradientBar {
public FixedGradientBar(int minvalue, int maxvalue) {
super(minvalue, maxvalue);
setDraggable(false);
}
@Override
@ -19,9 +20,4 @@ public class FixedGradientBar extends GradientBar {
setColor(getList().get(select).getColorInner());
super.clickButton(select);
}
@Override
protected void addMouseDragListener() {
//不添加拖拽事件
}
}

128
designer-base/src/main/java/com/fr/design/style/background/gradient/GradientBar.java

@ -1,5 +1,7 @@
package com.fr.design.style.background.gradient;
import com.fine.theme.light.ui.FineGradientBarUI;
import com.fine.theme.utils.FineUIUtils;
import com.fr.base.background.ColorBackground;
import com.fr.design.event.UIObserver;
import com.fr.design.event.UIObserverListener;
@ -8,34 +10,35 @@ import com.fr.design.style.color.ColorCell;
import com.fr.design.style.color.ColorSelectable;
import com.fr.design.style.color.NewColorSelectPane;
import com.fr.stable.AssistUtils;
import com.fr.stable.os.OperatingSystem;
import javax.swing.JPanel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.LinearGradientPaint;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.List;
/**
* TODO:面板缩放的功能没有考虑就是尾值过大导致超过界面显示的情况原来的那个实现完全是个BUG要缩放的情况也比较少就干脆以后弄吧
* 渐变色滑块
*
* @since 11.0
* Create on 2023/12/27.
*/
public class GradientBar extends AbstractComponentPopBox implements UIObserver, ColorSelectable {
private static final String UI_CLASS_ID = "GradientBarUI";
@Override
public String getUIClassID() {
return UI_CLASS_ID;
}
private NewColorSelectPane colorPane;
/**
*
*/
private static final long serialVersionUID = -8503629815871053585L;
private List<SelectColorPointBtn> list = new ArrayList<SelectColorPointBtn>();
@ -57,6 +60,8 @@ public class GradientBar extends AbstractComponentPopBox implements UIObserver,
private static final int MAX_VERTICAL = 45;
private boolean draggable = true;
// 选中的颜色
private Color color;
@ -71,19 +76,17 @@ public class GradientBar extends AbstractComponentPopBox implements UIObserver,
endLabel = new UINumberField(11);
endLabel.setValue(max);
endLabel.getDocument().addDocumentListener(docListener);
this.setPreferredSize(new Dimension(max + 5, 50));
p1 = new SelectColorPointBtn(startLabel.getValue(), 30, Color.WHITE);
p2 = new SelectColorPointBtn(endLabel.getValue(), 30, Color.BLACK);
int recHeight = FineUIUtils.getAndScaleInt("GradientBar.recHeight", 30);
p1 = new SelectColorPointBtn(startLabel.getValue(), recHeight, Color.WHITE);
p2 = new SelectColorPointBtn(endLabel.getValue(), recHeight, Color.BLACK);
list.add(p1);
list.add(p2);
this.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
p1.setStartPosition(0);
p2.setStartPosition(1);
addMouseClickListener();
addMouseDragListener();
iniListener();
setUI(new FineGradientBarUI());
}
public List<SelectColorPointBtn> getList() {
@ -110,7 +113,7 @@ public class GradientBar extends AbstractComponentPopBox implements UIObserver,
protected void addMouseClickListener() {
this.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if (e.getX() < max + MOUSE_OFFSET && e.getX() > 0) {
if (e.getX() < getWidth() && e.getX() > 0) {
int select = -1;
for (int i = 0; i < list.size(); i++) {
if (list.get(i).contains(e.getX(), e.getY())) {
@ -159,35 +162,6 @@ public class GradientBar extends AbstractComponentPopBox implements UIObserver,
return colorPane;
}
protected void addMouseDragListener() {
this.addMouseMotionListener(new MouseAdapter() {
public void mouseDragged(MouseEvent e) {
int oldIndex = index;
for (int i = 0; i < list.size(); i++) {
if (list.get(i).contains(e.getX(), e.getY())) {
index = i;
break;
}
}
if (OperatingSystem.isLinux() && AssistUtils.equals(oldIndex, index)) {
if (Math.abs(p1.getX() - e.getX()) > Math.abs(p2.getX() - e.getX())) {
index = 1;
} else {
index = 0;
}
}
boolean x = e.getX() <= max && e.getX() >= min;
if (x && e.getY() < MAX_VERTICAL) {
list.get(index).setX(e.getX());
}
GradientBar.this.repaint();
startLabel.setText(Double.toString(p1.getX()));
endLabel.setText(Double.toString(p2.getX()));
}
});
}
private void iniListener() {
uiObserverListener = new ArrayList<>();
if (shouldResponseChangeListener()) {
@ -216,40 +190,6 @@ public class GradientBar extends AbstractComponentPopBox implements UIObserver,
}
};
@Override
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
Point2D start = new Point2D.Float(4, 0);
Point2D end = new Point2D.Float(max, 0);
Collections.sort(list);
Color[] c = new Color[list.size()];
for (int i = 0; i < list.size(); i++) {
c[i] = list.get(i).getColorInner();
}
float[] dist = new float[list.size()];
for (int i = 0; i < list.size(); i++) {
double value = list.get(i).getX() - 4;
double defaultMax = max - 4;
if (Double.compare(value, defaultMax) > 0) {
// 设置了预定义的渐变色 渐变色起始位置比较大 然后由预定义样式切换到自定义样式 做下等比例转换
dist[i] = (float) (value / (GradientBackgroundPane.DEFAULT_GRADIENT_WIDTH - 4));
list.get(i).setX(max * dist[i]);
} else {
dist[i] = (float) (value / defaultMax);
}
}
LinearGradientPaint paint = new LinearGradientPaint(start, end, dist, c);
g2.setPaint(paint);
g2.fillRect(4, 0, max - 4, 30);
g2.setColor(new Color(138, 138, 138));
g2.drawRect(4, 0, max - 4, 30);
for (int i = 0; i < list.size(); i++) {
list.get(i).paint(g2);
}
}
/**
* 状态改变
*/
@ -281,14 +221,14 @@ public class GradientBar extends AbstractComponentPopBox implements UIObserver,
* @return
*/
public double getStartValue() {
return startLabel.getValue();
return p1.getStartPosition() * (max - min) + min;
}
/**
* @return
*/
public double getEndValue() {
return endLabel.getValue();
return p2.getStartPosition() * (max - min) + min;
}
/**
@ -296,7 +236,7 @@ public class GradientBar extends AbstractComponentPopBox implements UIObserver,
*/
public void setStartValue(double startValue) {
startLabel.setValue(startValue);
p1.setX(startValue);
p1.setStartPosition((startValue - min) / (max - min));
}
/**
@ -304,7 +244,7 @@ public class GradientBar extends AbstractComponentPopBox implements UIObserver,
*/
public void setEndValue(double endValue) {
endLabel.setValue(endValue);
p2.setX(endValue);
p2.setStartPosition((endValue - min) / (max - min));
}
/**
@ -359,4 +299,12 @@ public class GradientBar extends AbstractComponentPopBox implements UIObserver,
public void colorSetted(ColorCell colorCell) {
}
public boolean isDraggable() {
return draggable;
}
public void setDraggable(boolean draggable) {
this.draggable = draggable;
}
}

43
designer-base/src/main/java/com/fr/design/style/background/gradient/SelectColorPointBtn.java

@ -4,6 +4,7 @@ import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.Path2D;
public class SelectColorPointBtn implements Comparable<SelectColorPointBtn> {
@ -11,12 +12,19 @@ public class SelectColorPointBtn implements Comparable<SelectColorPointBtn> {
private double y;
private double a = 4;
private double b = 4;
private GeneralPath ipath;
private GeneralPath jpath;
private Path2D ipath;
private Path2D jpath;
private Color colorInner;
// 起始位置,范围(0,1)
private double startPosition;
private double max;
/*提供一个可设置拖拉按钮边框颜色*/
private Color borderColor;
private boolean hover = false;
private boolean pressed = false;
public SelectColorPointBtn(double m, double n, Color colorInner){
this(m, n, colorInner, Color.BLACK);
}
@ -40,6 +48,14 @@ public class SelectColorPointBtn implements Comparable<SelectColorPointBtn> {
this.x = x;
}
public double getStartPosition() {
return startPosition;
}
public void setStartPosition(double startPosition) {
this.startPosition = startPosition;
}
public double getY() {
return y;
}
@ -84,6 +100,13 @@ public class SelectColorPointBtn implements Comparable<SelectColorPointBtn> {
g2.setColor(new Color(228, 228, 228));
g2.draw(jpath);
}
/**
* 更新拖拉按钮路径
*/
public void updatePath(Path2D directionalThumbShape) {
this.ipath = directionalThumbShape;
}
public boolean contains(double x, double y){
return ipath.contains(x, y);
@ -93,4 +116,20 @@ public class SelectColorPointBtn implements Comparable<SelectColorPointBtn> {
public int compareTo(SelectColorPointBtn o) {
return Double.compare(x, o.x);
}
public boolean isHover() {
return hover;
}
public void setHover(boolean b) {
hover = b;
}
public boolean isPressed() {
return pressed;
}
public void setPressed(boolean pressed) {
this.pressed = pressed;
}
}

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

@ -19,7 +19,7 @@ MenuItemUI=com.formdev.flatlaf.ui.FlatMenuItemUI
OptionPaneUI=com.formdev.flatlaf.ui.FlatOptionPaneUI
PanelUI=com.formdev.flatlaf.ui.FlatPanelUI
PasswordFieldUI=com.formdev.flatlaf.ui.FlatPasswordFieldUI
PopupMenuUI=com.formdev.flatlaf.ui.FlatPopupMenuUI
PopupMenuUI=com.fine.theme.light.ui.FinePopupMenuUI
PopupMenuSeparatorUI=com.formdev.flatlaf.ui.FlatPopupMenuSeparatorUI
ProgressBarUI=com.formdev.flatlaf.ui.FlatProgressBarUI
RadioButtonUI=com.formdev.flatlaf.ui.FlatRadioButtonUI
@ -28,7 +28,7 @@ RootPaneUI=com.formdev.flatlaf.ui.FlatRootPaneUI
ScrollBarUI=com.formdev.flatlaf.ui.FlatScrollBarUI
ScrollPaneUI=com.formdev.flatlaf.ui.FlatScrollPaneUI
SeparatorUI=com.formdev.flatlaf.ui.FlatSeparatorUI
SliderUI=com.formdev.flatlaf.ui.FlatSliderUI
SliderUI=com.fine.theme.light.ui.FineSliderUI
SpinnerUI=com.formdev.flatlaf.ui.FlatSpinnerUI
SplitPaneUI=com.formdev.flatlaf.ui.FlatSplitPaneUI
TabbedPaneUI=com.formdev.flatlaf.ui.FlatTabbedPaneUI
@ -46,4 +46,5 @@ ViewportUI=com.formdev.flatlaf.ui.FlatViewportUI
HeadGroupUI=com.fine.theme.light.ui.FineHeadGroupUI
ButtonGroupUI= com.fine.theme.light.ui.FineButtonGroupUI
SelectBoxUI= com.fine.theme.light.ui.FineSelectBoxUI
InputUI=com.fine.theme.light.ui.FineInputUI
GradientBarUI=com.fine.theme.light.ui.FineGradientBarUI

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

@ -547,14 +547,14 @@ PopupToolPane.height=34
PopupToolPane.borderInsets=0, 10, 0, 10
#---- PopupMenu ----
PopupMenu.border = com.formdev.flatlaf.ui.FlatPopupMenuBorder
PopupMenu.borderInsets = 4,1,4,1
PopupMenu.border=com.fine.theme.light.ui.FinePopupMenuBorder
PopupMenu.borderInsets=10,0,10,0
PopupMenu.borderCornerRadius = $Popup.borderCornerRadius
PopupMenu.background = @menuBackground
PopupMenu.background=$background.normal
PopupMenu.scrollArrowColor = @buttonArrowColor
PopupMenu.borderColor = shade(@background,28%)
PopupMenu.borderColor=$border.divider
PopupMenu.hoverScrollArrowBackground = darken(@background,5%)
PopupMenu.arc=$Component.arc
#---- PopupMenuSeparator ----
@ -688,17 +688,34 @@ Separator.foreground = shade(@background,15%)
Slider.focusInsets = 0,0,0,0
Slider.trackWidth = 2
Slider.thumbSize = 12,12
Slider.focusWidth = 4
Slider.focusWidth=0
Slider.trackValueColor=$brand.normal
Slider.trackColor=$border.divider
Slider.thumbColor=$fill.normal
Slider.thumbBorderColor=$border.divider
Slider.tickColor = @disabledForeground
Slider.focusedColor = fade(changeLightness($Component.focusColor,75%,derived),50%,derived)
Slider.focusedColor=$border.divider
Slider.focusedThumbBorderColor=$border.divider
Slider.hoverThumbColor=$fill.hover
Slider.pressedThumbColor=$fill.hover
Slider.disabledTrackColor = darken(@background,13%)
Slider.disabledThumbColor = $Slider.disabledTrackColor
Slider.labelHeight=13
#---- FormSliderPane ----
FormSliderPane.showValueWidth=40
FormSliderPane.showValueHeight=20
FormSliderPane.sliderWidth=220
FormSliderPane.sliderHeight=20
#---- GradientBar ----
GradientBar.borderColor=$border.divider
GradientBar.thumbBorderColor=$border.divider
GradientBar.borderWidth=1
GradientBar.pressedThumbColor=@BrandColor
GradientBar.hoverThumbColor=@BrandColor
GradientBar.thumbWidth=12
GradientBar.recWidth=160
GradientBar.recHeight=30
#---- Spinner ----

25
designer-base/src/test/java/com/fr/design/gui/storybook/components/SliderStoryBoard.java

@ -1,8 +1,12 @@
package com.fr.design.gui.storybook.components;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.islider.UISlider;
import com.fr.design.gui.storybook.Story;
import com.fr.design.gui.storybook.StoryBoard;
import com.fr.design.mainframe.JFormSliderPane;
import com.fr.design.style.background.gradient.GradientBar;
import java.awt.Color;
import static com.fine.swing.ui.layout.Layouts.*;
@ -13,12 +17,27 @@ import static com.fine.swing.ui.layout.Layouts.*;
* @since 11.0
* Created on 2023/12/14
*/
@Story
public class SliderStoryBoard extends StoryBoard {
public SliderStoryBoard() {
super("滑块");
add(
cell(new UILabel("面板缩放滑块")).with(this::h3),
row(cell(new JFormSliderPane()))
cell(new UILabel("无标签滑块")).with(this::h3),
row(cell(new UISlider()).with(it -> {
it.setValue(50);
it.setMaximum(100);
it.setMinimum(0);
})),
cell(new UILabel("带标签滑块")).with(this::h3),
row(cell(new UISlider()).with(it -> {
it.setPaintLabels(true);
it.setMajorTickSpacing(90);
it.setValue(40);
it.setMaximum(90);
it.setMinimum(-90);
})),
cell(new UILabel("渐变色滑块")).with(this::h3),
row(cell(new GradientBar(6, 150)).with(it -> it.updateColor(new Color(55, 104, 196), new Color(180, 97, 39))))
);
}
}

1
designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/GroupPane.java

@ -289,7 +289,6 @@ public class GroupPane extends JPanel {
public void mouseClicked(MouseEvent e) {
UIPopupMenu popupMenu = new UIPopupMenu();
popupMenu.setOnlyText(true);
popupMenu.setBackground(UIConstants.DEFAULT_BG_RULER);
popupMenu.add(new PopupMenuItem(new RenameAction()));
popupMenu.add(new PopupMenuItem(new RemoveAction()));

Loading…
Cancel
Save