Browse Source

REPORT-99485 修复白化图标高DPI下显示不正确的问题

newui
jinsihou 11 months ago
parent
commit
397ba58db7
  1. 49
      designer-base/src/main/java/com/fine/theme/icon/IconManager.java
  2. 23
      designer-base/src/main/java/com/fine/theme/icon/IconType.java
  3. 29
      designer-base/src/main/java/com/fine/theme/icon/LazyIcon.java
  4. 53
      designer-base/src/main/java/com/fine/theme/icon/svg/SvgIcon.java
  5. 6
      designer-base/src/main/java/com/fine/theme/light/ui/FineLightIconSet.java
  6. 23
      designer-base/src/test/java/com/fr/design/gui/storybook/components/ButtonGroupStoryBoard.java

49
designer-base/src/main/java/com/fine/theme/icon/IconManager.java

@ -23,11 +23,11 @@ import java.util.HashMap;
@Immutable
public class IconManager {
public static boolean initialized = false;
public static ArrayList<IconSet> iconSets = new ArrayList<>(2);
public static HashMap<String, WeakReference<Icon>> cache = new HashMap<>(64);
public static HashMap<String, WeakReference<Icon>> disableCache = new HashMap<>(64);
public static HashMap<String, WeakReference<Icon>> whiteCache = new HashMap<>(32);
private static final ArrayList<IconSet> ICON_SETS = new ArrayList<>(2);
private static final HashMap<String, WeakReference<Icon>> CACHE = new HashMap<>(64);
private static final HashMap<String, WeakReference<Icon>> DISABLE_CACHE = new HashMap<>(64);
private static final HashMap<String, WeakReference<Icon>> WHITE_CACHE = new HashMap<>(32);
/**
@ -37,7 +37,7 @@ public class IconManager {
* @return 图标集
*/
public static IconSet getSet(String id) {
for (IconSet set : iconSets) {
for (IconSet set : ICON_SETS) {
if (set.getId().equals(id)) {
return set;
}
@ -51,8 +51,8 @@ public class IconManager {
* @param set 图标集
*/
public static void addSet(@NotNull IconSet set) {
if (!iconSets.contains(set)) {
iconSets.add(set);
if (!ICON_SETS.contains(set)) {
ICON_SETS.add(set);
// 清理可能来自其他图集相同名称图标
clearIconSetCache(set);
} else {
@ -85,14 +85,14 @@ public class IconManager {
*/
@NotNull
public static <I extends Icon> I getWhiteIcon(String id) {
final WeakReference<Icon> reference = whiteCache.get(id);
final WeakReference<Icon> reference = WHITE_CACHE.get(id);
I icon = reference != null ? (I) reference.get() : null;
if (icon == null) {
for (IconSet set : iconSets) {
for (IconSet set : ICON_SETS) {
Icon f = set.findWhiteIcon(id);
if (f != null) {
icon = (I) f;
whiteCache.put(id, new WeakReference<>(icon));
WHITE_CACHE.put(id, new WeakReference<>(icon));
}
}
}
@ -120,14 +120,14 @@ public class IconManager {
@Nullable
private static <I extends Icon> I findDisableIcon(String id) {
final WeakReference<Icon> reference = disableCache.get(id);
final WeakReference<Icon> reference = DISABLE_CACHE.get(id);
I icon = reference != null ? (I) reference.get() : null;
if (icon == null) {
for (IconSet set : iconSets) {
for (IconSet set : ICON_SETS) {
Icon f = set.findDisableIcon(id);
if (f != null) {
icon = (I) f;
disableCache.put(id, new WeakReference<>(icon));
DISABLE_CACHE.put(id, new WeakReference<>(icon));
}
}
}
@ -136,14 +136,14 @@ public class IconManager {
@Nullable
private static <I extends Icon> I findIcon(String id) {
final WeakReference<Icon> reference = cache.get(id);
final WeakReference<Icon> reference = CACHE.get(id);
I icon = reference != null ? (I) reference.get() : null;
if (icon == null) {
for (IconSet set : iconSets) {
for (IconSet set : ICON_SETS) {
Icon f = set.findIcon(id);
if (f != null) {
icon = (I) f;
cache.put(id, new WeakReference<>(icon));
CACHE.put(id, new WeakReference<>(icon));
}
}
}
@ -154,22 +154,25 @@ public class IconManager {
* 清理所有缓存
*/
public static void clearCache() {
cache.clear();
disableCache.clear();
CACHE.clear();
DISABLE_CACHE.clear();
WHITE_CACHE.clear();
}
/**
* 清理图标缓存
*/
public static void clearIconCache(String id) {
cache.remove(id);
disableCache.remove(id);
CACHE.remove(id);
DISABLE_CACHE.remove(id);
WHITE_CACHE.clear();
}
private static void clearIconSetCache(@NotNull IconSet set) {
for (String id : set.getIds()) {
cache.remove(id);
disableCache.remove(id);
CACHE.remove(id);
DISABLE_CACHE.remove(id);
WHITE_CACHE.remove(id);
}
}
}

23
designer-base/src/main/java/com/fine/theme/icon/IconType.java

@ -0,0 +1,23 @@
package com.fine.theme.icon;
/**
* 图标类型
*
* @author vito
* @since 11.0
* Created on 2024/01/09
*/
public enum IconType {
/**
* 灰化图
*/
disable,
/**
* 白化图用于反白场景
*/
white,
/**
* 原始图
*/
normal
}

29
designer-base/src/main/java/com/fine/theme/icon/LazyIcon.java

@ -6,6 +6,7 @@ import org.jetbrains.annotations.NotNull;
import javax.swing.Icon;
import java.awt.Component;
import java.awt.Graphics;
import java.util.StringJoiner;
/**
* 懒加载图标
@ -19,8 +20,16 @@ public class LazyIcon implements Identifiable, DisabledIcon, WhiteIcon, Icon {
@NotNull
private final String id;
private final IconType type;
public LazyIcon(@NotNull final String id) {
this.id = id;
this.type = IconType.normal;
}
private LazyIcon(@NotNull final String id, IconType type) {
this.id = id;
this.type = type;
}
@ -48,7 +57,14 @@ public class LazyIcon implements Identifiable, DisabledIcon, WhiteIcon, Icon {
@NotNull
public <I extends Icon> I getIcon() {
return IconManager.getIcon(getId());
switch (type) {
case white:
return IconManager.getWhiteIcon(getId());
case disable:
return IconManager.getDisableIcon(getId());
default:
return IconManager.getIcon(getId());
}
}
/**
@ -59,7 +75,7 @@ public class LazyIcon implements Identifiable, DisabledIcon, WhiteIcon, Icon {
@NotNull
@Override
public Icon disabled() {
return IconManager.getDisableIcon(getId());
return new LazyIcon(getId(), IconType.disable);
}
/**
@ -70,14 +86,15 @@ public class LazyIcon implements Identifiable, DisabledIcon, WhiteIcon, Icon {
@NotNull
@Override
public Icon white() {
return IconManager.getWhiteIcon(getId());
return new LazyIcon(getId(), IconType.white);
}
@NotNull
@Override
public String toString() {
return getClass().getCanonicalName() + "[id=" + getId() + "]";
return new StringJoiner(", ", LazyIcon.class.getSimpleName() + "[", "]")
.add("id='" + id + "'")
.add("type=" + type)
.toString();
}
}

53
designer-base/src/main/java/com/fine/theme/icon/svg/SvgIcon.java

@ -3,6 +3,7 @@ package com.fine.theme.icon.svg;
import com.fine.theme.icon.DisabledIcon;
import com.fine.theme.icon.GraphicsFilter;
import com.fine.theme.icon.IconResource;
import com.fine.theme.icon.IconType;
import com.fine.theme.icon.WhiteIcon;
import com.formdev.flatlaf.FlatLaf;
import com.formdev.flatlaf.ui.FlatUIUtils;
@ -42,41 +43,28 @@ import static com.fine.theme.utils.FineUIScale.scale;
@Immutable
public class SvgIcon implements DisabledIcon, WhiteIcon, Icon {
public enum Type {
/**
* 灰化图
*/
disable,
/**
* 白化图用于反白场景
*/
white,
/**
* 原始效果图
*/
origin
}
private final Dimension size;
private final Dimension scaleSize;
private final IconResource resource;
private final Type type;
private final IconType type;
private final NullableLazyValue<SVGDocument> svgDocument = NullableLazyValue.createValue(() -> load(Type.origin));
private final NullableLazyValue<SVGDocument> whiteSvgDocument = NullableLazyValue.createValue(() -> load(Type.white));
private final NullableLazyValue<SVGDocument> svgDocument = NullableLazyValue.createValue(() -> load(IconType.normal));
private final NullableLazyValue<SVGDocument> whiteSvgDocument = NullableLazyValue.createValue(() -> load(IconType.white));
public SvgIcon(IconResource resource, Dimension size) {
this(resource, size, Type.origin);
this(resource, size, IconType.normal);
}
public SvgIcon(IconResource resource, Dimension size, Type type) {
public SvgIcon(IconResource resource, Dimension size, IconType type) {
this.resource = resource;
this.size = size;
// 根据dpi进行缩放
this.size = scale(size);
this.scaleSize = scale(size);
this.type = type;
}
public SvgIcon(IconResource resource, int side) {
this(resource, new Dimension(side, side), Type.origin);
this(resource, new Dimension(side, side), IconType.normal);
}
/**
@ -85,7 +73,7 @@ public class SvgIcon implements DisabledIcon, WhiteIcon, Icon {
*/
@Override
public void paintIcon(Component c, Graphics g, int x, int y) {
if (type == Type.disable) {
if (type == IconType.disable) {
g = grayGraphics(g);
}
Object[] oldRenderingHints = FlatUIUtils.setRenderingHints(g);
@ -104,22 +92,22 @@ public class SvgIcon implements DisabledIcon, WhiteIcon, Icon {
@Override
public int getIconWidth() {
return size.width;
return scaleSize.width;
}
@Override
public int getIconHeight() {
return size.height;
return scaleSize.height;
}
private void render(Component c, Graphics g, int x, int y) {
try {
if (type == Type.white) {
if (type == IconType.white) {
Objects.requireNonNull(whiteSvgDocument.getValue())
.render((JComponent) c, (Graphics2D) g, new ViewBox(x, y, size.width, size.height));
.render((JComponent) c, (Graphics2D) g, new ViewBox(x, y, scaleSize.width, scaleSize.height));
} else {
Objects.requireNonNull(svgDocument.getValue())
.render((JComponent) c, (Graphics2D) g, new ViewBox(x, y, size.width, size.height));
.render((JComponent) c, (Graphics2D) g, new ViewBox(x, y, scaleSize.width, scaleSize.height));
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error("SvgIcon from url: " + resource + "can not paint.", e);
@ -127,9 +115,9 @@ public class SvgIcon implements DisabledIcon, WhiteIcon, Icon {
}
private SVGDocument load(Type type) {
private SVGDocument load(IconType type) {
SVGLoader loader = new SVGLoader();
return type == Type.white
return type == IconType.white
? loader.load(resource.getInputStream(), new WhiteParser())
: loader.load(resource.getInputStream());
}
@ -141,6 +129,7 @@ public class SvgIcon implements DisabledIcon, WhiteIcon, Icon {
.add("resource=" + resource)
.add("type=" + type)
.add("size=" + size)
.add("scaleSize=" + scaleSize)
.toString();
}
@ -149,7 +138,7 @@ public class SvgIcon implements DisabledIcon, WhiteIcon, Icon {
*/
@Override
public @NotNull SvgIcon white() {
return new SvgIcon(resource, size, Type.white);
return new SvgIcon(resource, size, IconType.white);
}
@ -158,6 +147,6 @@ public class SvgIcon implements DisabledIcon, WhiteIcon, Icon {
*/
@Override
public @NotNull SvgIcon disabled() {
return new SvgIcon(resource, size, Type.disable);
return new SvgIcon(resource, size, IconType.disable);
}
}

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

@ -45,9 +45,9 @@ public class FineLightIconSet extends AbstractIconSet {
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),
new SvgIconSource("file", "com/fine/theme/icon/dataset/file.svg", true),
new SvgIconSource("tree", "com/fine/theme/icon/dataset/tree.svg", true),
new SvgIconSource("multi", "com/fine/theme/icon/dataset/multi.svg"),
new SvgIconSource("file", "com/fine/theme/icon/dataset/file.svg"),
new SvgIconSource("tree", "com/fine/theme/icon/dataset/tree.svg"),
new SvgIconSource("store_procedure", "com/fine/theme/icon/dataset/store_procedure.svg", true),
new SvgIconSource("batch_esd_on", "com/fine/theme/icon/dataset/batch_esd_on.svg", true),
new SvgIconSource("batch_esd_off", "com/fine/theme/icon/dataset/batch_esd_off.svg", true),

23
designer-base/src/test/java/com/fr/design/gui/storybook/components/ButtonGroupStoryBoard.java

@ -8,6 +8,7 @@ import com.fr.design.gui.itoolbar.UIToolbar;
import com.fr.design.gui.storybook.Story;
import com.fr.design.gui.storybook.StoryBoard;
import com.fr.stable.ArrayUtils;
import com.fr.value.NotNullLazyValue;
import javax.swing.Icon;
import java.awt.Component;
@ -49,6 +50,17 @@ public class ButtonGroupStoryBoard extends StoryBoard {
);
}
private static final NotNullLazyValue<Icon[]> iconArray = NotNullLazyValue.createValue(() -> ArrayUtils.toArray(
new LazyIcon("edit"),
new LazyIcon("preview"),
new LazyIcon("connection")
));
private static final NotNullLazyValue<Icon[][]> iconArrayWithWhite = NotNullLazyValue.createValue(() -> ArrayUtils.toArray(
ArrayUtils.toArray(new LazyIcon("edit"), new LazyIcon("copy")),
ArrayUtils.toArray(new LazyIcon("preview"), new LazyIcon("save"))
));
private static Component getToolbar(){
UIToolbar toolbar = new UIToolbar();
UIButtonGroup<Object> objectUIButtonGroup = new UIButtonGroup<>(iconArrayWithWhite(),null,true);
@ -58,18 +70,11 @@ public class ButtonGroupStoryBoard extends StoryBoard {
}
private static Icon[] iconArray() {
return ArrayUtils.toArray(
new LazyIcon("edit"),
new LazyIcon("preview"),
new LazyIcon("connection")
);
return iconArray.getValue();
}
private static Icon[][] iconArrayWithWhite() {
return ArrayUtils.toArray(
ArrayUtils.toArray(new LazyIcon("edit"), new LazyIcon("copy")),
ArrayUtils.toArray(new LazyIcon("preview"), new LazyIcon("save"))
);
return iconArrayWithWhite.getValue();
}
private String[] fiveTextArray() {

Loading…
Cancel
Save