|
|
|
package com.fine.component.popup;
|
|
|
|
|
|
|
|
import com.fine.theme.utils.FineUIUtils;
|
|
|
|
import com.formdev.flatlaf.ui.FlatUIUtils;
|
|
|
|
import com.formdev.flatlaf.util.Animator;
|
|
|
|
import com.formdev.flatlaf.util.CubicBezierEasing;
|
|
|
|
import com.formdev.flatlaf.util.UIScale;
|
|
|
|
import net.miginfocom.swing.MigLayout;
|
|
|
|
|
|
|
|
import javax.swing.JPanel;
|
|
|
|
import java.awt.AlphaComposite;
|
|
|
|
import java.awt.Graphics;
|
|
|
|
import java.awt.Graphics2D;
|
|
|
|
import java.awt.Image;
|
|
|
|
import java.awt.image.BufferedImage;
|
|
|
|
import java.util.Stack;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 遮罩功能:渐显遮罩层
|
|
|
|
*
|
|
|
|
* @author Levy.Xie
|
|
|
|
* @since 12.0
|
|
|
|
* Created on 2024/12/12
|
|
|
|
*/
|
|
|
|
public class ComponentLayer extends JPanel {
|
|
|
|
|
|
|
|
private GlassPaneChild component;
|
|
|
|
private GlassPaneChild nextComponent;
|
|
|
|
private Animator animator;
|
|
|
|
private float animate;
|
|
|
|
private boolean showSnapshot;
|
|
|
|
private boolean simpleSnapshot;
|
|
|
|
private Image image;
|
|
|
|
|
|
|
|
private Image nextImage;
|
|
|
|
private Stack<GlassPaneChild> componentStack;
|
|
|
|
private boolean push;
|
|
|
|
|
|
|
|
private void pushStack(GlassPaneChild component) {
|
|
|
|
if (componentStack == null) {
|
|
|
|
componentStack = new Stack<>();
|
|
|
|
}
|
|
|
|
componentStack.push(component);
|
|
|
|
}
|
|
|
|
|
|
|
|
public ComponentLayer(GlassPaneChild component) {
|
|
|
|
this.component = component;
|
|
|
|
init();
|
|
|
|
}
|
|
|
|
|
|
|
|
private void init() {
|
|
|
|
MigLayout layout = new MigLayout("insets 0,fill", "fill", "fill");
|
|
|
|
setLayout(layout);
|
|
|
|
if (component.getRoundBorder() > 0) {
|
|
|
|
setOpaque(false);
|
|
|
|
component.setOpaque(false);
|
|
|
|
}
|
|
|
|
add(component);
|
|
|
|
component.setVisible(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void initAnimator() {
|
|
|
|
animator = new Animator(350, new Animator.TimingTarget() {
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void timingEvent(float v) {
|
|
|
|
animate = v;
|
|
|
|
repaint();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void begin() {
|
|
|
|
nextImage = FineUIUtils.createImage(nextComponent);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void end() {
|
|
|
|
showSnapshot = false;
|
|
|
|
component = nextComponent;
|
|
|
|
component.popupShow();
|
|
|
|
nextComponent = null;
|
|
|
|
animate = 0;
|
|
|
|
component.setVisible(true);
|
|
|
|
if (nextImage != null) {
|
|
|
|
nextImage.flush();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
animator.setInterpolator(CubicBezierEasing.EASE);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void startAnimate() {
|
|
|
|
if (animator == null) {
|
|
|
|
initAnimator();
|
|
|
|
}
|
|
|
|
if (animator.isRunning()) {
|
|
|
|
animator.stop();
|
|
|
|
}
|
|
|
|
animate = 0;
|
|
|
|
animator.start();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 放入组件
|
|
|
|
*
|
|
|
|
* @param component 组件
|
|
|
|
*/
|
|
|
|
public void pushComponent(GlassPaneChild component) {
|
|
|
|
component.onPush();
|
|
|
|
pushStack(this.component);
|
|
|
|
push = true;
|
|
|
|
showComponent(component);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 弹出组件
|
|
|
|
*/
|
|
|
|
public void popComponent() {
|
|
|
|
if (!componentStack.isEmpty()) {
|
|
|
|
GlassPaneChild component = componentStack.pop();
|
|
|
|
component.onPop();
|
|
|
|
push = false;
|
|
|
|
showComponent(component);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void showComponent(GlassPaneChild component) {
|
|
|
|
showSnapshot = true;
|
|
|
|
this.nextComponent = component;
|
|
|
|
if (!component.isTransparent()) {
|
|
|
|
image = FineUIUtils.createImage(this.component);
|
|
|
|
}
|
|
|
|
if (component.getRoundBorder() > 0) {
|
|
|
|
setOpaque(false);
|
|
|
|
component.setOpaque(false);
|
|
|
|
}
|
|
|
|
component.setVisible(false);
|
|
|
|
remove(this.component);
|
|
|
|
add(component);
|
|
|
|
revalidate();
|
|
|
|
startAnimate();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 显示遮罩
|
|
|
|
*/
|
|
|
|
public void showSnapshot() {
|
|
|
|
if (animator != null && animator.isRunning()) {
|
|
|
|
animator.stop();
|
|
|
|
}
|
|
|
|
simpleSnapshot = true;
|
|
|
|
doLayout();
|
|
|
|
if (!component.isTransparent()) {
|
|
|
|
image = FineUIUtils.createImage(component, component.getRoundBorder());
|
|
|
|
}
|
|
|
|
component.setVisible(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 隐藏遮罩
|
|
|
|
*/
|
|
|
|
public void hideSnapshot() {
|
|
|
|
showSnapshot = false;
|
|
|
|
simpleSnapshot = false;
|
|
|
|
component.setVisible(true);
|
|
|
|
if (image != null) {
|
|
|
|
image.flush();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void paintComponent(Graphics g) {
|
|
|
|
if (!component.isTransparent()) {
|
|
|
|
if (!isOpaque() && component.getRoundBorder() > 0) {
|
|
|
|
Graphics2D g2 = (Graphics2D) g.create();
|
|
|
|
FlatUIUtils.setRenderingHints(g2);
|
|
|
|
g2.setColor(getBackground());
|
|
|
|
int arc = UIScale.scale(component.getRoundBorder());
|
|
|
|
FlatUIUtils.paintComponentBackground(g2, 0, 0, getWidth(), getHeight(), 0, arc);
|
|
|
|
g2.dispose();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
super.paintComponent(g);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void paint(Graphics g) {
|
|
|
|
if (simpleSnapshot) {
|
|
|
|
g.drawImage(image, 0, 0, null);
|
|
|
|
} else if (showSnapshot) {
|
|
|
|
int width = getWidth();
|
|
|
|
int height = getHeight();
|
|
|
|
if (width > 0 && height > 0) {
|
|
|
|
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
|
|
|
Graphics2D g2 = bufferedImage.createGraphics();
|
|
|
|
FlatUIUtils.setRenderingHints(g2);
|
|
|
|
int arc = UIScale.scale(component.getRoundBorder());
|
|
|
|
g2.setColor(getBackground());
|
|
|
|
FlatUIUtils.paintComponentBackground(g2, 0, 0, width, height, 0, arc);
|
|
|
|
if (image != null) {
|
|
|
|
paintImage(g2);
|
|
|
|
}
|
|
|
|
if (nextImage != null) {
|
|
|
|
paintNextImage(g2);
|
|
|
|
}
|
|
|
|
g2.dispose();
|
|
|
|
g.drawImage(bufferedImage, 0, 0, null);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
super.paint(g);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void paintNextImage(Graphics2D g2) {
|
|
|
|
int w = nextImage.getWidth(null);
|
|
|
|
double x;
|
|
|
|
if (push) {
|
|
|
|
x = getWidth() - (w * animate);
|
|
|
|
} else {
|
|
|
|
x = -getWidth() + (w * animate);
|
|
|
|
}
|
|
|
|
g2.setComposite(AlphaComposite.SrcAtop.derive(animate));
|
|
|
|
g2.drawImage(nextImage, (int) x, 0, null);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void paintImage(Graphics2D g2) {
|
|
|
|
int w = image.getWidth(null);
|
|
|
|
double x;
|
|
|
|
if (push) {
|
|
|
|
x = -w * animate;
|
|
|
|
} else {
|
|
|
|
x = w * animate;
|
|
|
|
}
|
|
|
|
g2.setComposite(AlphaComposite.SrcAtop.derive(1f - animate));
|
|
|
|
g2.drawImage(image, (int) x, 0, null);
|
|
|
|
}
|
|
|
|
|
|
|
|
public GlassPaneChild getComponent() {
|
|
|
|
return component;
|
|
|
|
}
|
|
|
|
}
|