Leo.Qin
1 year ago
8 changed files with 394 additions and 102 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); |
||||
} |
||||
} |
Loading…
Reference in new issue