Browse Source

Pull request #7505: REPORT-64487 表头按钮颜色配置主题色以后,联动有问题

Merge in DESIGN/design from ~HENRY.WANG/design:feature/x to feature/x

* commit 'b8eb6e881f2a96d24fd4b3cafa40dc0b69073f86':
  REPORT-64679 插入删除行以后,排序区域和表头区域的单元格值没有联动变化
  REPORT-64487 表头按钮颜色配置主题色以后,联动有问题
feature/x
Henry.Wang 3 years ago
parent
commit
e37fcbbfd3
  1. 3
      designer-base/src/main/java/com/fr/base/svg/IconUtils.java
  2. 6
      designer-base/src/main/java/com/fr/base/svg/SVGIcon.java
  3. 92
      designer-base/src/main/java/com/fr/base/svg/SVGLoader.java
  4. 181
      designer-base/src/main/java/com/fr/base/svg/SVGTranscoder.java
  5. 101
      designer-base/src/main/java/com/fr/base/svg/SystemScaleUtils.java
  6. 19
      designer-base/src/main/resources/com/fr/design/images/sort/asc.svg
  7. 17
      designer-base/src/main/resources/com/fr/design/images/sort/des.svg
  8. 41
      designer-base/src/main/resources/com/fr/design/images/sort/nosort.svg
  9. 165
      designer-realize/src/main/java/com/fr/design/sort/header/HeaderSortRulePane.java

3
designer-base/src/main/java/com/fr/base/svg/IconUtils.java

@ -6,8 +6,7 @@ import com.fr.stable.bridge.StableFactory;
import com.fr.stable.fun.ResourcePathTransformer; import com.fr.stable.fun.ResourcePathTransformer;
import com.fr.stable.plugin.ExtraClassManagerProvider; import com.fr.stable.plugin.ExtraClassManagerProvider;
import javax.swing.Icon; import javax.swing.*;
import javax.swing.ImageIcon;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;

6
designer-base/src/main/java/com/fr/base/svg/SVGIcon.java

@ -2,10 +2,8 @@ package com.fr.base.svg;
import com.fr.general.IOUtils; import com.fr.general.IOUtils;
import javax.swing.Icon; import javax.swing.*;
import java.awt.Component; import java.awt.*;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;

92
designer-base/src/main/java/com/fr/base/svg/SVGLoader.java

@ -1,92 +0,0 @@
package com.fr.base.svg;
import com.fr.general.IOUtils;
import org.apache.batik.transcoder.TranscoderException;
import org.apache.batik.transcoder.TranscoderInput;
import org.apache.xmlgraphics.java2d.Dimension2DDouble;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.awt.Image;
import java.io.IOException;
import java.net.URL;
/**
* SVG图标加载器
* @author Yvan
* @version 10.0
* Created by Yvan on 2020/12/17
*/
public class SVGLoader {
public static final int ICON_DEFAULT_SIZE = 16;
public SVGLoader() {
}
@Nullable
public static Image load(@NotNull String url) {
try {
URL resource = IOUtils.getResource(url, SVGLoader.class);
if (resource == null) {
return null;
}
return load(resource, SVGIcon.SYSTEM_SCALE);
} catch (IOException ignore) {
return null;
}
}
@Nullable
public static Image load(@NotNull URL url) throws IOException {
return load(url, SVGIcon.SYSTEM_SCALE);
}
@Nullable
public static Image load(@NotNull URL url, double scale) throws IOException {
try {
String svgUri = url.toString();
TranscoderInput input = new TranscoderInput(svgUri);
return SVGTranscoder.createImage(scale, input).getImage();
} catch (TranscoderException ignore) {
return null;
}
}
@Nullable
public static Image load(@NotNull URL url, double scale, Dimension2DDouble dimension) throws IOException {
try {
String svgUri = url.toString();
TranscoderInput input = new TranscoderInput(svgUri);
return SVGTranscoder.createImage(scale, input,
(float) (dimension.getWidth() * scale), (float) (dimension.getHeight() * scale)).getImage();
} catch (TranscoderException ignore) {
return null;
}
}
@Nullable
public static Image load(@NotNull URL url, double scale, double overriddenWidth, double overriddenHeight) throws IOException {
try {
String svgUri = url.toString();
TranscoderInput input = new TranscoderInput(svgUri);
return SVGTranscoder.createImage(scale, input, (float) (overriddenWidth * scale), (float) (overriddenHeight * scale)).getImage();
} catch (TranscoderException ignore) {
return null;
}
}
@Nullable
public static Image load(@NotNull String url, float width, float height) {
try {
URL resource = IOUtils.getResource(url, SVGLoader.class);
if (resource == null) {
return null;
}
TranscoderInput input = new TranscoderInput(resource.toString());
return SVGTranscoder.createImage(SVGIcon.SYSTEM_SCALE, input, -1, -1, width, height).getImage();
} catch (TranscoderException ignore) {
return null;
}
}
}

181
designer-base/src/main/java/com/fr/base/svg/SVGTranscoder.java

@ -1,181 +0,0 @@
package com.fr.base.svg;
import com.fr.stable.AssistUtils;
import com.fr.value.AtomicNotNullLazyValue;
import org.apache.batik.anim.dom.SAXSVGDocumentFactory;
import org.apache.batik.anim.dom.SVGOMDocument;
import org.apache.batik.bridge.BridgeContext;
import org.apache.batik.bridge.UserAgent;
import org.apache.batik.transcoder.SVGAbstractTranscoder;
import org.apache.batik.transcoder.TranscoderException;
import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.TranscoderOutput;
import org.apache.batik.transcoder.image.ImageTranscoder;
import org.apache.batik.util.XMLResourceDescriptor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.w3c.dom.Element;
import org.w3c.dom.svg.SVGDocument;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.StringReader;
/**
* 可以根据某个缩放倍数scale将SVG图片转化为Image对象
* @author Yvan
* @version 10.0
* Created by Yvan on 2020/12/17
*/
public class SVGTranscoder extends ImageTranscoder {
private static final float DEFAULT_VALUE = -1.0F;
public static final float ICON_DEFAULT_SIZE = 16F;
private float origDocWidth;
private float origDocHeight;
@Nullable
private BufferedImage image;
private final double scale;
@NotNull
private static AtomicNotNullLazyValue<Double> iconMaxSize = new AtomicNotNullLazyValue<Double>() {
@NotNull
@Override
protected Double compute() {
double maxSize = Double.MAX_VALUE;
if (!GraphicsEnvironment.isHeadless()) {
GraphicsDevice defaultScreenDevice = GraphicsEnvironment
.getLocalGraphicsEnvironment()
.getDefaultScreenDevice();
Rectangle bounds = defaultScreenDevice.getDefaultConfiguration().getBounds();
AffineTransform tx = defaultScreenDevice
.getDefaultConfiguration()
.getDefaultTransform();
maxSize = Math.max(bounds.width * tx.getScaleX(), bounds.height * tx.getScaleY());
}
return maxSize;
}
};
public SVGTranscoder(double scale) {
this.scale = scale;
this.width = ICON_DEFAULT_SIZE;
this.height = ICON_DEFAULT_SIZE;
}
public SVGTranscoder(double scale, float width, float height) {
this.scale = scale;
this.width = width;
this.height = height;
}
public final float getOrigDocWidth() {
return this.origDocWidth;
}
public final void setOrigDocWidth(float origDocWidth) {
this.origDocWidth = origDocWidth;
}
public final float getOrigDocHeight() {
return this.origDocHeight;
}
public final void setOrigDocHeight(float origDocHeight) {
this.origDocHeight = origDocHeight;
}
public static double getIconMaxSize() {
return iconMaxSize.getValue();
}
@Nullable
public final BufferedImage getImage() {
return this.image;
}
@NotNull
public static SVGTranscoder createImage(double scale, @NotNull TranscoderInput input) throws TranscoderException {
return createImage(scale, input, -1, -1);
}
@NotNull
public static SVGTranscoder createImage(double scale, @NotNull TranscoderInput input, float overriddenWidth, float overriddenHeight) throws TranscoderException {
return createImage(scale, input, overriddenWidth, overriddenHeight, ICON_DEFAULT_SIZE, ICON_DEFAULT_SIZE);
}
@NotNull
public static SVGTranscoder createImage(double scale, @NotNull TranscoderInput input, float overriddenWidth, float overriddenHeight, float width, float height) throws TranscoderException {
SVGTranscoder transcoder = new SVGTranscoder(scale, width, height);
if (!AssistUtils.equals(overriddenWidth, DEFAULT_VALUE)) {
transcoder.addTranscodingHint(SVGAbstractTranscoder.KEY_WIDTH, overriddenWidth);
}
if (!AssistUtils.equals(overriddenHeight, DEFAULT_VALUE)) {
transcoder.addTranscodingHint(SVGAbstractTranscoder.KEY_HEIGHT, overriddenHeight);
}
double iconMaxSize = SVGTranscoder.iconMaxSize.getValue();
transcoder.addTranscodingHint(SVGAbstractTranscoder.KEY_MAX_WIDTH, (float) iconMaxSize);
transcoder.addTranscodingHint(SVGAbstractTranscoder.KEY_MAX_HEIGHT, (float) iconMaxSize);
transcoder.transcode(input, null);
return transcoder;
}
private static SVGDocument createFallbackPlaceholder() {
try {
String fallbackIcon = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\">\n" +
" <rect x=\"1\" y=\"1\" width=\"14\" height=\"14\" fill=\"none\" stroke=\"red\" stroke-width=\"2\"/>\n" +
" <line x1=\"1\" y1=\"1\" x2=\"15\" y2=\"15\" stroke=\"red\" stroke-width=\"2\"/>\n" +
" <line x1=\"1\" y1=\"15\" x2=\"15\" y2=\"1\" stroke=\"red\" stroke-width=\"2\"/>\n" +
"</svg>\n";
SAXSVGDocumentFactory factory = new SAXSVGDocumentFactory(XMLResourceDescriptor.getXMLParserClassName());
return (SVGDocument) factory.createDocument(null, new StringReader(fallbackIcon));
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
@Override
protected void setImageSize(float docWidth, float docHeight) {
super.setImageSize((float) (docWidth * this.scale), (float) (docHeight * this.scale));
this.origDocWidth = docWidth;
this.origDocHeight = docHeight;
}
@Override
@NotNull
public BufferedImage createImage(int width, int height) {
return new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
}
@Override
public void writeImage(@NotNull BufferedImage image, @Nullable TranscoderOutput output) {
this.image = image;
}
@Override
@NotNull
protected UserAgent createUserAgent() {
return new SVGAbstractTranscoderUserAgent() {
@Override
@NotNull
public SVGDocument getBrokenLinkDocument(@NotNull Element e, @NotNull String url, @NotNull String message) {
return createFallbackPlaceholder();
}
};
}
/**
* 开放访问权限
*/
@Override
public BridgeContext createBridgeContext(SVGOMDocument doc) {
return super.createBridgeContext(doc);
}
}

101
designer-base/src/main/java/com/fr/base/svg/SystemScaleUtils.java

@ -1,101 +0,0 @@
package com.fr.base.svg;
import com.bulenkov.iconloader.util.UIUtil;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.StableUtils;
import com.fr.stable.os.OperatingSystem;
import org.jetbrains.annotations.NotNull;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.lang.reflect.Method;
import java.util.concurrent.atomic.AtomicReference;
/**
* 获取系统Scale相关的工具类
* @author Yvan
* @version 10.0
* Created by Yvan on 2020/12/17
*/
public class SystemScaleUtils {
private static final AtomicReference<Boolean> JRE_HIDPI = new AtomicReference<>();
private static final String HI_DPI = "hidpi";
/**
* 判断是否支持高清
* @return
*/
public static boolean isJreHiDPIEnabled() {
if (JRE_HIDPI.get() != null) {
return JRE_HIDPI.get();
}
if (OperatingSystem.isMacos()) {
// 如果是mac os系统,直接返回true
return true;
}
if (OperatingSystem.isWindows() && StableUtils.getMajorJavaVersion() <= 8) {
// 如果是jdk8 + Windows系统,直接返回false
return false;
}
synchronized (JRE_HIDPI) {
if (JRE_HIDPI.get() != null) {
return JRE_HIDPI.get();
}
boolean result = false;
if (getBooleanProperty(HI_DPI, true)) {
try {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
Class<?> sunGraphicsEnvironmentClass = Class.forName("sun.java2d.SunGraphicsEnvironment");
if (sunGraphicsEnvironmentClass.isInstance(ge)) {
try {
Method method = sunGraphicsEnvironmentClass.getDeclaredMethod("isUIScaleEnabled");
method.setAccessible(true);
result = (Boolean)method.invoke(ge);
}
catch (NoSuchMethodException e) {
FineLoggerFactory.getLogger().error(e.getMessage());
}
}
}
catch (Throwable ignore) {
}
}
JRE_HIDPI.set(result);
return result;
}
}
public static boolean getBooleanProperty(@NotNull final String key, final boolean defaultValue) {
final String value = System.getProperty(key);
return value == null ? defaultValue : Boolean.parseBoolean(value);
}
/**
* 获取系统Scale
* @return
*/
public static float sysScale() {
// 如果检测到是retina,直接返回2
if (UIUtil.isRetina()) {
return 2.0f;
}
float scale = 1.0f;
// 先判断是否支持高清,不支持代表此时是Windows + jdk8 的设计器,返回的scale值为1.0
if (isJreHiDPIEnabled()) {
// 获取屏幕图形设备对象
GraphicsDevice graphicsDevice = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
if (graphicsDevice != null) {
// 获取图形配置对象
GraphicsConfiguration configuration = graphicsDevice.getDefaultConfiguration();
if (configuration != null && configuration.getDevice().getType() != GraphicsDevice.TYPE_PRINTER) {
// 获取屏幕缩放率,Windows+jdk11环境下会得到用户设置的dpi值
scale = (float) configuration.getDefaultTransform().getScaleX();
}
}
}
return scale;
}
}

19
designer-base/src/main/resources/com/fr/design/images/sort/asc.svg

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>升序备份</title>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="画板" transform="translate(-641.000000, -632.000000)">
<g id="升序备份" transform="translate(641.000000, 632.000000)">
<rect id="矩形" x="0" y="0" width="16" height="16"></rect>
<g id="编组-2" transform="translate(1.000000, 2.000000)" fill="#{fillColor}">
<rect id="矩形" x="10.5" y="1" width="1" height="11"></rect>
<path d="M11.16,0.213333333 L13.76,3.68 C13.8262742,3.76836556 13.8083656,3.89372583 13.72,3.96 C13.6853808,3.98596443 13.643274,4 13.6,4 L8.4,4 C8.28954305,4 8.2,3.91045695 8.2,3.8 C8.2,3.75672596 8.21403557,3.71461923 8.24,3.68 L10.84,0.213333333 C10.9062742,0.124967773 11.0316344,0.107059163 11.12,0.173333333 C11.1351611,0.184704183 11.1486292,0.1981722 11.16,0.213333333 Z" id="三角形"></path>
<rect id="矩形" x="0" y="4" width="7" height="1"></rect>
<rect id="矩形备份-3" x="0" y="0.5" width="6" height="1"></rect>
<rect id="矩形备份" x="0" y="7.5" width="8" height="1"></rect>
<rect id="矩形备份-2" x="0" y="11" width="9" height="1"></rect>
</g>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

17
designer-base/src/main/resources/com/fr/design/images/sort/des.svg

@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>降序</title>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="画板" transform="translate(-641.000000, -662.000000)">
<g id="降序" transform="translate(641.000000, 662.000000)">
<rect id="矩形" transform="translate(8.000000, 8.000000) scale(1, -1) translate(-8.000000, -8.000000) " x="0" y="0" width="16" height="16"></rect>
<rect id="矩形" fill="#{fillColor}" transform="translate(12.000000, 7.500000) scale(1, -1) translate(-12.000000, -7.500000) " x="11.5" y="2" width="1" height="11"></rect>
<path d="M12.16,10.2133333 L14.76,13.68 C14.8262742,13.7683656 14.8083656,13.8937258 14.72,13.96 C14.6853808,13.9859644 14.643274,14 14.6,14 L9.4,14 C9.28954305,14 9.2,13.9104569 9.2,13.8 C9.2,13.756726 9.21403557,13.7146192 9.24,13.68 L11.84,10.2133333 C11.9062742,10.1249678 12.0316344,10.1070592 12.12,10.1733333 C12.1351611,10.1847042 12.1486292,10.1981722 12.16,10.2133333 Z" id="三角形" fill="#{fillColor}" transform="translate(12.000000, 12.000000) scale(1, -1) translate(-12.000000, -12.000000) "></path>
<rect id="矩形" fill="#{fillColor}" transform="translate(4.500000, 9.500000) scale(1, -1) translate(-4.500000, -9.500000) " x="1" y="9" width="7" height="1"></rect>
<rect id="矩形备份-3" fill="#{fillColor}" transform="translate(4.000000, 13.000000) scale(1, -1) translate(-4.000000, -13.000000) " x="1" y="12.5" width="6" height="1"></rect>
<rect id="矩形备份" fill="#{fillColor}" transform="translate(5.000000, 6.000000) scale(1, -1) translate(-5.000000, -6.000000) " x="1" y="5.5" width="8" height="1"></rect>
<rect id="矩形备份-2" fill="#{fillColor}" transform="translate(5.500000, 2.500000) scale(1, -1) translate(-5.500000, -2.500000) " x="1" y="2" width="9" height="1"></rect>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.1 KiB

41
designer-base/src/main/resources/com/fr/design/images/sort/nosort.svg

@ -1,41 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<title>不排序</title>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="画板" transform="translate(-641.000000, -692.000000)">
<g id="不排序" transform="translate(641.000000, 692.000000)">
<rect id="矩形" transform="translate(8.000000, 8.000000) scale(1, -1) translate(-8.000000, -8.000000) "
x="0" y="0" width="16" height="16"></rect>
<g id="编组-5" transform="translate(9.000000, 8.000000)" fill="#{fillColor}">
<rect id="矩形"
transform="translate(3.000000, 2.500000) scale(1, -1) translate(-3.000000, -2.500000) "
x="2.5" y="0" width="1" height="5"></rect>
<path d="M3.16,2.21333333 L5.76,5.68 C5.82627417,5.76836556 5.80836556,5.89372583 5.72,5.96 C5.68538077,5.98596443 5.64327404,6 5.6,6 L0.4,6 C0.28954305,6 0.2,5.91045695 0.2,5.8 C0.2,5.75672596 0.214035574,5.71461923 0.24,5.68 L2.84,2.21333333 C2.90627417,2.12496777 3.03163444,2.10705916 3.12,2.17333333 C3.13516113,2.18470418 3.14862915,2.1981722 3.16,2.21333333 Z"
id="三角形"
transform="translate(3.000000, 4.000000) scale(1, -1) translate(-3.000000, -4.000000) "></path>
</g>
<g id="编组-5"
transform="translate(12.000000, 4.000000) scale(1, -1) translate(-12.000000, -4.000000) translate(9.000000, 1.000000)"
fill="#{fillColor}">
<rect id="矩形"
transform="translate(3.000000, 2.500000) scale(1, -1) translate(-3.000000, -2.500000) "
x="2.5" y="0" width="1" height="5"></rect>
<path d="M3.16,2.21333333 L5.76,5.68 C5.82627417,5.76836556 5.80836556,5.89372583 5.72,5.96 C5.68538077,5.98596443 5.64327404,6 5.6,6 L0.4,6 C0.28954305,6 0.2,5.91045695 0.2,5.8 C0.2,5.75672596 0.214035574,5.71461923 0.24,5.68 L2.84,2.21333333 C2.90627417,2.12496777 3.03163444,2.10705916 3.12,2.17333333 C3.13516113,2.18470418 3.14862915,2.1981722 3.16,2.21333333 Z"
id="三角形"
transform="translate(3.000000, 4.000000) scale(1, -1) translate(-3.000000, -4.000000) "></path>
</g>
<rect id="矩形" fill="#{fillColor}"
transform="translate(4.500000, 9.500000) scale(1, -1) translate(-4.500000, -9.500000) " x="1"
y="9" width="7" height="1"></rect>
<rect id="矩形备份-3" fill="#{fillColor}" x="1" y="12.5" width="6" height="1"></rect>
<rect id="矩形备份" fill="#{fillColor}"
transform="translate(4.500000, 6.000000) scale(1, -1) translate(-4.500000, -6.000000) " x="1"
y="5.5" width="7" height="1"></rect>
<rect id="矩形备份-2" fill="#{fillColor}"
transform="translate(4.000000, 2.500000) scale(1, -1) translate(-4.000000, -2.500000) " x="1"
y="2" width="6" height="1"></rect>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.3 KiB

165
designer-realize/src/main/java/com/fr/design/sort/header/HeaderSortRulePane.java

@ -1,45 +1,37 @@
package com.fr.design.sort.header; package com.fr.design.sort.header;
import com.fr.base.FineColor;
import com.fr.base.svg.SVGIcon; import com.fr.base.svg.SVGIcon;
import com.fr.base.svg.SVGTranscoder;
import com.fr.design.event.UIObserver; import com.fr.design.event.UIObserver;
import com.fr.design.event.UIObserverListener; import com.fr.design.event.UIObserverListener;
import com.fr.design.gui.icheckbox.UICheckBox; import com.fr.design.gui.icheckbox.UICheckBox;
import com.fr.design.gui.ilable.UILabel; import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.ipoppane.PopupHider;
import com.fr.design.i18n.Toolkit; import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.TableLayoutHelper; import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.mainframe.theme.edit.ui.ColorListPane; import com.fr.design.style.color.ColorControlWindow;
import com.fr.general.IOUtils; import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.log.FineLoggerFactory; import com.fr.report.core.sort.header.HeaderIconBuilder;
import com.fr.report.core.sort.header.SortHeader; import com.fr.report.core.sort.header.SortHeader;
import com.fr.report.core.sort.common.SortRule; import com.fr.report.core.sort.common.SortRule;
import org.apache.batik.transcoder.TranscoderInput;
import javax.swing.*; import javax.swing.*;
import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener; import javax.swing.event.ChangeListener;
import java.awt.*; import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class HeaderSortRulePane extends JPanel { public class HeaderSortRulePane extends JPanel {
private static final String ASC_ICON_TEMPLATE_PATH = "/com/fr/design/images/sort/asc.svg";
private static final String DES_ICON_TEMPLATE_PATH = "/com/fr/design/images/sort/des.svg";
private static final String NOSORT_ICON_TEMPLATE_PATH = "/com/fr/design/images/sort/nosort.svg";
private static final double ICON_SCALE = SVGIcon.SYSTEM_SCALE * 1.25;
private static final int ICON_LENGTH = (int) Math.ceil(16 * ICON_SCALE);
IconButton ascIconButton; IconButton ascIconButton;
IconButton desIconButton; IconButton desIconButton;
IconButton nosortIconButton; IconButton nosortIconButton;
UICheckBox ascUICheckBox; UICheckBox ascUICheckBox;
UICheckBox desUICheckBox; UICheckBox desUICheckBox;
UICheckBox nosortUICheckBox; UICheckBox nosortUICheckBox;
static Map<String, String> originalSvgTextMap = new HashMap<>(); Color defaultColor = new Color(33, 33, 34);
HeaderSortRulePane() { HeaderSortRulePane() {
initComponents(); initComponents();
@ -61,12 +53,12 @@ public class HeaderSortRulePane extends JPanel {
void initSortRuleItem() { void initSortRuleItem() {
Component[][] components = new Component[][]{ Component[][] components = new Component[][]{
new Component[]{ascUICheckBox = new UICheckBox(SortRule.ASC.getDescription()), ascIconButton = new IconButton(ASC_ICON_TEMPLATE_PATH)}, new Component[]{ascUICheckBox = new UICheckBox(SortRule.ASC.getDescription()), ascIconButton = new IconButton(SortRule.ASC)},
new Component[]{desUICheckBox = new UICheckBox(SortRule.DES.getDescription()), desIconButton = new IconButton(DES_ICON_TEMPLATE_PATH)}, new Component[]{desUICheckBox = new UICheckBox(SortRule.DES.getDescription()), desIconButton = new IconButton(SortRule.DES)},
new Component[]{nosortUICheckBox = new UICheckBox(SortRule.NO_SORT.getDescription()), nosortIconButton = new IconButton(NOSORT_ICON_TEMPLATE_PATH)}, new Component[]{nosortUICheckBox = new UICheckBox(SortRule.NO_SORT.getDescription()), nosortIconButton = new IconButton(SortRule.NO_SORT)},
}; };
double[] rowSize = {ICON_LENGTH + 10, ICON_LENGTH + 10, ICON_LENGTH + 10}; double[] rowSize = {HeaderIconBuilder.ICON_LENGTH + 10, HeaderIconBuilder.ICON_LENGTH + 10, HeaderIconBuilder.ICON_LENGTH + 10};
double[] columnSize = {80, ICON_LENGTH + 10}; double[] columnSize = {80, HeaderIconBuilder.ICON_LENGTH + 10};
JPanel sortRuleItem = TableLayoutHelper.createCommonTableLayoutPane(components, rowSize, columnSize, 0); JPanel sortRuleItem = TableLayoutHelper.createCommonTableLayoutPane(components, rowSize, columnSize, 0);
this.add(sortRuleItem, BorderLayout.CENTER); this.add(sortRuleItem, BorderLayout.CENTER);
initUICheckBoxChange(ascUICheckBox, ascIconButton); initUICheckBoxChange(ascUICheckBox, ascIconButton);
@ -87,24 +79,23 @@ public class HeaderSortRulePane extends JPanel {
ascUICheckBox.setSelected(selected); ascUICheckBox.setSelected(selected);
desUICheckBox.setSelected(selected); desUICheckBox.setSelected(selected);
nosortUICheckBox.setSelected(selected); nosortUICheckBox.setSelected(selected);
ascIconButton.refreshIconLabelColor(new Color(33, 33, 34)); ascIconButton.refreshIconLabelColor(new FineColor(defaultColor));
desIconButton.refreshIconLabelColor(new Color(33, 33, 34)); desIconButton.refreshIconLabelColor(new FineColor(defaultColor));
nosortIconButton.refreshIconLabelColor(new Color(33, 33, 34)); nosortIconButton.refreshIconLabelColor(new FineColor(defaultColor));
} }
class IconButton extends JPanel implements UIObserver { class IconButton extends JPanel implements UIObserver, PopupHider {
SortRule sortRule;
JLayeredPane jLayeredPane; JLayeredPane jLayeredPane;
String iconTemplatePath;
UILabel iconLabel; UILabel iconLabel;
ColorListPane.ColorButton colorButton; FineColor fineColor = new FineColor(defaultColor);
Color color;
BufferedImage bufferedImage;
UIObserverListener uiObserverListener; UIObserverListener uiObserverListener;
boolean activeState; boolean activeState;
UILabel borderUiLabel; UILabel borderUiLabel;
private ColorControlWindow colorSelector;
IconButton(String iconTemplatePath) { IconButton(SortRule sortRule) {
this.iconTemplatePath = iconTemplatePath; this.sortRule = sortRule;
initComponents(); initComponents();
} }
@ -115,48 +106,47 @@ public class HeaderSortRulePane extends JPanel {
public void setActiveState(boolean activeState) { public void setActiveState(boolean activeState) {
if (activeState) { if (activeState) {
borderUiLabel.setBorder(BorderFactory.createLineBorder(Color.gray, 1)); borderUiLabel.setBorder(BorderFactory.createLineBorder(Color.gray, 1));
colorButton.setVisible(true);
} else { } else {
borderUiLabel.setBorder(null); borderUiLabel.setBorder(null);
colorButton.setVisible(false);
} }
this.activeState = activeState; this.activeState = activeState;
} }
void initComponents() { void initComponents() {
jLayeredPane = new JLayeredPane(); jLayeredPane = new JLayeredPane();
iconLabel = getIconLabel(iconTemplatePath); iconLabel = getIconLabel();
borderUiLabel = new UILabel(); borderUiLabel = new UILabel();
borderUiLabel.setSize(ICON_LENGTH, ICON_LENGTH); borderUiLabel.setSize(HeaderIconBuilder.ICON_LENGTH, HeaderIconBuilder.ICON_LENGTH);
borderUiLabel.setOpaque(true); borderUiLabel.setOpaque(true);
borderUiLabel.setBackground(Color.WHITE); borderUiLabel.setBackground(Color.WHITE);
iconLabel.setSize(ICON_LENGTH, ICON_LENGTH); iconLabel.setSize(HeaderIconBuilder.ICON_LENGTH, HeaderIconBuilder.ICON_LENGTH);
colorButton = new ColorListPane.ColorButton(Color.CYAN); iconLabel.addMouseListener(new MouseAdapter() {
colorButton.setSize(ICON_LENGTH, ICON_LENGTH);
colorButton.addChangeListener(new ChangeListener() {
@Override @Override
public void stateChanged(ChangeEvent e) { public void mouseClicked(MouseEvent e) {
color = colorButton.getSelectObject(); if (activeState) {
refreshIconLabelColor(color); showPopupMenu();
uiObserverListener.doChange(); }
} }
}); });
jLayeredPane.setPreferredSize(new Dimension(ICON_LENGTH, ICON_LENGTH)); jLayeredPane.setPreferredSize(new Dimension(HeaderIconBuilder.ICON_LENGTH, HeaderIconBuilder.ICON_LENGTH));
jLayeredPane.add(iconLabel, JLayeredPane.POPUP_LAYER); jLayeredPane.add(iconLabel, JLayeredPane.POPUP_LAYER);
jLayeredPane.add(borderUiLabel, JLayeredPane.MODAL_LAYER); jLayeredPane.add(borderUiLabel, JLayeredPane.MODAL_LAYER);
jLayeredPane.add(colorButton, JLayeredPane.PALETTE_LAYER);
this.add(jLayeredPane); this.add(jLayeredPane);
} }
void refreshIconLabelColor(Color color) { void refreshIconLabelColor(FineColor fineColor) {
Icon icon = getIcon(iconTemplatePath, color); Icon icon = getIcon(fineColor);
refreshIconLabel(icon); refreshIconLabel(icon);
} }
Icon getIcon(FineColor fineColor) {
BufferedImage bufferedImage = HeaderIconBuilder.getIcon(sortRule, fineColor);
Icon icon = new ImageIcon(bufferedImage);
return icon;
}
void refreshIconLabel(BufferedImage bufferedImage) { void refreshIconLabel(BufferedImage bufferedImage) {
if (bufferedImage != null) { if (bufferedImage != null) {
this.bufferedImage = bufferedImage;
Icon icon = new SVGIcon(bufferedImage); Icon icon = new SVGIcon(bufferedImage);
refreshIconLabel(icon); refreshIconLabel(icon);
} }
@ -170,64 +160,46 @@ public class HeaderSortRulePane extends JPanel {
} }
} }
UILabel getIconLabel(String iconPath) { UILabel getIconLabel() {
return getIconLabel(iconPath, new Color(33, 33, 34)); return getIconLabel(new FineColor(defaultColor));
} }
UILabel getIconLabel(String iconPath, Color color) { UILabel getIconLabel(FineColor fineColor) {
Icon svgIcon = getIcon(iconPath, color); Icon svgIcon = getIcon(fineColor);
return new UILabel(svgIcon); return new UILabel(svgIcon);
} }
Icon getIcon(String iconPath, Color color) { private void showPopupMenu() {
try { hidePopupMenu();
String originalSvgText = getOriginalSvgText(iconPath); colorSelector = this.getColorSelector();
String svgText = originalSvgText.replaceAll("\\{fillColor\\}", shiftColor(color)); GUICoreUtils.showPopupMenu(colorSelector, this, 0, this.getSize().height);
InputStream svgInputStream = new ByteArrayInputStream(svgText.getBytes(StandardCharsets.UTF_8));
TranscoderInput input = new TranscoderInput(svgInputStream);
bufferedImage = SVGTranscoder.createImage(ICON_SCALE, input).getImage();
SVGIcon svgIcon = new SVGIcon(bufferedImage);
return svgIcon;
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e, e.getMessage());
}
return null;
} }
String getOriginalSvgText(String iconPath) throws Exception { @Override
String originalSvgText = originalSvgTextMap.get(iconPath); public void hidePopupMenu() {
if (originalSvgText == null) { if (colorSelector != null) {
InputStream inputStream = IOUtils.getResourceAsStream(iconPath, HeaderSortRulePane.class); colorSelector.setVisible(false);
originalSvgText = getSvgText(inputStream);
originalSvgTextMap.put(iconPath, originalSvgText);
} }
return originalSvgText; colorSelector = null;
} }
String shiftColor(Color color) { private ColorControlWindow getColorSelector() {
StringBuilder stringBuilder = new StringBuilder(); return new ColorControlWindow(false, IconButton.this) {
stringBuilder.append(shiftValue(color.getRed())); @Override
stringBuilder.append(shiftValue(color.getGreen())); protected void colorChanged() {
stringBuilder.append(shiftValue(color.getBlue())); Color color = this.getColor();
return stringBuilder.toString(); if (color instanceof FineColor) {
fineColor = (FineColor) color;
} else {
fineColor = new FineColor(color);
} }
refreshIconLabelColor(fineColor);
String shiftValue(int value) { hidePopupMenu();
String resultValue = Integer.toHexString(value); uiObserverListener.doChange();
if (resultValue.length() == 1) {
resultValue = "0" + resultValue;
} }
return resultValue; };
} }
private String getSvgText(InputStream inputStream) throws Exception {
StringBuffer stringBuffer = new StringBuffer();
byte[] b = new byte[1024];
for (int n; (n = inputStream.read(b)) != -1; ) {
stringBuffer.append(new String(b, 0, n));
}
return stringBuffer.toString();
}
@Override @Override
public void registerChangeListener(UIObserverListener uiObserverListener) { public void registerChangeListener(UIObserverListener uiObserverListener) {
@ -256,7 +228,6 @@ public class HeaderSortRulePane extends JPanel {
nosortIconButton.refreshIconLabel(bufferedImage); nosortIconButton.refreshIconLabel(bufferedImage);
nosortUICheckBox.setSelected(true); nosortUICheckBox.setSelected(true);
} }
} }
} }
} }
@ -264,13 +235,13 @@ public class HeaderSortRulePane extends JPanel {
public SortHeader.SortItem[] updateBean() { public SortHeader.SortItem[] updateBean() {
java.util.List<SortHeader.SortItem> items = new ArrayList<>(); java.util.List<SortHeader.SortItem> items = new ArrayList<>();
if (ascUICheckBox.isSelected()) { if (ascUICheckBox.isSelected()) {
items.add(new SortHeader.SortItem(SortRule.ASC, ascIconButton.bufferedImage)); items.add(new SortHeader.SortItem(SortRule.ASC, ascIconButton.fineColor));
} }
if (desUICheckBox.isSelected()) { if (desUICheckBox.isSelected()) {
items.add(new SortHeader.SortItem(SortRule.DES, desIconButton.bufferedImage)); items.add(new SortHeader.SortItem(SortRule.DES, desIconButton.fineColor));
} }
if (nosortUICheckBox.isSelected()) { if (nosortUICheckBox.isSelected()) {
items.add(new SortHeader.SortItem(SortRule.NO_SORT, nosortIconButton.bufferedImage)); items.add(new SortHeader.SortItem(SortRule.NO_SORT, nosortIconButton.fineColor));
} }
SortHeader.SortItem[] resultItems = new SortHeader.SortItem[items.size()]; SortHeader.SortItem[] resultItems = new SortHeader.SortItem[items.size()];
return items.toArray(resultItems); return items.toArray(resultItems);

Loading…
Cancel
Save