Browse Source
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-覃宇攀
1 year ago
26 changed files with 951 additions and 211 deletions
@ -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); |
||||
} |
||||
} |
@ -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); |
||||
} |
||||
} |
@ -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); |
||||
} |
||||
} |
@ -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; |
||||
} |
||||
|
||||
} |
@ -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); |
||||
} |
||||
|
||||
} |
Loading…
Reference in new issue