Browse Source

Fixed merge conflict

newui
vito-刘恒霖 9 months ago
parent
commit
a90d60b758
  1. 10
      build.gradle
  2. 12
      designer-base/build.base.gradle
  3. 88
      designer-base/src/main/java/com/fine/theme/icon/AbstractIconSet.java
  4. 106
      designer-base/src/main/java/com/fine/theme/icon/AbstractIconSource.java
  5. 23
      designer-base/src/main/java/com/fine/theme/icon/DisabledIcon.java
  6. 59
      designer-base/src/main/java/com/fine/theme/icon/GraphicsFilter.java
  7. 29
      designer-base/src/main/java/com/fine/theme/icon/IconException.java
  8. 175
      designer-base/src/main/java/com/fine/theme/icon/IconManager.java
  9. 23
      designer-base/src/main/java/com/fine/theme/icon/IconResource.java
  10. 71
      designer-base/src/main/java/com/fine/theme/icon/IconSet.java
  11. 36
      designer-base/src/main/java/com/fine/theme/icon/IconSource.java
  12. 12
      designer-base/src/main/java/com/fine/theme/icon/Identifiable.java
  13. 83
      designer-base/src/main/java/com/fine/theme/icon/LazyIcon.java
  14. 53
      designer-base/src/main/java/com/fine/theme/icon/UrlIconResource.java
  15. 22
      designer-base/src/main/java/com/fine/theme/icon/WhiteIcon.java
  16. 75
      designer-base/src/main/java/com/fine/theme/icon/icons/AnimatedRadioButtonIcon.java
  17. 163
      designer-base/src/main/java/com/fine/theme/icon/svg/SvgIcon.java
  18. 80
      designer-base/src/main/java/com/fine/theme/icon/svg/SvgIconSource.java
  19. 65
      designer-base/src/main/java/com/fine/theme/icon/svg/SvgTranscoder.java
  20. 50
      designer-base/src/main/java/com/fine/theme/icon/svg/WhiteParser.java
  21. 42
      designer-base/src/main/java/com/fine/theme/light/ui/FineButtonBorder.java
  22. 42
      designer-base/src/main/java/com/fine/theme/light/ui/FineButtonGroupUI.java
  23. 114
      designer-base/src/main/java/com/fine/theme/light/ui/FineButtonUI.java
  24. 37
      designer-base/src/main/java/com/fine/theme/light/ui/FineCheckBoxUI.java
  25. 66
      designer-base/src/main/java/com/fine/theme/light/ui/FineColorButtonUI.java
  26. 90
      designer-base/src/main/java/com/fine/theme/light/ui/FineCombinationButtonUI.java
  27. 41
      designer-base/src/main/java/com/fine/theme/light/ui/FineComboBoxUI.java
  28. 309
      designer-base/src/main/java/com/fine/theme/light/ui/FineGradientBarUI.java
  29. 74
      designer-base/src/main/java/com/fine/theme/light/ui/FineHeadGroupUI.java
  30. 123
      designer-base/src/main/java/com/fine/theme/light/ui/FineInputUI.java
  31. 249
      designer-base/src/main/java/com/fine/theme/light/ui/FineLightIconSet.java
  32. 41
      designer-base/src/main/java/com/fine/theme/light/ui/FineMenuItemUI.java
  33. 40
      designer-base/src/main/java/com/fine/theme/light/ui/FineMenuUI.java
  34. 19
      designer-base/src/main/java/com/fine/theme/light/ui/FinePopupMenuBorder.java
  35. 70
      designer-base/src/main/java/com/fine/theme/light/ui/FinePopupMenuSeparatorUI.java
  36. 58
      designer-base/src/main/java/com/fine/theme/light/ui/FinePopupMenuUI.java
  37. 28
      designer-base/src/main/java/com/fine/theme/light/ui/FineReportComponentBorder.java
  38. 40
      designer-base/src/main/java/com/fine/theme/light/ui/FineReportComponentCompositeUI.java
  39. 63
      designer-base/src/main/java/com/fine/theme/light/ui/FineRoundBorder.java
  40. 49
      designer-base/src/main/java/com/fine/theme/light/ui/FineSelectBoxUI.java
  41. 344
      designer-base/src/main/java/com/fine/theme/light/ui/FineSliderUI.java
  42. 393
      designer-base/src/main/java/com/fine/theme/light/ui/FineTemplateTabPaneUI.java
  43. 213
      designer-base/src/main/java/com/fine/theme/light/ui/FineToggleButtonUI.java
  44. 102
      designer-base/src/main/java/com/fine/theme/light/ui/FineTooltipUI.java
  45. 39
      designer-base/src/main/java/com/fine/theme/light/ui/RectangleButtonUI.java
  46. 92
      designer-base/src/main/java/com/fine/theme/light/ui/ReportScrollBarUI.java
  47. 32
      designer-base/src/main/java/com/fine/theme/light/ui/UIFlatTreeUI.java
  48. 52
      designer-base/src/main/java/com/fine/theme/light/ui/laf/FineDarkLaf.java
  49. 38
      designer-base/src/main/java/com/fine/theme/light/ui/laf/FineLaf.java
  50. 52
      designer-base/src/main/java/com/fine/theme/light/ui/laf/FineLightLaf.java
  51. 35
      designer-base/src/main/java/com/fine/theme/utils/FineClientProperties.java
  52. 86
      designer-base/src/main/java/com/fine/theme/utils/FineUIScale.java
  53. 101
      designer-base/src/main/java/com/fine/theme/utils/FineUIStyle.java
  54. 367
      designer-base/src/main/java/com/fine/theme/utils/FineUIUtils.java
  55. 8
      designer-base/src/main/java/com/fr/design/actions/UpdateAction.java
  56. 22
      designer-base/src/main/java/com/fr/design/actions/core/ActionFactory.java
  57. 3
      designer-base/src/main/java/com/fr/design/actions/edit/CopyAction.java
  58. 4
      designer-base/src/main/java/com/fr/design/actions/edit/CutAction.java
  59. 3
      designer-base/src/main/java/com/fr/design/actions/edit/PasteAction.java
  60. 3
      designer-base/src/main/java/com/fr/design/actions/file/DelFileAction.java
  61. 3
      designer-base/src/main/java/com/fr/design/actions/file/LocateAction.java
  62. 3
      designer-base/src/main/java/com/fr/design/actions/file/RenameAction.java
  63. 8
      designer-base/src/main/java/com/fr/design/actions/help/alphafine/component/CustomSortPane.java
  64. 5
      designer-base/src/main/java/com/fr/design/actions/server/ProcedureListAction.java
  65. 10
      designer-base/src/main/java/com/fr/design/constants/LayoutConstants.java
  66. 6
      designer-base/src/main/java/com/fr/design/data/BasicTableDataTreePane.java
  67. 48
      designer-base/src/main/java/com/fr/design/data/datapane/TableDataCreatorProducer.java
  68. 35
      designer-base/src/main/java/com/fr/design/data/datapane/TableDataNameObjectCreator.java
  69. 15
      designer-base/src/main/java/com/fr/design/data/datapane/TableDataTree.java
  70. 32
      designer-base/src/main/java/com/fr/design/data/datapane/TableDataTreePane.java
  71. 45
      designer-base/src/main/java/com/fr/design/data/datapane/VerticalChoosePane.java
  72. 4
      designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionTableProcedurePane.java
  73. 140
      designer-base/src/main/java/com/fr/design/data/datapane/management/search/pane/FineSearchPane.java
  74. 2
      designer-base/src/main/java/com/fr/design/data/datapane/management/search/pane/TableDataSearchRemindPane.java
  75. 95
      designer-base/src/main/java/com/fr/design/data/datapane/management/search/pane/TreeSearchToolbarPane.java
  76. 5
      designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/ProcedureListPane.java
  77. 8
      designer-base/src/main/java/com/fr/design/data/tabledata/wrapper/MultiResultTableDataWrapperHelper.java
  78. 19
      designer-base/src/main/java/com/fr/design/data/tabledata/wrapper/ServerTableDataWrapper.java
  79. 4
      designer-base/src/main/java/com/fr/design/data/tabledata/wrapper/StoreProcedureDataWrapper.java
  80. 4
      designer-base/src/main/java/com/fr/design/data/tabledata/wrapper/StoreProcedureNameWrapper.java
  81. 37
      designer-base/src/main/java/com/fr/design/data/tabledata/wrapper/TableDataFactory.java
  82. 9
      designer-base/src/main/java/com/fr/design/data/tabledata/wrapper/TemplateTableDataWrapper.java
  83. 2
      designer-base/src/main/java/com/fr/design/dialog/MultiTabPane.java
  84. 11
      designer-base/src/main/java/com/fr/design/dialog/UIDialog.java
  85. 47
      designer-base/src/main/java/com/fr/design/editor/DoubleDeckValueEditorPane.java
  86. 2
      designer-base/src/main/java/com/fr/design/editor/editor/ColumnIndexEditor.java
  87. 2
      designer-base/src/main/java/com/fr/design/editor/editor/TextEditor.java
  88. 13
      designer-base/src/main/java/com/fr/design/event/HoverAware.java
  89. 25
      designer-base/src/main/java/com/fr/design/extra/exe/callback/ModifyStatusCallback.java
  90. 47
      designer-base/src/main/java/com/fr/design/extra/exe/callback/UninstallPluginCallback.java
  91. 7
      designer-base/src/main/java/com/fr/design/file/DefaultTemplateTreeDefineProcessor.java
  92. 731
      designer-base/src/main/java/com/fr/design/file/MultiTemplateTabPane.java
  93. 173
      designer-base/src/main/java/com/fr/design/file/NewTemplatePane.java
  94. 91
      designer-base/src/main/java/com/fr/design/foldablepane/HeaderPane.java
  95. 8
      designer-base/src/main/java/com/fr/design/foldablepane/UIExpandablePane.java
  96. 191
      designer-base/src/main/java/com/fr/design/formula/FormulaPane.java
  97. 4
      designer-base/src/main/java/com/fr/design/formula/FormulaPaneWhenReserveFormula.java
  98. 22
      designer-base/src/main/java/com/fr/design/formula/TinyFormulaPane.java
  99. 30
      designer-base/src/main/java/com/fr/design/gui/UILookAndFeel.java
  100. 43
      designer-base/src/main/java/com/fr/design/gui/controlpane/AbstractNameableCreator.java
  101. Some files were not shown because too many files have changed in this diff Show More

10
build.gradle

@ -73,8 +73,8 @@ allprojects {
implementation 'org.swingexplorer:swexpl:2.0.1'
implementation 'org.swingexplorer:swag:1.0'
implementation 'net.java.dev.jna:jna:5.4.0'
implementation 'org.apache.tomcat:tomcat-catalina:8.5.72'
implementation 'org.apache.tomcat:tomcat-websocket:8.5.72'
implementation 'org.apache.tomcat:tomcat-catalina:8.5.93'
implementation 'org.apache.tomcat:tomcat-websocket:8.5.93'
implementation 'io.socket:socket.io-client:0.7.0'
implementation 'com.fr.third:fine-third:' + frVersion
implementation 'com.fr.core:fine-core:' + frDevVersion
@ -87,6 +87,11 @@ allprojects {
implementation 'com.fr.report:engine-chart:' + frDevVersion
implementation 'com.fr.report:engine-i18n:' + frDevVersion
implementation 'com.fr.design:design-i18n:' + frDevVersion
implementation 'com.formdev:flatlaf:3.2'
implementation 'com.formdev:flatlaf-extras:3.2.1'
implementation 'com.github.weisj:jsvg:1.2.0'
implementation 'com.fanruan.vito:gui-inspector:1.0.1'
implementation 'com.fine.swing.ui:layout:1.0-SNAPSHOT'
testImplementation 'org.easymock:easymock:3.5.1'
testImplementation 'org.powermock:powermock-module-junit4:1.7.1'
testImplementation 'org.powermock:powermock-api-easymock:1.7.1'
@ -98,6 +103,7 @@ allprojects {
if (OperatingSystem.current().isMacOsX() && "aarch64".equals(System.getProperty("os.arch"))) {
dependencies {
// jxbrowser 6.23M16.23jar还是需要留着
implementation 'com.fr.third:jxbrowser-mac:6.23'
implementation "com.fr.third:jxbrowser-mac-arm-v7:${jxBrowserVersion}"
}
} else if (OperatingSystem.current().isMacOsX()) {

12
designer-base/build.base.gradle

@ -59,12 +59,12 @@ def branchName=buildDir.substring(buildDir.lastIndexOf ('\\')+1)
//
dependencies{
compile fileTree(dir:"../${baseDir}/lib-other",include:'**/*.jar')
compile fileTree(dir:"../${baseDir}/lib-core",include:'**/*.jar')
compile fileTree(dir:"../${baseDir}/lib-design",include:'**/*.jar')
compile fileTree(dir:"../${baseDir}",include:"**/build/libs/*.jar",exclude:"bi/**/*.jar")
compile group: 'io.socket', name: 'socket.io-client', version: '0.7.0'
testCompile 'junit:junit:4.12'
api fileTree(dir:"../${baseDir}/lib-other",include:'**/*.jar')
api fileTree(dir:"../${baseDir}/lib-core",include:'**/*.jar')
api fileTree(dir:"../${baseDir}/lib-design",include:'**/*.jar')
api fileTree(dir:"../${baseDir}",include:"**/build/libs/*.jar",exclude:"bi/**/*.jar")
api group: 'io.socket', name: 'socket.io-client', version: '0.7.0'
testImplementation 'junit:junit:4.12'
}
//

88
designer-base/src/main/java/com/fine/theme/icon/AbstractIconSet.java

@ -0,0 +1,88 @@
package com.fine.theme.icon;
import com.fr.third.errorprone.annotations.Immutable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.Icon;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* 抽象图标集
*
* @author vito
* @since 11.0
* Created on 2023/11/15
*/
@Immutable
public abstract class AbstractIconSet implements IconSet {
private final String id;
private final Map<String, IconSource<? extends Icon>> map = new ConcurrentHashMap<>(64);
private final Map<String, Icon> cache = new ConcurrentHashMap<>(64);
private final Map<String, Icon> disableCache = new ConcurrentHashMap<>(64);
public AbstractIconSet(String id) {
this.id = id;
}
@Override
public @NotNull String getId() {
return id;
}
@Override
public @NotNull Collection<String> getIds() {
return map.keySet();
}
@Override
public void addIcon(@NotNull IconSource<? extends Icon> icon) {
map.put(icon.getId(), icon);
}
@Override
public void addIcon(@NotNull IconSource<? extends Icon>... icons) {
for (IconSource<? extends Icon> icon : icons) {
map.put(icon.getId(), icon);
}
}
@Override
public @Nullable Icon findIcon(@NotNull String id) {
Icon icon = cache.get(id);
if (icon == null) {
IconSource<? extends Icon> iconSource = map.get(id);
if (iconSource != null) {
icon = iconSource.loadIcon();
cache.put(id, icon);
}
}
return icon;
}
@Override
public @Nullable Icon findWhiteIcon(@NotNull String id) {
IconSource<? extends Icon> iconSource = map.get(id);
if (iconSource != null) {
return iconSource.white();
}
return null;
}
@Override
public @Nullable Icon findDisableIcon(@NotNull String id) {
Icon icon = disableCache.get(id);
if (icon == null) {
IconSource<? extends Icon> iconSource = map.get(id);
if (iconSource != null) {
icon = iconSource.disabled();
disableCache.put(id, icon);
}
}
return icon;
}
}

106
designer-base/src/main/java/com/fine/theme/icon/AbstractIconSource.java

@ -0,0 +1,106 @@
package com.fine.theme.icon;
import com.fr.third.errorprone.annotations.Immutable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.Icon;
/**
* 抽象图标源
* 能够根据图标源寻找灰化图标资源
*
* @author vito
* @since 11.0
* Created on 2023/11/14
*/
@Immutable
public abstract class AbstractIconSource<I extends Icon> implements IconSource<I> {
public static final String ICON_DISABLE = "_disable";
protected String id;
protected final IconResource resource;
@Nullable
protected IconResource grayResource;
protected boolean autoFindDisable = false;
public AbstractIconSource(@NotNull final String id, @NotNull final IconResource resource) {
this.id = id;
this.resource = resource;
}
public AbstractIconSource(@NotNull final String id,
@NotNull final IconResource resource,
final boolean autoFindDisable) {
this.id = id;
this.resource = resource;
this.autoFindDisable = autoFindDisable;
}
public AbstractIconSource(@NotNull final String id,
@NotNull final IconResource resource,
@Nullable final IconResource grayResource) {
this.id = id;
this.resource = resource;
this.grayResource = grayResource;
}
@NotNull
@Override
public String getId() {
return id;
}
@NotNull
@Override
public IconResource getResource() {
return resource;
}
@NotNull
@Override
public I loadIcon() {
try {
return loadIcon(resource);
} catch (final Exception e) {
throw new IconException("Unable to load Icon: " + getId(), e);
}
}
@NotNull
protected abstract I loadIcon(@NotNull IconResource resource);
/**
* 先找提供明确URL的灰化图
* 再找指定自动寻找路径的灰化图
* 最后再由具体图标提供默认灰化图
*
* @return 灰化图
*/
@Override
public @NotNull I disabled() {
if (grayResource != null) {
return loadIcon(grayResource);
}
if (autoFindDisable && resource instanceof UrlIconResource) {
String disablePath = findDisablePath(((UrlIconResource) resource).getPath());
grayResource = new UrlIconResource(disablePath);
return loadIcon(grayResource);
}
return loadDisableIcon();
}
private static String findDisablePath(String path) {
int i = path.lastIndexOf('.');
return path.substring(0, i) + ICON_DISABLE + path.substring(i);
}
@NotNull
protected abstract I loadDisableIcon();
}

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

@ -0,0 +1,23 @@
package com.fine.theme.icon;
import org.jetbrains.annotations.NotNull;
import javax.swing.Icon;
/**
* 创建一个灰化 Icon
*
* @author vito
* @since 11.0
* Created on 2023/11/16
*/
public interface DisabledIcon {
/**
* 创建一份灰化图标
*
* @return 灰化图标
*/
@NotNull
Icon disabled();
}

59
designer-base/src/main/java/com/fine/theme/icon/GraphicsFilter.java

@ -0,0 +1,59 @@
package com.fine.theme.icon;
import com.formdev.flatlaf.util.Graphics2DProxy;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.image.RGBImageFilter;
/**
* 颜色过滤器画板
*
* @author vito
* @since 11.0
* Created on 2023/11/21
*/
public class GraphicsFilter
extends Graphics2DProxy {
private final RGBImageFilter grayFilter;
public GraphicsFilter(Graphics2D delegate, RGBImageFilter grayFilter) {
super(delegate);
this.grayFilter = grayFilter;
}
@Override
public Graphics create() {
return new GraphicsFilter((Graphics2D) super.create(), grayFilter);
}
@Override
public Graphics create(int x, int y, int width, int height) {
return new GraphicsFilter((Graphics2D) super.create(x, y, width, height), grayFilter);
}
@Override
public void setColor(Color c) {
super.setColor(filterColor(c));
}
@Override
public void setPaint(Paint paint) {
if (paint instanceof Color) {
paint = filterColor((Color) paint);
}
super.setPaint(paint);
}
private Color filterColor(Color color) {
if (grayFilter != null) {
int oldRGB = color.getRGB();
int newRGB = grayFilter.filterRGB(0, 0, oldRGB);
color = (newRGB != oldRGB) ? new Color(newRGB, true) : color;
}
return color;
}
}

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

@ -0,0 +1,29 @@
package com.fine.theme.icon;
/**
* 图标异常
*
* @author vito
* @since 11.0
* Created on 2023/11/6
*/
public class IconException extends RuntimeException {
public IconException() {
}
public IconException(String message) {
super(message);
}
public IconException(String message, Throwable cause) {
super(message, cause);
}
public IconException(Throwable cause) {
super(cause);
}
public IconException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}

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

@ -0,0 +1,175 @@
package com.fine.theme.icon;
import com.fr.third.errorprone.annotations.Immutable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.Icon;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap;
/**
* 图标管理器
* 1. 提供注册管理图标集方便整体替换
* 2. 提供图标缓存
* 3. 查找图标
* 4. 配合 {@link LazyIcon} 实现图标懒加载
*
* @author vito
* @since 11.0
* Created on 2023/9/12
*/
@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);
/**
* 获取图标集
*
* @param id 图标集ID
* @return 图标集
*/
public static IconSet getSet(String id) {
for (IconSet set : iconSets) {
if (set.getId().equals(id)) {
return set;
}
}
throw new IconException("[IconManager] Can not find icon set by id: " + id);
}
/**
* 添加图标集
*
* @param set 图标集
*/
public static void addSet(@NotNull IconSet set) {
if (!iconSets.contains(set)) {
iconSets.add(set);
// 清理可能来自其他图集相同名称图标
clearIconSetCache(set);
} else {
throw new IconException("[IconManager] IconSet by id:" + set.getId() + "is added!");
}
}
/**
* 根据图标ID获取图标
*
* @param id 图标ID
* @param <I> 图标类型
* @return 图标
*/
@NotNull
public static <I extends Icon> I getIcon(String id) {
Icon icon = findIcon(id);
if (icon == null) {
throw new IconException("[IconManager] Can not find icon by id: " + id);
}
return (I) icon;
}
/**
* 获取灰化图标
*
* @param id 图标ID
* @param <I> 图标类型
* @return 图标
*/
@NotNull
public static <I extends Icon> I getWhiteIcon(String id) {
final WeakReference<Icon> reference = whiteCache.get(id);
I icon = reference != null ? (I) reference.get() : null;
if (icon == null) {
for (IconSet set : iconSets) {
Icon f = set.findWhiteIcon(id);
if (f != null) {
icon = (I) f;
whiteCache.put(id, new WeakReference<>(icon));
}
}
}
if (icon == null) {
throw new IconException("[IconManager] Can not find icon by id: " + id);
}
return icon;
}
/**
* 获取灰化图标
*
* @param id 图标ID
* @param <I> 图标类型
* @return 图标
*/
@NotNull
public static <I extends Icon> I getDisableIcon(String id) {
Icon icon = findDisableIcon(id);
if (icon == null) {
throw new IconException("[IconManager] Can not find icon by id: " + id);
}
return (I) icon;
}
@Nullable
private static <I extends Icon> I findDisableIcon(String id) {
final WeakReference<Icon> reference = disableCache.get(id);
I icon = reference != null ? (I) reference.get() : null;
if (icon == null) {
for (IconSet set : iconSets) {
Icon f = set.findDisableIcon(id);
if (f != null) {
icon = (I) f;
disableCache.put(id, new WeakReference<>(icon));
}
}
}
return icon;
}
@Nullable
private static <I extends Icon> I findIcon(String id) {
final WeakReference<Icon> reference = cache.get(id);
I icon = reference != null ? (I) reference.get() : null;
if (icon == null) {
for (IconSet set : iconSets) {
Icon f = set.findIcon(id);
if (f != null) {
icon = (I) f;
cache.put(id, new WeakReference<>(icon));
}
}
}
return icon;
}
/**
* 清理所有缓存
*/
public static void clearCache() {
cache.clear();
disableCache.clear();
}
/**
* 清理图标缓存
*/
public static void clearIconCache(String id) {
cache.remove(id);
disableCache.remove(id);
}
private static void clearIconSetCache(@NotNull IconSet set) {
for (String id : set.getIds()) {
cache.remove(id);
disableCache.remove(id);
}
}
}

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

@ -0,0 +1,23 @@
package com.fine.theme.icon;
import org.jetbrains.annotations.NotNull;
import java.io.InputStream;
/**
* 资源接口
*
* @author vito
* @since 11.0
* Created on 2023/11/6
*/
public interface IconResource {
/**
* 获取输入资源流
*
* @return 资源流
*/
@NotNull
InputStream getInputStream();
}

71
designer-base/src/main/java/com/fine/theme/icon/IconSet.java

@ -0,0 +1,71 @@
package com.fine.theme.icon;
import com.fr.third.errorprone.annotations.Immutable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.Icon;
import java.util.Collection;
/**
* 图标集
*
* @author vito
* @since 11.0
* Created on 2023/11/6
*/
@Immutable
public interface IconSet extends Identifiable {
@NotNull
@Override
String getId();
/**
* 返回集合中所有 Icons id
*
* @return 集合中所有 Icons id
*/
@NotNull
Collection<String> getIds();
/**
* 将指定 IconSource 引用的新 Icon 添加到集合中
*
* @param icon icon
*/
void addIcon(@NotNull IconSource<? extends Icon> icon);
/**
* 将指定 IconSource 引用的新 Icon 添加到集合中
*
* @param icon icon
*/
void addIcon(@NotNull IconSource<? extends Icon>... icon);
/**
* 返回指定 id Icon
*
* @param id id
* @return Icon
*/
@Nullable
Icon findIcon(@NotNull String id);
/**
* 返回指定 id Icon
*
* @param id id
* @return Icon
*/
@Nullable
Icon findWhiteIcon(@NotNull String id);
/**
* 返回指定 id Icon
*
* @param id id
* @return Icon
*/
@Nullable
Icon findDisableIcon(@NotNull String id);
}

36
designer-base/src/main/java/com/fine/theme/icon/IconSource.java

@ -0,0 +1,36 @@
package com.fine.theme.icon;
import com.fr.third.errorprone.annotations.Immutable;
import org.jetbrains.annotations.NotNull;
import javax.swing.Icon;
import java.io.Serializable;
/**
* 图标源在进行图标管理的时候代替真实图标对象
* 使用时加载节省内存
*
* @author vito
* @since 11.0
* Created on 2023/11/6
*/
@Immutable
public interface IconSource<I extends Icon> extends Identifiable, DisabledIcon, WhiteIcon, Cloneable, Serializable {
/**
* 获取图标资源
*
* @return 图标资源
*/
@NotNull
IconResource getResource();
/**
* 加载图标
*
* @return 图标
*/
@NotNull
I loadIcon();
}

12
designer-base/src/main/java/com/fine/theme/icon/Identifiable.java

@ -0,0 +1,12 @@
package com.fine.theme.icon;
/**
* id 接口
*
* @author vito
* @since 11.0
* Created on 2023/11/6
*/
public interface Identifiable {
String getId();
}

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

@ -0,0 +1,83 @@
package com.fine.theme.icon;
import com.fr.third.errorprone.annotations.Immutable;
import org.jetbrains.annotations.NotNull;
import javax.swing.Icon;
import java.awt.Component;
import java.awt.Graphics;
/**
* 懒加载图标
*
* @author vito
* @since 11.0
* Created on 2023/11/6
*/
@Immutable
public class LazyIcon implements Identifiable, DisabledIcon, WhiteIcon, Icon {
@NotNull
private final String id;
public LazyIcon(@NotNull final String id) {
this.id = id;
}
@NotNull
@Override
public String getId() {
return id;
}
@Override
public void paintIcon(@NotNull final Component c, @NotNull final Graphics g, final int x, final int y) {
getIcon().paintIcon(c, g, x, y);
}
@Override
public int getIconWidth() {
return getIcon().getIconWidth();
}
@Override
public int getIconHeight() {
return getIcon().getIconHeight();
}
@NotNull
public <I extends Icon> I getIcon() {
return IconManager.getIcon(getId());
}
/**
* 创建一份灰化图标
*
* @return 灰化图标
*/
@NotNull
@Override
public Icon disabled() {
return IconManager.getDisableIcon(getId());
}
/**
* 创建一份白化图标
*
* @return 白化图标
*/
@NotNull
@Override
public Icon white() {
return IconManager.getWhiteIcon(getId());
}
@NotNull
@Override
public String toString() {
return getClass().getCanonicalName() + "[id=" + getId() + "]";
}
}

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

@ -0,0 +1,53 @@
package com.fine.theme.icon;
import com.fr.general.IOUtils;
import com.fr.io.utils.ResourceIOUtils;
import com.fr.third.errorprone.annotations.Immutable;
import org.jetbrains.annotations.NotNull;
import java.io.InputStream;
import java.util.StringJoiner;
/**
* url图标资源
*
* @author vito
* @since 11.0
* Created on 2023/11/15
*/
@Immutable
public class UrlIconResource implements IconResource {
private final String path;
public UrlIconResource(String path) {
this.path = path;
}
public String getPath() {
return path;
}
@Override
@NotNull
public InputStream getInputStream() {
InputStream inputStream = getInputStream(path);
if (inputStream == null) {
throw new IconException("Icon load failed: " + path);
}
return inputStream;
}
private InputStream getInputStream(String path) {
InputStream inputStream = IOUtils.getInputStream(path);
return inputStream != null ? inputStream : ResourceIOUtils.read(path);
}
@Override
public String toString() {
return new StringJoiner(", ", UrlIconResource.class.getSimpleName() + "[", "]")
.add("path='" + path + "'")
.toString();
}
}

22
designer-base/src/main/java/com/fine/theme/icon/WhiteIcon.java

@ -0,0 +1,22 @@
package com.fine.theme.icon;
import org.jetbrains.annotations.NotNull;
import javax.swing.Icon;
/**
* 白化图像
*
* @author vito
* @since 11.0
* Created on 2024/1/8
*/
public interface WhiteIcon {
/**
* 创建一份白化图标
*
* @return 灰化图标
*/
@NotNull
Icon white();
}

75
designer-base/src/main/java/com/fine/theme/icon/icons/AnimatedRadioButtonIcon.java

@ -0,0 +1,75 @@
package com.fine.theme.icon.icons;
import com.formdev.flatlaf.icons.FlatAnimatedIcon;
import com.formdev.flatlaf.util.ColorFunctions;
import org.jetbrains.annotations.Nullable;
import javax.swing.AbstractButton;
import javax.swing.ButtonModel;
import javax.swing.JRadioButton;
import javax.swing.UIManager;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;
/**
* RadioButton 图标带动画
*
* @author vito
* @since 11.0
* Created on 2023/11/22
*/
public class AnimatedRadioButtonIcon
extends FlatAnimatedIcon {
private static final int SIZE = 16;
private static final int BORDER_SIZE = 2;
private static final int ON_SIZE = 8;
private final Color offColor = UIManager.getColor("CheckBox.icon.borderColor");
private final Color onColor = UIManager.getColor("CheckBox.icon.checkmarkColor");
public AnimatedRadioButtonIcon() {
super(SIZE, SIZE, null);
}
@Override
public void paintIconAnimated(Component c, Graphics g, int x, int y, float animatedValue) {
Color color = ColorFunctions.mix(onColor, offColor, animatedValue);
// border
g.setColor(getBorderColor(c, color, onColor));
g.fillOval(0, 0, SIZE, SIZE);
// background
g.setColor(c.getBackground());
float onDiameter = SIZE - (BORDER_SIZE + (ON_SIZE - BORDER_SIZE) * (animatedValue));
float xy = (SIZE - onDiameter) / 2f;
((Graphics2D) g).fill(new Ellipse2D.Float(xy, xy, onDiameter, onDiameter));
}
@Nullable
private Color getBorderColor(Component c, Color enableColor, Color hoverColor) {
if (c instanceof AbstractButton) {
ButtonModel model = ((AbstractButton) c).getModel();
if (model.isRollover()) {
return hoverColor;
}
}
return enableColor;
}
@Override
public float getValue(Component c) {
return ((JRadioButton) c).isSelected() ? 1 : 0;
}
@Override
public int getAnimationDuration() {
return 200;
}
}

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

@ -0,0 +1,163 @@
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.WhiteIcon;
import com.formdev.flatlaf.FlatLaf;
import com.formdev.flatlaf.ui.FlatUIUtils;
import com.formdev.flatlaf.util.GrayFilter;
import com.fr.clone.cloning.Immutable;
import com.fr.log.FineLoggerFactory;
import com.fr.value.NullableLazyValue;
import com.github.weisj.jsvg.SVGDocument;
import com.github.weisj.jsvg.attributes.ViewBox;
import com.github.weisj.jsvg.parser.SVGLoader;
import org.jetbrains.annotations.NotNull;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.UIManager;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.RGBImageFilter;
import java.util.Objects;
import java.util.StringJoiner;
import static com.fine.theme.utils.FineUIScale.scale;
/**
* svg图标
* 1.绘制长度会跟随DPI比率变化
* 1跟2的缩放原因不同因此不能混淆宽高测量等依旧
* 使用DPI缩放进行只有绘制内容时使用Retina绘制如果有
* Retina绘制不影响最终尺寸注意区分
*
* @author vito
* @since 11.0
* Created on 2023/11/15
*/
@Immutable
public class SvgIcon implements DisabledIcon, WhiteIcon, Icon {
public enum Type {
/**
* 灰化图
*/
disable,
/**
* 白化图用于反白场景
*/
white,
/**
* 原始效果图
*/
origin
}
private final Dimension size;
private final IconResource resource;
private final Type type;
private final NullableLazyValue<SVGDocument> svgDocument = NullableLazyValue.createValue(() -> load(Type.origin));
private final NullableLazyValue<SVGDocument> whiteSvgDocument = NullableLazyValue.createValue(() -> load(Type.white));
public SvgIcon(IconResource resource, Dimension size) {
this(resource, size, Type.origin);
}
public SvgIcon(IconResource resource, Dimension size, Type type) {
this.resource = resource;
// 根据dpi进行缩放
this.size = scale(size);
this.type = type;
}
public SvgIcon(IconResource resource, int side) {
this(resource, new Dimension(side, side), Type.origin);
}
/**
* 如果支持绘制Retina绘制则进行Retina绘制
* 绘制结束不影响任何外部尺寸
*/
@Override
public void paintIcon(Component c, Graphics g, int x, int y) {
if (type == Type.disable) {
g = grayGraphics(g);
}
Object[] oldRenderingHints = FlatUIUtils.setRenderingHints(g);
render(c, g, x, y);
FlatUIUtils.resetRenderingHints(g, oldRenderingHints);
}
private Graphics2D grayGraphics(Graphics g) {
Object grayFilterObj = UIManager.get("Component.grayFilter");
RGBImageFilter grayFilter = (grayFilterObj instanceof RGBImageFilter)
? (RGBImageFilter) grayFilterObj
: GrayFilter.createDisabledIconFilter(FlatLaf.isLafDark());
return new GraphicsFilter((Graphics2D) g.create(), grayFilter);
}
@Override
public int getIconWidth() {
return size.width;
}
@Override
public int getIconHeight() {
return size.height;
}
private void render(Component c, Graphics g, int x, int y) {
try {
if (type == Type.white) {
Objects.requireNonNull(whiteSvgDocument.getValue())
.render((JComponent) c, (Graphics2D) g, new ViewBox(x, y, size.width, size.height));
} else {
Objects.requireNonNull(svgDocument.getValue())
.render((JComponent) c, (Graphics2D) g, new ViewBox(x, y, size.width, size.height));
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error("SvgIcon from url: " + resource + "can not paint.", e);
}
}
private SVGDocument load(Type type) {
SVGLoader loader = new SVGLoader();
return type == Type.white
? loader.load(resource.getInputStream(), new WhiteParser())
: loader.load(resource.getInputStream());
}
@Override
public String toString() {
return new StringJoiner(", ", SvgIcon.class.getSimpleName() + "[", "]")
.add("resource=" + resource)
.add("type=" + type)
.add("size=" + size)
.toString();
}
/**
* 默认提供一个简单的灰化处理
*/
@Override
public @NotNull SvgIcon white() {
return new SvgIcon(resource, size, Type.white);
}
/**
* 默认提供一个简单的灰化处理
*/
@Override
public @NotNull SvgIcon disabled() {
return new SvgIcon(resource, size, Type.disable);
}
}

80
designer-base/src/main/java/com/fine/theme/icon/svg/SvgIconSource.java

@ -0,0 +1,80 @@
package com.fine.theme.icon.svg;
import com.fine.theme.icon.AbstractIconSource;
import com.fine.theme.icon.IconResource;
import com.fine.theme.icon.UrlIconResource;
import com.fr.clone.cloning.Immutable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.Icon;
import java.awt.Dimension;
/**
* svg图标源
*
* @author vito
* @since 11.0
* Created on 2023/11/14
*/
@Immutable
public class SvgIconSource extends AbstractIconSource<SvgIcon> {
private static final int ICON_SIDE_LENGTH = 16;
private final Dimension size;
public SvgIconSource(@NotNull String id, @NotNull String resource) {
this(id, new UrlIconResource(resource), null, new Dimension(ICON_SIDE_LENGTH, ICON_SIDE_LENGTH));
}
public SvgIconSource(@NotNull String id, @NotNull String resource, boolean autoFindDisable) {
this(id, new UrlIconResource(resource), autoFindDisable, new Dimension(ICON_SIDE_LENGTH, ICON_SIDE_LENGTH));
}
public SvgIconSource(@NotNull String id, @NotNull String resource, int side) {
this(id, new UrlIconResource(resource), null, side);
}
public SvgIconSource(@NotNull String id, @NotNull String resource, boolean autoFindDisable, int side) {
this(id, new UrlIconResource(resource), autoFindDisable, new Dimension(side, side));
}
public SvgIconSource(@NotNull String id, @NotNull String resource, @Nullable String grayResource, int side) {
this(id, new UrlIconResource(resource), new UrlIconResource(grayResource), side);
}
public SvgIconSource(@NotNull String id, @NotNull IconResource resource,
@Nullable IconResource grayResource, int side) {
this(id, resource, grayResource, new Dimension(side, side));
}
public SvgIconSource(@NotNull String id, @NotNull IconResource resource,
boolean autoFindDisable, Dimension size) {
super(id, resource, autoFindDisable);
this.size = size;
}
public SvgIconSource(@NotNull String id, @NotNull IconResource resource,
@Nullable IconResource grayResource, Dimension size) {
super(id, resource, grayResource);
this.size = size;
}
@NotNull
@Override
protected SvgIcon loadIcon(@NotNull IconResource resource) {
return new SvgIcon(resource, size);
}
@Override
public @NotNull SvgIcon loadDisableIcon() {
return new SvgIcon(resource, size).disabled();
}
@Override
public @NotNull Icon white() {
return new SvgIcon(resource, size).white();
}
}

65
designer-base/src/main/java/com/fine/theme/icon/svg/SvgTranscoder.java

@ -0,0 +1,65 @@
package com.fine.theme.icon.svg;
import org.apache.batik.transcoder.SVGAbstractTranscoder;
import org.apache.batik.transcoder.TranscoderException;
import org.apache.batik.transcoder.TranscoderOutput;
import org.apache.batik.transcoder.image.ImageTranscoder;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.image.BufferedImage;
/**
* Svg图标转码器
*
* @author vito
* @since 11.0
* Created on 2023/11/15
*/
public class SvgTranscoder extends ImageTranscoder {
private BufferedImage bufferedImage;
private boolean gray = false;
public SvgTranscoder(Dimension size) {
addTranscodingHint(SVGAbstractTranscoder.KEY_WIDTH, (float) size.getWidth());
addTranscodingHint(SVGAbstractTranscoder.KEY_HEIGHT, (float) size.getHeight());
}
public SvgTranscoder(Dimension size, Color background, boolean gray) {
this.gray = gray;
addTranscodingHint(SVGAbstractTranscoder.KEY_WIDTH, (float) size.getWidth());
addTranscodingHint(SVGAbstractTranscoder.KEY_HEIGHT, (float) size.getHeight());
addTranscodingHint(ImageTranscoder.KEY_BACKGROUND_COLOR, background);
}
public SvgTranscoder(float width, float height) {
addTranscodingHint(SVGAbstractTranscoder.KEY_WIDTH, width);
addTranscodingHint(SVGAbstractTranscoder.KEY_HEIGHT, height);
}
@Override
public BufferedImage createImage(int width, int height) {
return gray ?
createGrayImage(width, height) :
new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
}
/**
* 灰化底图
*/
private BufferedImage createGrayImage(int width, int height) {
return new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
}
@Override
public void writeImage(BufferedImage bufferedImage, TranscoderOutput transcoderOutput) throws TranscoderException {
this.bufferedImage = bufferedImage;
}
public BufferedImage getImage() {
return bufferedImage;
}
}

50
designer-base/src/main/java/com/fine/theme/icon/svg/WhiteParser.java

@ -0,0 +1,50 @@
package com.fine.theme.icon.svg;
import com.github.weisj.jsvg.attributes.paint.AwtSVGPaint;
import com.github.weisj.jsvg.attributes.paint.PaintParser;
import com.github.weisj.jsvg.attributes.paint.SVGPaint;
import com.github.weisj.jsvg.parser.AttributeNode;
import com.github.weisj.jsvg.parser.DefaultParserProvider;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.awt.Color;
/**
* svg绘制白化转化器
*
* @author vito
* @since 11.0
* Created on 2024/1/8
*/
public class WhiteParser extends DefaultParserProvider {
@Override
public @NotNull PaintParser createPaintParser() {
return new WhitePaintParser(super.createPaintParser());
}
static class WhitePaintParser implements PaintParser {
private final PaintParser delegate;
WhitePaintParser(PaintParser delegate) {
this.delegate = delegate;
}
@Override
public @Nullable Color parseColor(@NotNull String value, @NotNull AttributeNode attributeNode) {
return delegate.parseColor(value, attributeNode);
}
@Override
public @Nullable SVGPaint parsePaint(@Nullable String value, @NotNull AttributeNode attributeNode) {
SVGPaint paint = delegate.parsePaint(value, attributeNode);
if (!(paint instanceof AwtSVGPaint)) {
return paint;
}
return new AwtSVGPaint(Color.WHITE);
}
}
}

42
designer-base/src/main/java/com/fine/theme/light/ui/FineButtonBorder.java

@ -0,0 +1,42 @@
package com.fine.theme.light.ui;
import com.fine.theme.utils.FineUIUtils;
import com.formdev.flatlaf.ui.FlatButtonBorder;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Paint;
import static com.fine.theme.light.ui.FineButtonUI.isPartRoundButton;
/**
* 按钮边框
*
* @author vito
* @since 11.0
* Created on 2023/12/20
*/
public class FineButtonBorder extends FlatButtonBorder {
public FineButtonBorder() {
}
@Override
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
if (isPartRoundButton(c)) {
Graphics2D g2 = (Graphics2D) g.create();
Paint borderPaint = getBorderColor(c);
if (borderPaint == null) {
return;
}
g2.setPaint(borderPaint);
FineUIUtils.paintPartRoundButtonBorder(c, g2, x, y, width, height, borderWidth, (float) getArc(c));
} else {
super.paintBorder(c, g, x, y, width, height);
}
}
}

42
designer-base/src/main/java/com/fine/theme/light/ui/FineButtonGroupUI.java

@ -0,0 +1,42 @@
package com.fine.theme.light.ui;
import com.fr.design.gui.ibutton.UIButtonGroup;
import javax.swing.JComponent;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.PanelUI;
import java.awt.Graphics;
/**
* 按钮组UI应用于 {@link com.fr.design.gui.ibutton.UIButtonGroup}
*
* @author Levy.Xie
* @since 11.0
* Created on 2023/12/15
*/
public class FineButtonGroupUI extends PanelUI {
/**
* 创建UI
*
* @param c 组件
* @return ComponentUI
*/
public static ComponentUI createUI(JComponent c) {
return new FineButtonGroupUI();
}
@Override
public void update(Graphics g, JComponent c) {
UIButtonGroup group = (UIButtonGroup) c;
if (!group.isInToolbar()) {
c.setBorder(new FineRoundBorder());
}
super.update(g, c);
}
@Override
public void uninstallUI(JComponent c) {
super.uninstallUI(c);
}
}

114
designer-base/src/main/java/com/fine/theme/light/ui/FineButtonUI.java

@ -0,0 +1,114 @@
package com.fine.theme.light.ui;
import com.fine.theme.utils.FineClientProperties;
import com.fine.theme.utils.FineUIUtils;
import com.formdev.flatlaf.ui.FlatButtonUI;
import com.formdev.flatlaf.ui.FlatUIUtils;
import javax.swing.AbstractButton;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.plaf.ComponentUI;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Path2D;
import static com.fine.theme.utils.FineClientProperties.BUTTON_BORDER;
/**
* 按钮UI
*
* @author vito
* @since 11.0
* Created on 2023/12/20
*/
public class FineButtonUI extends FlatButtonUI {
/**
* @param shared
* @since 2
*/
protected FineButtonUI(boolean shared) {
super(shared);
}
/**
* 是否左圆角矩形
*
* @param c 组件
* @return 是否左圆角矩形
*/
public static boolean isLeftRoundButton(Component c) {
return c instanceof JButton
&& FineClientProperties.BUTTON_BORDER_LEFT_ROUND_RECT.equals(getButtonBorderTypeStr((JButton) c));
}
/**
* 是否右圆角矩形
*
* @param c 组件
* @return 是否右圆角矩形
*/
public static boolean isRightRoundButton(Component c) {
return c instanceof JButton
&& FineClientProperties.BUTTON_BORDER_RIGHT_ROUND_RECT.equals(getButtonBorderTypeStr((JButton) c));
}
/**
* 是否部分圆角矩形
*
* @param c 组件
* @return 是否部分圆角矩形
*/
public static boolean isPartRoundButton(Component c) {
return isLeftRoundButton(c) || isRightRoundButton(c);
}
protected void paintBackground(Graphics g, JComponent c) {
if (isPartRoundButton(c)) {
Color background = getBackground(c);
if (background == null) {
return;
}
Graphics2D g2 = (Graphics2D) g.create();
try {
FlatUIUtils.setRenderingHints(g2);
float arc = FlatUIUtils.getBorderArc(c);
int width = c.getWidth();
int height = c.getHeight();
g2.setColor(FlatUIUtils.deriveColor(background, getBackgroundBase(c, false)));
Path2D path2DLeft;
if (isLeftRoundButton(c)) {
path2DLeft = FineUIUtils.createLeftRoundRectangle(0, 0, width, height, arc);
} else {
path2DLeft = FineUIUtils.createRightRoundRectangle(0, 0, width, height, arc);
}
g2.fill(path2DLeft);
} finally {
g2.dispose();
}
} else {
super.paintBackground(g, c);
}
}
/**
* 创建UI
*/
public static ComponentUI createUI(JComponent c) {
return new FineButtonUI(false);
}
static String getButtonBorderTypeStr(AbstractButton c) {
Object value = c.getClientProperty(BUTTON_BORDER);
if (value instanceof String) {
return (String) value;
}
return null;
}
}

37
designer-base/src/main/java/com/fine/theme/light/ui/FineCheckBoxUI.java

@ -0,0 +1,37 @@
package com.fine.theme.light.ui;
import com.fine.theme.icon.LazyIcon;
import com.formdev.flatlaf.ui.FlatCheckBoxUI;
import javax.swing.AbstractButton;
import javax.swing.JComponent;
import javax.swing.plaf.ComponentUI;
/**
* 提供 {@link javax.swing.JCheckBox} 的UI类
*
* @author Levy.Xie
* @since 11.0
* Created on 2023/12/14
*/
public class FineCheckBoxUI extends FlatCheckBoxUI {
public static ComponentUI createUI(JComponent c) {
return new FineCheckBoxUI(false);
}
protected FineCheckBoxUI(boolean shared) {
super(shared);
}
@Override
public void installDefaults(AbstractButton b) {
super.installDefaults(b);
b.setIcon(new LazyIcon("checkbox_unchecked"));
b.setSelectedIcon(new LazyIcon("checkbox_checked"));
b.setRolloverIcon(new LazyIcon("checkbox_hovered"));
b.setDisabledIcon(new LazyIcon("checkbox_unchecked").disabled());
b.setDisabledSelectedIcon(new LazyIcon("checkbox_checked").disabled());
}
}

66
designer-base/src/main/java/com/fine/theme/light/ui/FineColorButtonUI.java

@ -0,0 +1,66 @@
package com.fine.theme.light.ui;
import com.formdev.flatlaf.ui.FlatUIUtils;
import com.fr.base.Utils;
import com.fr.design.gui.ibutton.UIColorButton;
import javax.swing.ButtonModel;
import javax.swing.JComponent;
import javax.swing.plaf.ComponentUI;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.geom.RoundRectangle2D;
import static com.fine.theme.utils.FineUIScale.scale;
/**
* 颜色按钮
*
* @author vito
* @since 11.0
* Created on 2024/1/3
*/
public class FineColorButtonUI extends FineButtonUI {
public static final float HEIGHT = 1.5f;
public static final float WIDTH = 13;
public static final float Y = 13.5f;
/**
* @param shared
* @since 2
*/
protected FineColorButtonUI(boolean shared) {
super(shared);
}
/**
* 创建UI
*/
public static ComponentUI createUI(JComponent c) {
return new FineColorButtonUI(false);
}
@Override
protected void paintIcon(Graphics g, JComponent c, Rectangle iconRect) {
super.paintIcon(g, c, iconRect);
UIColorButton b = (UIColorButton) c;
ButtonModel model = b.getModel();
if (model.isEnabled()) {
g.setColor(b.getColor());
} else {
g.setColor(new Color(Utils.filterRGB(b.getColor().getRGB(), 50)));
}
FlatUIUtils.setRenderingHints(g);
Graphics2D g2d = (Graphics2D) g;
float height = scale(HEIGHT);
float width = scale(WIDTH);
// 计算实际大小与icon区域大小的偏移,用于居中调整
float offsetX = (iconRect.width - width) / 2.0f;
RoundRectangle2D.Float colorRect = new RoundRectangle2D.Float(
iconRect.x + offsetX, iconRect.y + scale(Y), width, height, height, height);
g2d.fill(colorRect);
}
}

90
designer-base/src/main/java/com/fine/theme/light/ui/FineCombinationButtonUI.java

@ -0,0 +1,90 @@
package com.fine.theme.light.ui;
import com.fine.theme.utils.FineClientProperties;
import com.fine.theme.utils.FineUIStyle;
import com.fine.theme.utils.FineUIUtils;
import com.formdev.flatlaf.ui.FlatPanelUI;
import com.formdev.flatlaf.ui.FlatUIUtils;
import com.fr.design.gui.ibutton.UICombinationButton;
import javax.swing.JComponent;
import javax.swing.plaf.ComponentUI;
import java.awt.Color;
import java.awt.Graphics;
import java.beans.PropertyChangeEvent;
import static com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
/**
* 双组件按钮UI
*
* @author vito
* @since 11.0
* Created on 2023/12/21
*/
public class FineCombinationButtonUI extends FlatPanelUI {
@Styleable(dot = true)
protected Color background;
@Styleable(dot = true)
protected int arc;
/**
* @param shared
* @since 2
*/
protected FineCombinationButtonUI(boolean shared) {
super(shared);
}
/**
* 创建UI
*
* @param c 组件
* @return ComponentUI
*/
public static ComponentUI createUI(JComponent c) {
return new FineCombinationButtonUI(false);
}
@Override
public void installUI(JComponent c) {
super.installUI(c);
background = FineUIUtils.getUIColor("CombinationButton.background", "desktop");
arc = FineUIUtils.getUIInt("CombinationButton.arc", "Component.arc");
}
@Override
public void uninstallUI(JComponent c) {
super.uninstallUI(c);
}
@Override
public void paint(Graphics g, JComponent c) {
paintBackground(g, c);
super.paint(g, c);
}
protected void paintBackground(Graphics g, JComponent c) {
FlatUIUtils.setRenderingHints(g);
g.setColor(background);
g.fillRoundRect(0, 0, c.getWidth(), c.getHeight(), arc, arc);
}
@Override
public void propertyChange(PropertyChangeEvent e) {
super.propertyChange(e);
switch (e.getPropertyName()) {
case FineClientProperties.STYLE_CLASS:
UICombinationButton b = (UICombinationButton) e.getSource();
if (FineUIStyle.STYLE_PRIMARY.equals(e.getNewValue())) {
b.setPrimary();
}
b.repaint();
break;
default:
break;
}
}
}

41
designer-base/src/main/java/com/fine/theme/light/ui/FineComboBoxUI.java

@ -0,0 +1,41 @@
package com.fine.theme.light.ui;
import com.formdev.flatlaf.ui.FlatComboBoxUI;
import javax.swing.JComponent;
import javax.swing.JButton;
import javax.swing.SwingConstants;
import javax.swing.plaf.ComponentUI;
import java.awt.Graphics2D;
/**
* 提供 {@link javax.swing.JComboBox} 的UI类
*
* @author Levy.Xie
* @since 11.0
* Created on 2023/12/07
*/
public class FineComboBoxUI extends FlatComboBoxUI {
public static ComponentUI createUI(JComponent c) {
return new FineComboBoxUI();
}
@Override
protected JButton createArrowButton() {
return new FineComboBoxButton();
}
protected class FineComboBoxButton extends FlatComboBoxButton {
@Override
protected void paintArrow(Graphics2D g) {
if (isPopupVisible(comboBox)) {
setDirection(SwingConstants.NORTH);
} else {
setDirection(SwingConstants.SOUTH);
}
super.paintArrow(g);
}
}
}

309
designer-base/src/main/java/com/fine/theme/light/ui/FineGradientBarUI.java

@ -0,0 +1,309 @@
package com.fine.theme.light.ui;
import com.fine.theme.utils.FineUIUtils;
import com.formdev.flatlaf.ui.FlatPanelUI;
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 FlatPanelUI {
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;
protected FineGradientBarUI(boolean shared) {
super(shared);
}
/**
* 创建UI
*
* @param c 组件
* @return UI
*/
public static ComponentUI createUI(JComponent c) {
return new FineGradientBarUI(false);
}
@Override
public void installUI(JComponent c) {
super.installUI(c);
installDefaults(c);
gradientBar = (GradientBar) c;
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).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;
gradientBar = (GradientBar) c;
list = gradientBar.getList();
p1 = gradientBar.getSelectColorPointBtnP1();
p2 = gradientBar.getSelectColorPointBtnP2();
if (hoverStatus == null) {
hoverStatus = new boolean[list.size()];
}
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 = getColorFloats(c, btnList);
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 float[] getColorFloats(GradientBar c, List<SelectColorPointBtn> btnList) {
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);
btnList.get(i).setY(recHeight);
}
float dist1 = dist[btnList.size() - 1];
float dist2 = dist[btnList.size() - 2];
if (AssistUtils.equals(dist1, dist2)) {
dist[btnList.size() - 1] = (float) (dist2 + offset);
}
return dist;
}
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);
}
}

74
designer-base/src/main/java/com/fine/theme/light/ui/FineHeadGroupUI.java

@ -0,0 +1,74 @@
package com.fine.theme.light.ui;
import com.fine.theme.utils.FineUIUtils;
import com.formdev.flatlaf.ui.FlatUIUtils;
import javax.swing.JComponent;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.PanelUI;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import static com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
/**
* HeadGroup 的UI类
*
* @author vito
* @since 11.0
* Created on 2023/12/15
*/
public class FineHeadGroupUI extends PanelUI {
@Styleable(dot = true)
protected Color background;
@Styleable(dot = true)
protected int arc;
/**
* 创建UI
*
* @param c 组件
* @return ComponentUI
*/
public static ComponentUI createUI(JComponent c) {
return new FineHeadGroupUI();
}
@Override
public void installUI(JComponent c) {
super.installUI(c);
background = FineUIUtils.getUIColor("HeadGroup.background", "desktop");
arc = FineUIUtils.getUIInt("HeadGroup.arc", "Component.arc");
}
@Override
public void uninstallUI(JComponent c) {
super.uninstallUI(c);
}
@Override
public Dimension getMinimumSize(JComponent component) {
return new Dimension(0, 0);
}
@Override
public Dimension getMaximumSize(JComponent component) {
return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
}
@Override
public void update(Graphics g, JComponent c) {
paintBackground(g, c);
paint(g, c);
}
protected void paintBackground(Graphics g, JComponent c) {
FlatUIUtils.setRenderingHints(g);
g.setColor(background);
g.fillRoundRect(0, 0, c.getWidth(), c.getHeight(), arc, arc);
}
}

123
designer-base/src/main/java/com/fine/theme/light/ui/FineInputUI.java

@ -0,0 +1,123 @@
package com.fine.theme.light.ui;
import com.fine.theme.utils.FineUIUtils;
import com.formdev.flatlaf.ui.FlatButtonUI;
import com.formdev.flatlaf.ui.FlatPanelUI;
import javax.swing.AbstractButton;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
import java.beans.PropertyChangeEvent;
/**
* Input输入框类组件 UI类
*
* @author Leo.Qin
* @since 11.0
* Created on 2023/12/11
*/
public class FineInputUI extends FlatPanelUI {
private static final String ENABLED = "enabled";
private static final String EDITABLE = "editable";
private final int defaultArc = 5;
public FineInputUI(boolean shared) {
super(shared);
}
/**
* 创建UI
*/
public static ComponentUI createUI(JComponent c) {
return new FineInputUI(false);
}
@Override
public void installUI(JComponent c) {
super.installUI(c);
c.setBackground(UIManager.getColor("Input.background"));
c.setBorder(UIManager.getBorder("Input.border"));
}
@Override
protected void installDefaults(JPanel p) {
super.installDefaults(p);
arc = FineUIUtils.getAndScaleInt("Input.arc", defaultArc);
}
@Override
public void propertyChange(PropertyChangeEvent e) {
String propertyName = e.getPropertyName();
if (EDITABLE.equals(propertyName) || ENABLED.equals(propertyName)) {
updateBackground(e);
} else {
super.propertyChange(e);
}
}
private void updateBackground(PropertyChangeEvent e) {
JPanel source = (JPanel) e.getSource();
if (e.getNewValue() == Boolean.FALSE) {
source.setBackground(UIManager.getColor("Input.disabledBackground"));
} else {
source.setBackground(UIManager.getColor("Input.background"));
}
}
/**
* input输入框中的Button UI类
*
* @author Leo.Qin
* @since 11.0
* Created on 2023/12/12
*/
public static class FineInputButtonUI extends FlatButtonUI {
public FineInputButtonUI(boolean shared) {
super(shared);
}
/**
* 创建UI
*/
public static ComponentUI createUI(JComponent c) {
return new FineInputButtonUI(false);
}
@Override
public void installUI(JComponent c) {
super.installUI(c);
c.setBorder(null);
c.setOpaque(false);
}
@Override
protected void installDefaults(AbstractButton b) {
super.installDefaults(b);
hoverBackground = UIManager.getColor("InputButton.hoverBackground");
pressedBackground = UIManager.getColor("InputButton.pressedBackground");
background = UIManager.getColor("InputButton.background");
}
@Override
public void propertyChange(AbstractButton b, PropertyChangeEvent e) {
String propertyName = e.getPropertyName();
if (EDITABLE.equals(propertyName) || ENABLED.equals(propertyName)) {
updateBackground(b, e);
} else {
super.propertyChange(b, e);
}
}
private void updateBackground(AbstractButton b, PropertyChangeEvent e) {
if (e.getNewValue() == Boolean.FALSE) {
b.setBackground(UIManager.getColor("InputButton.disabledBackground"));
} else {
b.setBackground(UIManager.getColor("InputButton.background"));
}
}
}
}

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

@ -0,0 +1,249 @@
package com.fine.theme.light.ui;
import com.fine.theme.icon.AbstractIconSet;
import com.fine.theme.icon.svg.SvgIconSource;
/**
* Fine 亮主题图标集
*
* @author vito
* @since 11.0
* Created on 2023/11/17
*/
public class FineLightIconSet extends AbstractIconSet {
public FineLightIconSet(String id) {
super(id);
load();
}
private void load() {
addIcon(
new SvgIconSource("cut", "com/fine/theme/icon/cut.svg", true),
new SvgIconSource("save", "com/fine/theme/icon/save.svg", true),
new SvgIconSource("copy", "com/fine/theme/icon/copy.svg", true),
new SvgIconSource("formatBrush", "com/fine/theme/icon/formatBrush.svg", true),
new SvgIconSource("paste", "com/fine/theme/icon/paste.svg", true),
new SvgIconSource("undo", "com/fine/theme/icon/undo.svg", true),
new SvgIconSource("redo", "com/fine/theme/icon/redo.svg", true),
new SvgIconSource("version_save", "com/fine/theme/icon/version_save.svg", true),
new SvgIconSource("font_miss_check", "com/fine/theme/icon/font_miss_check.svg", true),
new SvgIconSource("template_theme", "com/fine/theme/icon/template_theme.svg", true),
new SvgIconSource("remove", "com/fine/theme/icon/remove.svg", true),
new SvgIconSource("search", "com/fine/theme/icon/search.svg", true),
new SvgIconSource("add", "com/fine/theme/icon/add.svg", true),
new SvgIconSource("drag_left", "com/fine/theme/icon/drag_left.svg", true),
new SvgIconSource("drag_right", "com/fine/theme/icon/drag_right.svg", true),
new SvgIconSource("down_arrow", "com/fine/theme/icon/down_arrow.svg", true),
new SvgIconSource("down_arrow_12", "com/fine/theme/icon/down_arrow.svg", true, 12),
new SvgIconSource("up_arrow_12", "com/fine/theme/icon/up_arrow.svg", true, 12),
new SvgIconSource("select", "com/fine/theme/icon/select.svg", true),
// 数据集相关Icon
new SvgIconSource("database", "com/fine/theme/icon/dataset/database.svg", true),
new SvgIconSource("preview", "com/fine/theme/icon/dataset/preview.svg", true),
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("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),
new SvgIconSource("edit", "com/fine/theme/icon/dataset/edit.svg", true),
new SvgIconSource("server_database", "com/fine/theme/icon/dataset/server_database.svg", true),
new SvgIconSource("field", "com/fine/theme/icon/dataset/field.svg", true),
// 目录树相关Icon
new SvgIconSource("folder", "com/fine/theme/icon/filetree/folder.svg", true),
new SvgIconSource("folder_open", "com/fine/theme/icon/filetree/folder_open.svg", true),
new SvgIconSource("cpt_icon", "com/fine/theme/icon/filetree/cpt_icon.svg", true),
new SvgIconSource("frm_icon", "com/fine/theme/icon/filetree/frm_icon.svg", true),
new SvgIconSource("fvs_icon", "com/fine/theme/icon/filetree/fvs_icon.svg", true),
new SvgIconSource("excel_icon", "com/fine/theme/icon/filetree/excel_icon.svg", true),
new SvgIconSource("minus", "com/fine/theme/icon/filetree/minus.svg", true),
new SvgIconSource("plus", "com/fine/theme/icon/filetree/plus.svg", true),
new SvgIconSource("locate", "com/fine/theme/icon/filetree/locate.svg", true),
new SvgIconSource("rename", "com/fine/theme/icon/filetree/rename.svg", true),
new SvgIconSource("collapse_all", "com/fine/theme/icon/filetree/collapse_all.svg", true),
new SvgIconSource("vcs_list", "com/fine/theme/icon/filetree/vcs_list.svg", true),
new SvgIconSource("view_folder", "com/fine/theme/icon/filetree/view_folder.svg", true),
new SvgIconSource("refresh", "com/fine/theme/icon/filetree/refresh.svg", true),
new SvgIconSource("new_folder", "com/fine/theme/icon/filetree/new_folder.svg", true),
// 文件类型
new SvgIconSource("add_report", "com/fine/theme/icon/filetree/filetype/add_report.svg", true),
new SvgIconSource("add_word", "com/fine/theme/icon/filetree/filetype/add_word.svg", true),
new SvgIconSource("bmpFile", "com/fine/theme/icon/filetree/filetype/bmpFile.svg", true),
new SvgIconSource("chtFile", "com/fine/theme/icon/filetree/filetype/chtFile.svg", true),
new SvgIconSource("classFile", "com/fine/theme/icon/filetree/filetype/classFile.svg", true),
new SvgIconSource("cpt_locked", "com/fine/theme/icon/filetree/filetype/cpt_locked.svg", true),
new SvgIconSource("excel_import", "com/fine/theme/icon/filetree/filetype/excel_import.svg", true),
new SvgIconSource("excelFile", "com/fine/theme/icon/filetree/filetype/excelFile.svg", true),
new SvgIconSource("flashFile", "com/fine/theme/icon/filetree/filetype/flashFile.svg", true),
new SvgIconSource("frm_locked", "com/fine/theme/icon/filetree/filetype/frm_locked.svg", true),
new SvgIconSource("gifFile", "com/fine/theme/icon/filetree/filetype/gifFile.svg", true),
new SvgIconSource("htmlFile", "com/fine/theme/icon/filetree/filetype/htmlFile.svg", true),
new SvgIconSource("jarFile", "com/fine/theme/icon/filetree/filetype/jarFile.svg", true),
new SvgIconSource("javaFile", "com/fine/theme/icon/filetree/filetype/javaFile.svg", true),
new SvgIconSource("jpgFile", "com/fine/theme/icon/filetree/filetype/jpgFile.svg", true),
new SvgIconSource("jsFile", "com/fine/theme/icon/filetree/filetype/jsFile.svg", true),
new SvgIconSource("jspFile", "com/fine/theme/icon/filetree/filetype/jspFile.svg", true),
new SvgIconSource("pdfFile", "com/fine/theme/icon/filetree/filetype/pdfFile.svg", true),
new SvgIconSource("pngFile", "com/fine/theme/icon/filetree/filetype/pngFile.svg", true),
new SvgIconSource("sqlFile", "com/fine/theme/icon/filetree/filetype/sqlFile.svg", true),
new SvgIconSource("wordFile", "com/fine/theme/icon/filetree/filetype/wordFile.svg", true),
new SvgIconSource("xlsFile", "com/fine/theme/icon/filetree/filetype/xlsFile.svg", true),
new SvgIconSource("xmlFile", "com/fine/theme/icon/filetree/filetype/xmlFile.svg", true),
// 属性面板Icon
new SvgIconSource("cellattr", "com/fine/theme/icon/propertiestab/cellattr.svg", false, 18),
new SvgIconSource("cellattr_disabled", "com/fine/theme/icon/propertiestab/cellattr_disabled.svg", false, 18),
new SvgIconSource("cellattr_selected", "com/fine/theme/icon/propertiestab/cellattr_selected.svg", false, 18),
new SvgIconSource("cellelement", "com/fine/theme/icon/propertiestab/cellelement.svg", false, 18),
new SvgIconSource("cellelement_disabled", "com/fine/theme/icon/propertiestab/cellelement_disabled.svg", false, 18),
new SvgIconSource("cellelement_selected", "com/fine/theme/icon/propertiestab/cellelement_selected.svg", false, 18),
new SvgIconSource("conditionattr", "com/fine/theme/icon/propertiestab/conditionattr.svg", false, 18),
new SvgIconSource("conditionattr_disabled", "com/fine/theme/icon/propertiestab/conditionattr_disabled.svg", false, 18),
new SvgIconSource("conditionattr_selected", "com/fine/theme/icon/propertiestab/conditionattr_selected.svg", false, 18),
new SvgIconSource("floatelement", "com/fine/theme/icon/propertiestab/floatelement.svg", false, 18),
new SvgIconSource("floatelement_disabled", "com/fine/theme/icon/propertiestab/floatelement_disabled.svg", false, 18),
new SvgIconSource("floatelement_selected", "com/fine/theme/icon/propertiestab/floatelement_selected.svg", false, 18),
new SvgIconSource("hyperlink", "com/fine/theme/icon/propertiestab/hyperlink.svg", false, 18),
new SvgIconSource("hyperlink_disabled", "com/fine/theme/icon/propertiestab/hyperlink_disabled.svg", false, 18),
new SvgIconSource("hyperlink_selected", "com/fine/theme/icon/propertiestab/hyperlink_selected.svg", false, 18),
new SvgIconSource("widgetlib", "com/fine/theme/icon/propertiestab/widgetlib.svg", false, 18),
new SvgIconSource("widgetlib_disabled", "com/fine/theme/icon/propertiestab/widgetlib_disabled.svg", false, 18),
new SvgIconSource("widgetlib_selected", "com/fine/theme/icon/propertiestab/widgetlib_selected.svg", false, 18),
new SvgIconSource("widgetsettings", "com/fine/theme/icon/propertiestab/widgetsettings.svg", false, 18),
new SvgIconSource("widgetsettings_disabled", "com/fine/theme/icon/propertiestab/widgetsettings_disabled.svg", false, 18),
new SvgIconSource("widgetsettings_selected", "com/fine/theme/icon/propertiestab/widgetsettings_selected.svg", false, 18),
new SvgIconSource("configuredroles", "com/fine/theme/icon/propertiestab/configuredroles.svg", false, 18),
new SvgIconSource("configuredroles_selected", "com/fine/theme/icon/propertiestab/configuredroles_selected.svg", false, 18),
new SvgIconSource("configuredroles_disabled", "com/fine/theme/icon/propertiestab/configuredroles_disabled.svg", false, 18),
new SvgIconSource("authorityedit", "com/fine/theme/icon/propertiestab/authorityedit.svg", false, 18),
new SvgIconSource("authorityedit_disabled", "com/fine/theme/icon/propertiestab/authorityedit_disabled.svg", false, 18),
new SvgIconSource("authorityedit_selected", "com/fine/theme/icon/propertiestab/authorityedit_selected.svg", false, 18),
// sheet标签栏相关icon
new SvgIconSource("add_worksheet", "com/fine/theme/icon/sheet/add_sheet.svg", true),
// TODO: 待视觉提供后替换
new SvgIconSource("add_polysheet", "com/fine/theme/icon/sheet/add_frm.svg", true),
// CheckBox相关Icon
new SvgIconSource("checkbox_checked", "com/fine/theme/icon/checkbox/checked.svg", true),
new SvgIconSource("checkbox_unchecked", "com/fine/theme/icon/checkbox/unchecked.svg", true),
new SvgIconSource("checkbox_part_checked", "com/fine/theme/icon/checkbox/part_checked.svg", true),
new SvgIconSource("checkbox_hovered", "com/fine/theme/icon/checkbox/hovered.svg", true),
// radioButton相关icon
new SvgIconSource("radio_selected", "com/fine/theme/icon/radio/radio_selected.svg", true),
new SvgIconSource("radio_unselected", "com/fine/theme/icon/radio/radio_unselected.svg", true),
// 菜单栏Icon
new SvgIconSource("bold", "com/fine/theme/icon/font/bold.svg"),
new SvgIconSource("italic", "com/fine/theme/icon/font/italic.svg"),
new SvgIconSource("underline", "com/fine/theme/icon/font/underline.svg"),
new SvgIconSource("foreground", "com/fine/theme/icon/font/foreground.svg"),
new SvgIconSource("background", "com/fine/theme/icon/font/background.svg"),
new SvgIconSource("h_left", "com/fine/theme/icon/cellstyle/h_left.svg"),
new SvgIconSource("h_center", "com/fine/theme/icon/cellstyle/h_center.svg"),
new SvgIconSource("h_right", "com/fine/theme/icon/cellstyle/h_right.svg"),
new SvgIconSource("noboder", "com/fine/theme/icon/noboder.svg", true),
new SvgIconSource("merge", "com/fine/theme/icon/merge/merge.svg", true),
new SvgIconSource("unmerge", "com/fine/theme/icon/merge/unmerge.svg", true),
new SvgIconSource("bind_column", "com/fine/theme/icon/bindcolumn/bind_column.svg", true),
new SvgIconSource("text", "com/fine/theme/icon/insert/text.svg", true),
new SvgIconSource("richtext", "com/fine/theme/icon/insert/richtext.svg", true),
new SvgIconSource("formula", "com/fine/theme/icon/insert/formula.svg", true),
new SvgIconSource("chart", "com/fine/theme/icon/insert/chart.svg", true),
new SvgIconSource("image", "com/fine/theme/icon/insert/image.svg", true),
new SvgIconSource("bias", "com/fine/theme/icon/insert/bias.svg", true),
new SvgIconSource("sub_report", "com/fine/theme/icon/insert/sub_report.svg", true),
new SvgIconSource("chart_line", "com/fine/theme/icon/chart/chart_line.svg", true),
new SvgIconSource("popup", "com/fine/theme/icon/popup/popup.svg", true),
new SvgIconSource("clear", "com/fine/theme/icon/clear.svg", true),
new SvgIconSource("clear_hover", "com/fine/theme/icon/clear_hover.svg", true),
// 工具栏
new SvgIconSource("tool_copy", "com/fine/theme/icon/toolbar/copy.svg", true),
new SvgIconSource("move_down", "com/fine/theme/icon/toolbar/move_down.svg", true),
new SvgIconSource("move_up", "com/fine/theme/icon/toolbar/move_up.svg", true),
new SvgIconSource("move_left", "com/fine/theme/icon/toolbar/move_left.svg", true),
new SvgIconSource("move_right", "com/fine/theme/icon/toolbar/move_right.svg", true),
new SvgIconSource("tool_edit", "com/fine/theme/icon/toolbar/edit.svg", true),
new SvgIconSource("tool_edit_white", "com/fine/theme/icon/toolbar/edit_white.svg", true),
new SvgIconSource("tool_more", "com/fine/theme/icon/toolbar/more.svg", true),
new SvgIconSource("tool_more_hover", "com/fine/theme/icon/toolbar/more_hover.svg"),
new SvgIconSource("tool_config", "com/fine/theme/icon/toolbar/config.svg", true),
new SvgIconSource("add_popup", "com/fine/theme/icon/toolbar/add_popup.svg", true, 24),
// 参数面板
new SvgIconSource("param_edit", "com/fine/theme/icon/param/edit.svg", true, 24),
new SvgIconSource("param_edit_pressed", "com/fine/theme/icon/param/edit_pressed.svg", true, 24),
new SvgIconSource("param_hide", "com/fine/theme/icon/param/hide.svg", true, 24),
new SvgIconSource("param_hide_pressed", "com/fine/theme/icon/param/hide_pressed.svg", true, 24),
new SvgIconSource("param_view", "com/fine/theme/icon/param/view.svg", true, 18),
new SvgIconSource("param", "com/fine/theme/icon/param/param.svg", true),
// 北区菜单栏
new SvgIconSource("notification", "com/fine/theme/icon/notification/notification.svg"),
new SvgIconSource("notification_dot", "com/fine/theme/icon/notification/notification_dot.svg"),
//东区面板
new SvgIconSource("cellelement_small", "com/fine/theme/icon/cellelement.svg"),
// 三角
new SvgIconSource("triangle_down", "com/fine/theme/icon/triangle/triangle_down.svg"),
new SvgIconSource("triangle_down_small", "com/fine/theme/icon/triangle/triangle_down_small.svg"),
new SvgIconSource("triangle_left", "com/fine/theme/icon/triangle/triangle_left.svg"),
new SvgIconSource("triangle_left_small", "com/fine/theme/icon/triangle/triangle_left_small.svg"),
new SvgIconSource("triangle_right", "com/fine/theme/icon/triangle/triangle_right.svg"),
new SvgIconSource("triangle_right_small", "com/fine/theme/icon/triangle/triangle_right_small.svg"),
// 滚动条
new SvgIconSource("zoomIn", "com/fine/theme/icon/zoom/zoomIn.svg", true),
new SvgIconSource("zoomOut", "com/fine/theme/icon/zoom/zoomOut.svg", true),
//排序
new SvgIconSource("sort_asc", "com/fine/theme/icon/sort/sort_asc.svg", true),
new SvgIconSource("sort_desc", "com/fine/theme/icon/sort/sort_desc.svg", true),
new SvgIconSource("nosort", "com/fine/theme/icon/sort/nosort.svg", true),
// 关闭
new SvgIconSource("close", "com/fine/theme/icon/close/close.svg", true),
new SvgIconSource("close_round", "com/fine/theme/icon/close/close_round.svg", true),
// 文字样式
new SvgIconSource("add_parenthesis", "com/fine/theme/icon/font/add_parenthesis.svg", true),
new SvgIconSource("remove_parenthesis", "com/fine/theme/icon/font/remove_parenthesis.svg", true),
new SvgIconSource("shadow", "com/fine/theme/icon/font/shadow.svg", true),
new SvgIconSource("strike", "com/fine/theme/icon/font/strike.svg", true),
new SvgIconSource("sub", "com/fine/theme/icon/font/sub.svg", true),
new SvgIconSource("super", "com/fine/theme/icon/font/super.svg", true),
new SvgIconSource("dot", "com/fine/theme/icon/dot.svg", true),
new SvgIconSource("expand_popup", "com/fine/theme/icon/popup/expand_popup.svg"),
new SvgIconSource("collapse_popup", "com/fine/theme/icon/popup/collapse_popup.svg"),
new SvgIconSource("logMsg", "com/fine/theme/icon/log/logMsg.svg", true),
new SvgIconSource("logMsg_dot", "com/fine/theme/icon/log/logMsg_dot.svg", true),
// 右键弹窗
new SvgIconSource("cellClear", "com/fine/theme/icon/cell/cellClear.svg", true),
new SvgIconSource("cellExpandAttr", "com/fine/theme/icon/cell/cellExpandAttr.svg", true),
new SvgIconSource("cellStyleAttr", "com/fine/theme/icon/cell/cellStyleAttr.svg", true),
new SvgIconSource("cellOtherAttr", "com/fine/theme/icon/cell/cellOtherAttr.svg", true),
new SvgIconSource("cellWidgetAttr", "com/fine/theme/icon/cell/cellWidgetAttr.svg", true),
new SvgIconSource("cellConditionalAttr", "com/fine/theme/icon/cell/cellConditionalAttr.svg", true),
new SvgIconSource("cellHyperLinkAttr", "com/fine/theme/icon/cell/cellHyperLinkAttr.svg", true),
new SvgIconSource("cellPresentAttr", "com/fine/theme/icon/cell/cellPresentAttr.svg", true),
new SvgIconSource("cellElementAttr", "com/fine/theme/icon/cell/cellElementAttr.svg", true),
new SvgIconSource("move", "com/fine/theme/icon/filetree/move.svg", true),
new SvgIconSource("monochrome_copy", "com/fine/theme/icon/filetree/monochrome_copy.svg", true),
new SvgIconSource("monochrome_paste", "com/fine/theme/icon/filetree/monochrome_paste.svg", true)
);
}
}

41
designer-base/src/main/java/com/fine/theme/light/ui/FineMenuItemUI.java

@ -0,0 +1,41 @@
package com.fine.theme.light.ui;
import com.fine.theme.utils.FineClientProperties;
import com.formdev.flatlaf.ui.FlatMenuItemUI;
import com.fr.design.editlock.EditLockUtils;
import javax.swing.JComponent;
import javax.swing.plaf.ComponentUI;
import java.awt.Graphics;
/**
* menuItem UI类
*
* @author Leo.Qin
* @since 11.0
* Created on 2024/1/8
*/
public class FineMenuItemUI extends FlatMenuItemUI {
int iconSize = 16;
int rightMargin = 10;
/**
* 创建UI
*
* @param c
* @return
*/
public static ComponentUI createUI(JComponent c) {
return new FineMenuItemUI();
}
@Override
public void paint(Graphics g, JComponent c) {
super.paint(g, c);
Object itemType = c.getClientProperty(FineClientProperties.MENU_ITEM_TYPE);
if (FineClientProperties.MENU_ITEM_TYPE_LOCK.equals(itemType)) {
g.drawImage(EditLockUtils.LOCKED_IMAGE, c.getWidth() - rightMargin - iconSize, (c.getHeight() - iconSize) / 2, iconSize, iconSize, null);
}
}
}

40
designer-base/src/main/java/com/fine/theme/light/ui/FineMenuUI.java

@ -0,0 +1,40 @@
package com.fine.theme.light.ui;
import com.fine.theme.icon.LazyIcon;
import com.formdev.flatlaf.ui.FlatMenuUI;
import javax.swing.JComponent;
import javax.swing.plaf.ComponentUI;
import java.awt.Graphics;
/**
* 弹窗菜单UI
*
* @author Leo.Qin
* @since 11.0
* Created on 2024/1/8
*/
public class FineMenuUI extends FlatMenuUI {
/**
* 创建UI
*
* @param c
* @return
*/
public static ComponentUI createUI(JComponent c) {
return new FineMenuUI();
}
@Override
protected void installDefaults() {
arrowIcon = new LazyIcon("triangle_right");
super.installDefaults();
}
@Override
public void paint(Graphics g, JComponent c) {
super.paint(g, c);
}
}

19
designer-base/src/main/java/com/fine/theme/light/ui/FinePopupMenuBorder.java

@ -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);
}
}

70
designer-base/src/main/java/com/fine/theme/light/ui/FinePopupMenuSeparatorUI.java

@ -0,0 +1,70 @@
package com.fine.theme.light.ui;
import com.fine.theme.utils.FineUIUtils;
import com.formdev.flatlaf.ui.FlatPopupMenuSeparatorUI;
import com.formdev.flatlaf.ui.FlatUIUtils;
import javax.swing.JComponent;
import javax.swing.JSeparator;
import javax.swing.plaf.ComponentUI;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.geom.Rectangle2D;
import static com.formdev.flatlaf.util.UIScale.scale;
/**
* popup弹窗分割线UI
*
* @author Leo.Qin
* @since 11.0
* Created on 2024/1/8
*/
public class FinePopupMenuSeparatorUI extends FlatPopupMenuSeparatorUI {
protected Insets insets;
/**
* @param shared
* @since 2
*/
protected FinePopupMenuSeparatorUI(boolean shared) {
super(shared);
}
/**
* 创建UI类
*
* @param c
* @return
*/
public static ComponentUI createUI(JComponent c) {
return new FinePopupMenuSeparatorUI(false);
}
@Override
protected void installDefaults(JSeparator s) {
super.installDefaults(s);
insets = FineUIUtils.getAndScaleUIInsets("PopupMenuSeparator.Insets", new Insets(0, 10, 0, 10));
}
@Override
public void paint(Graphics g, JComponent c) {
Graphics2D g2 = (Graphics2D) g.create();
try {
FlatUIUtils.setRenderingHints(g2);
g2.setColor(c.getForeground());
float width = scale((float) stripeWidth);
float indent = scale((float) stripeIndent);
if (((JSeparator) c).getOrientation() == JSeparator.VERTICAL) {
g2.fill(new Rectangle2D.Float(indent, insets.left, width - (insets.left + insets.right), c.getHeight()));
} else {
g2.fill(new Rectangle2D.Float(insets.left, indent, c.getWidth() - (insets.left + insets.right), width));
}
} finally {
g2.dispose();
}
}
}

58
designer-base/src/main/java/com/fine/theme/light/ui/FinePopupMenuUI.java

@ -0,0 +1,58 @@
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 = 10;
/**
* 创建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);
}
}

28
designer-base/src/main/java/com/fine/theme/light/ui/FineReportComponentBorder.java

@ -0,0 +1,28 @@
package com.fine.theme.light.ui;
import com.fine.theme.utils.FineUIUtils;
import com.formdev.flatlaf.ui.FlatRoundBorder;
import javax.swing.UIManager;
import java.awt.Color;
import java.awt.Component;
/**
* 报表编辑区域边框
*
* @author Leo.Qin
* @since 11.0
* Created on 2024/1/2
*/
public class FineReportComponentBorder extends FlatRoundBorder {
@Override
protected int getArc(Component c) {
return FineUIUtils.getAndScaleInt("Center.arc", 10);
}
@Override
protected Color getBorderColor(Component c) {
return UIManager.getColor("Center.ZoneBorderColor");
}
}

40
designer-base/src/main/java/com/fine/theme/light/ui/FineReportComponentCompositeUI.java

@ -0,0 +1,40 @@
package com.fine.theme.light.ui;
import com.fine.theme.utils.FineUIUtils;
import com.formdev.flatlaf.ui.FlatPanelUI;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.plaf.ComponentUI;
/**
* 报表编辑区域UI
*
* @author Leo.Qin
* @since 11.0
* Created on 2024/1/2
*/
public class FineReportComponentCompositeUI extends FlatPanelUI {
/**
* @param shared
* @since 2
*/
protected FineReportComponentCompositeUI(boolean shared) {
super(shared);
}
/**
* 创建UI
*/
public static ComponentUI createUI(JComponent c) {
return new FineReportComponentCompositeUI(false);
}
@Override
protected void installDefaults(JPanel p) {
super.installDefaults(p);
this.arc = FineUIUtils.getAndScaleInt("Center.arc", 10);
}
}

63
designer-base/src/main/java/com/fine/theme/light/ui/FineRoundBorder.java

@ -0,0 +1,63 @@
package com.fine.theme.light.ui;
import com.fine.theme.utils.FineUIUtils;
import com.formdev.flatlaf.ui.FlatRoundBorder;
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
import com.fr.design.event.HoverAware;
import java.awt.Color;
import java.awt.Component;
import java.awt.Paint;
import java.util.StringJoiner;
/**
* 通用的Border类具备hoverclick禁用等多种状态
*
* @author Levy.Xie
* @since 11.0
* Created on 2023/12/06
*/
public class FineRoundBorder extends FlatRoundBorder {
@Styleable(dot = true)
protected Color borderColor = FineUIUtils.getUIColor("defaultBorderColor", "Component.borderColor");
@Styleable(dot = true)
protected Color disabledBorderColor = FineUIUtils.getUIColor("defaultBorderColor", "Component.disabledBorderColor");
@Styleable(dot = true)
protected Color highlightBorderColor = FineUIUtils.getUIColor("defaultHighlightBorderColor", "Component.focusedBorderColor");
@Styleable(dot = true)
protected Color focusColor = FineUIUtils.getUIColor("defaultBorderFocusShadow", "Component.focusedBorderColor");
@Override
protected Paint getBorderColor(Component c) {
if (isEnabled(c)) {
if (c instanceof HoverAware && ((HoverAware) c).isHovered()) {
return getHoverBorderColor();
} else {
return isFocused(c) ? focusedBorderColor : borderColor;
}
}
return disabledBorderColor;
}
@Override
protected Color getFocusColor(Component c) {
return focusColor;
}
protected Color getHoverBorderColor() {
return highlightBorderColor;
}
@Override
public String toString() {
return new StringJoiner(", ", FineRoundBorder.class.getSimpleName() + "[", "]")
.add("borderColor=" + borderColor)
.add("arc=" + arc)
.add("roundRect=" + roundRect)
.add("borderWidth=" + borderWidth)
.toString();
}
}

49
designer-base/src/main/java/com/fine/theme/light/ui/FineSelectBoxUI.java

@ -0,0 +1,49 @@
package com.fine.theme.light.ui;
import com.fine.theme.utils.FineUIUtils;
import javax.swing.JComponent;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.PanelUI;
import java.awt.Dimension;
/**
* 选择框面板UI应用于 {@link com.fr.design.style.AbstractSelectBox}
*
* @author Levy.Xie
* @since 11.0
* Created on 2023/12/15
*/
public class FineSelectBoxUI extends PanelUI {
private static final int DEFAULT_BOX_HEIGHT = 24;
protected int boxHeight;
/**
* 创建UI
*
* @param c 组件
* @return ComponentUI
*/
public static ComponentUI createUI(JComponent c) {
return new FineSelectBoxUI();
}
@Override
public void installUI(JComponent c) {
super.installUI(c);
boxHeight = FineUIUtils.getAndScaleInt("ComboBox.comboHeight", DEFAULT_BOX_HEIGHT);
c.setBorder(new FineRoundBorder());
}
@Override
public void uninstallUI(JComponent c) {
super.uninstallUI(c);
}
@Override
public Dimension getPreferredSize(JComponent c) {
return new Dimension(c.getWidth(), boxHeight);
}
}

344
designer-base/src/main/java/com/fine/theme/light/ui/FineSliderUI.java

@ -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;
}
}

393
designer-base/src/main/java/com/fine/theme/light/ui/FineTemplateTabPaneUI.java

@ -0,0 +1,393 @@
package com.fine.theme.light.ui;
import com.fine.theme.icon.LazyIcon;
import com.fine.theme.utils.FineUIUtils;
import com.formdev.flatlaf.ui.FlatUIUtils;
import com.fr.base.GraphHelper;
import com.fr.base.vcs.DesignerMode;
import com.fr.design.file.MultiTemplateTabPane;
import com.fr.stable.collections.combination.Pair;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.PanelUI;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.geom.Path2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import static com.fine.theme.utils.FineUIScale.scale;
import static com.fine.theme.utils.FineUIUtils.paintRoundTabBorder;
import static com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
import static com.fr.design.file.MultiTemplateTabPane.LEADING_WIDTH;
import static com.fr.design.file.MultiTemplateTabPane.TRAILING_WIDTH;
/**
* 文件Tab栏UI
*
* @author vito
* @since 11.0
* Created on 2023/12/27
*/
public class FineTemplateTabPaneUI extends PanelUI {
private MultiTemplateTabPane tabPane;
private static final String ELLIPSIS = "...";
private static final int ICON_TEXT_GAP = 4;
@Styleable(dot = true)
protected Color background;
@Styleable(dot = true)
protected Color selectedBackground;
@Styleable(dot = true)
protected Color hoverColor;
@Styleable(dot = true)
protected Color closeIconHoverBackground;
@Styleable(dot = true)
protected Color closeHoverBackground;
@Styleable(dot = true)
protected Color borderColor;
@Styleable(dot = true)
protected int tabHeight;
@Styleable(dot = true)
protected int separatorHeight;
@Styleable(dot = true)
protected int borderWidth;
@Styleable(dot = true)
protected int tabArc;
@Styleable(dot = true)
protected Insets tabInsets;
protected Icon fileIcon;
protected Icon moreAction;
protected Icon addAction;
protected Icon moreHoverAction;
private Icon closeIcon;
private Icon closeHoverIcon;
private int leadingWidth;
private int trailingWidth;
protected FineTemplateTabPaneUI() {
}
/**
* 创建UI
*
* @param c 组件
* @return ComponentUI
*/
public static ComponentUI createUI(JComponent c) {
return new FineTemplateTabPaneUI();
}
@Override
public void installUI(JComponent c) {
super.installUI(c);
this.tabPane = (MultiTemplateTabPane) c;
closeIcon = new LazyIcon("clear");
closeHoverIcon = new LazyIcon("clear_hover");
addAction = new LazyIcon("add_worksheet");
moreAction = new LazyIcon("tool_more");
moreHoverAction = new LazyIcon("tool_more_hover");
fileIcon = new LazyIcon("cpt_icon");
leadingWidth = scale(LEADING_WIDTH);
trailingWidth = scale(TRAILING_WIDTH);
borderWidth = FineUIUtils.getUIInt("TemplateTabPane.borderWidth", "TemplateTabPane.borderWidth");
tabArc = FineUIUtils.getUIInt("TemplateTabPane.tabArc", "TemplateTabPane.tabArc");
background = FineUIUtils.getUIColor("TemplateTabPane.background", "TabbedPane.background");
selectedBackground = FineUIUtils.getUIColor("TemplateTabPane.selectedBackground", "TemplateTabPane.selectedBackground");
closeHoverBackground = FineUIUtils.getUIColor("TemplateTabPane.closeHoverBackground", "TemplateTabPane.closeHoverBackground");
borderColor = FineUIUtils.getUIColor("TemplateTabPane.borderColor", "TabbedPane.tabSeparatorColor");
hoverColor = FineUIUtils.getUIColor("TemplateTabPane.hoverColor", "TemplateTabPane.hoverColor");
closeIconHoverBackground = FineUIUtils.getUIColor("TemplateTabPane.icon.hoverBackground ", "TemplateTabPane.icon.hoverBackground ");
// ---- scaled ----
tabInsets = FineUIUtils.getAndScaleUIInsets("TemplateTabPane.tabInsets", new Insets(4, 6, 4, 6));
tabHeight = FineUIUtils.getAndScaleInt("TemplateTabPane.tabHeight", "TabbedPane.tabHeight");
separatorHeight = FineUIUtils.getAndScaleInt("TemplateTabPane.separatorHeight", "TemplateTabPane.separatorHeight");
}
@Override
public void uninstallUI(JComponent c) {
super.uninstallUI(c);
}
@Override
public void update(Graphics g, JComponent c) {
super.update(g, c);
double maxWidth = c.getWidth() - leadingWidth - trailingWidth;
Graphics2D g2d = (Graphics2D) g;
paintDefaultBackground(g2d);
paintPaneUnderLine(c.getWidth(), g2d);
paintTabs(g2d, maxWidth);
}
private void paintDefaultBackground(Graphics2D g2d) {
//画默认背景
g2d.setPaint(new GradientPaint(0, 0, tabPane.getBackground(), 1, (float) (tabHeight), tabPane.getBackground()));
g2d.fillRect(0, 0, tabPane.getWidth(), tabHeight);
}
private void paintPaneUnderLine(float w, Graphics2D g2d) {
g2d.setPaint(borderColor);
float h = (float) tabHeight;
int t = scale(borderWidth);
Path2D border = new Path2D.Float(Path2D.WIND_EVEN_ODD);
border.append(FlatUIUtils.createComponentRectangle(0, 0, w, h, 0), false);
border.append(FlatUIUtils.createComponentRectangle(0, 0, w, h - t, 0), false);
g2d.fill(border);
}
private void paintTabs(Graphics2D g2d, double maxWidth) {
int maxStringlength = calculateStringMaxLength();
if (tabPane.getSelectedIndex() >= tabPane.getTabCount()) {
tabPane.setSelectedIndex(tabPane.getTabCount() - 1);
}
if (tabPane.getSelectedIndex() < 0) {
tabPane.setSelectedIndex(0);
}
double templateStartX = leadingWidth;
//从可以开始展示在tab面板上的tab开始画
Pair<Integer, Integer> viewRange = tabPane.getViewRange();
for (int i = viewRange.getFirst(); i <= viewRange.getSecond(); i++) {
Icon icon = tabPane.getTemplateIconByIndex(i);
String name = tabPane.getTemplateShowNameByIndex(i);
//如果tab名字的长度大于最大能显示的英文字符长度,则进行省略号处理
if (getStringWidth(name) > maxStringlength) {
name = getEllipsisName(name, maxStringlength);
}
Icon tabcloseIcon = tabPane.isCloseCurrent(i) ? closeHoverIcon : closeIcon;
if (i == tabPane.getSelectedIndex()) {
paintSelectedTab(g2d, icon, templateStartX, name, tabcloseIcon);
} else {
paintUnSelectedTab(g2d, icon, templateStartX, name, tabcloseIcon,
tabPane.getHoverIndex(), i);
}
templateStartX += tabPane.getTabWidth();
}
paintSeparators(g2d);
if (!DesignerMode.isVcsMode()) {
paintTrailingAction(g2d, maxWidth);
}
}
private void paintSeparators(Graphics2D g2d) {
g2d.setPaint(borderColor);
float x = leadingWidth;
Pair<Integer, Integer> viewRange = tabPane.getViewRange();
for (int i = viewRange.getFirst(); i <= viewRange.getSecond(); i++) {
if (i != tabPane.getSelectedIndex()
&& i + 1 != tabPane.getSelectedIndex()) {
paintSeparator(g2d, x);
}
x += tabPane.getTabWidth();
}
}
private void paintTrailingAction(Graphics2D g2d, double tabPaneWidth) {
int x = leadingWidth + (int) tabPaneWidth + (trailingWidth - moreAction.getIconWidth()) / 2;
int y = (tabHeight - moreAction.getIconHeight()) / 2;
if (tabPane.isHoverMoreAction()) {
moreHoverAction.paintIcon(tabPane, g2d, x, y);
} else {
moreAction.paintIcon(tabPane, g2d, x, y);
}
}
/**
* 判断tab文字的长度大于能装下的最大文字长度要用省略号
*
* @param name
* @param maxStringlength
* @return
*/
private String getEllipsisName(String name, int maxStringlength) {
int ellipsisWidth = getStringWidth(ELLIPSIS);
int leftkeyPoint = 0;
int rightKeyPoint = name.length() - 1;
int leftStrWidth = 0;
int rightStrWidth = 0;
while (leftStrWidth + rightStrWidth + ellipsisWidth < maxStringlength) {
if (leftStrWidth <= rightStrWidth) {
leftkeyPoint++;
} else {
rightKeyPoint--;
}
leftStrWidth = getStringWidth(name.substring(0, leftkeyPoint));
rightStrWidth = getStringWidth(name.substring(rightKeyPoint));
if (leftStrWidth + rightStrWidth + ellipsisWidth > maxStringlength) {
if (leftStrWidth <= rightStrWidth) {
rightKeyPoint++;
} else {
leftkeyPoint--;
}
break;
}
}
return name.substring(0, leftkeyPoint) + ELLIPSIS + name.substring(rightKeyPoint);
}
/**
* 计算过长度之后的每个tab的能接受的文字的英文字符数
*
* @return
*/
private int calculateStringMaxLength() {
return tabPane.getTabWidth()
- tabInsets.left - tabInsets.right
- ICON_TEXT_GAP * 2
- fileIcon.getIconWidth() - closeIcon.getIconWidth();
}
private int getStringWidth(String str) {
FontMetrics fm = GraphHelper.getFontMetrics(tabPane.getFont());
int size = 0;
for (int i = 0; i < str.length(); i++) {
size += fm.charWidth(str.codePointAt(i));
}
return size;
}
/**
* 画选中的tab
*
* @param g2d
* @param sheeticon
* @param templateStartX
* @param sheetName
* @param closeIcon
* @return
*/
private void paintSelectedTab(Graphics2D g2d, Icon sheeticon, double templateStartX, String sheetName, Icon closeIcon) {
Object[] oriRenderingHints = FlatUIUtils.setRenderingHints(g2d);
// 绘制选中背景
g2d.setPaint(selectedBackground);
Path2D tabShape = FineUIUtils.createTopRoundRectangle(templateStartX, 0,
tabPane.getTabWidth(), tabHeight, tabArc);
g2d.fill(tabShape);
// 绘制选中边框
g2d.setPaint(borderColor);
paintRoundTabBorder(g2d, templateStartX, 0,
tabPane.getTabWidth(), tabHeight, borderWidth, (float) tabArc);
FlatUIUtils.resetRenderingHints(g2d, oriRenderingHints);
// 绘制图标
int sheetIconY = (tabHeight - sheeticon.getIconHeight()) / 2;
sheeticon.paintIcon(tabPane, g2d, (int) templateStartX + tabInsets.left, sheetIconY);
// 绘制字符
g2d.setPaint(tabPane.getForeground());
Point2D.Double textPoint = calTextPoint(templateStartX, sheeticon.getIconWidth());
g2d.drawString(sheetName, (int) textPoint.x, (int) textPoint.y);
int closePosition = (int) templateStartX + tabPane.getTabWidth()
- this.closeIcon.getIconWidth() - tabInsets.right;
int closeY = (tabHeight - closeIcon.getIconHeight()) / 2;
if (!DesignerMode.isVcsMode()) {
closeIcon.paintIcon(tabPane, g2d, closePosition, closeY);
}
}
private Point2D.Double calTextPoint(double x, int iconWidth) {
FontMetrics fm = tabPane.getFontMetrics(tabPane.getFont());
int ascent = fm.getAscent();
int gap = (tabHeight - tabInsets.top - tabInsets.bottom - ascent) / 2;
double y = tabInsets.top + ascent + gap;
return new Point2D.Double(x + iconWidth + tabInsets.left + ICON_TEXT_GAP, y);
}
/**
* 画没有选中的tab
*
* @param g2d
* @param sheeticon
* @param templateStartX
* @param sheetName
* @param closeIcon
*/
private void paintUnSelectedTab(Graphics2D g2d, Icon sheeticon, double templateStartX, String sheetName, Icon closeIcon, int mouseOveredIndex, int selfIndex) {
if (selfIndex == mouseOveredIndex) {
g2d.setPaint(hoverColor);
} else {
g2d.setPaint(background);
}
Object[] oriRenderingHints = FlatUIUtils.setRenderingHints(g2d);
Path2D tabShape = FineUIUtils.createTopRoundRectangle(templateStartX, 0,
tabPane.getTabWidth(), tabHeight - scale(borderWidth), tabArc);
g2d.fill(tabShape);
FlatUIUtils.resetRenderingHints(g2d, oriRenderingHints);
int sheetIconY = (tabHeight - sheeticon.getIconHeight()) / 2;
sheeticon.paintIcon(tabPane, g2d, (int) templateStartX + tabInsets.left, sheetIconY);
// 画字符
g2d.setPaint(tabPane.getForeground());
Point2D.Double textPoint = calTextPoint(templateStartX, sheeticon.getIconWidth());
g2d.drawString(sheetName, (int) textPoint.x, (int) textPoint.y);
int closeY = (tabHeight - closeIcon.getIconHeight()) / 2;
int closePosition = (int) templateStartX + tabPane.getTabWidth()
- this.closeIcon.getIconWidth() - tabInsets.right;
if (!DesignerMode.isVcsMode()) {
closeIcon.paintIcon(tabPane, g2d, closePosition, closeY);
}
}
private void paintSeparator(Graphics2D g2d, float templateStartX) {
float x = templateStartX + tabPane.getTabWidth();
float gap = (tabHeight - separatorHeight) / 2.0f;
g2d.fill(new Rectangle2D.Float(x, gap, scale(borderWidth), tabHeight - gap * 2));
}
@Override
public Dimension getPreferredSize(JComponent c) {
return new Dimension(c.getWidth(), tabHeight);
}
@Override
public Dimension getMinimumSize(JComponent c) {
return new Dimension(0, tabHeight);
}
@Override
public Dimension getMaximumSize(JComponent c) {
return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
}
}

213
designer-base/src/main/java/com/fine/theme/light/ui/FineToggleButtonUI.java

@ -0,0 +1,213 @@
package com.fine.theme.light.ui;
import com.fine.theme.utils.FineUIUtils;
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
import com.formdev.flatlaf.ui.FlatToggleButtonUI;
import com.formdev.flatlaf.ui.FlatUIUtils;
import com.fr.design.gui.ibutton.UIButton;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.AbstractButton;
import javax.swing.JComponent;
import javax.swing.JToggleButton;
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.Shape;
import java.awt.Rectangle;
import static com.fine.theme.utils.FineClientProperties.BUTTON_TYPE_GROUP;
import static com.fine.theme.utils.FineClientProperties.BUTTON_TYPE;
import static com.fine.theme.utils.FineClientProperties.BUTTON_TYPE_TAB;
import static com.fine.theme.utils.FineClientProperties.BUTTON_GROUP_POSITION;
import static com.fine.theme.utils.FineClientProperties.GROUP_BUTTON_POSITION_INNER;
import static com.fine.theme.utils.FineClientProperties.GROUP_BUTTON_POSITION_LEFT;
import static com.fine.theme.utils.FineClientProperties.GROUP_BUTTON_POSITION_LEFT_BOTTOM;
import static com.fine.theme.utils.FineClientProperties.GROUP_BUTTON_POSITION_LEFT_TOP;
import static com.fine.theme.utils.FineClientProperties.GROUP_BUTTON_POSITION_RIGHT;
import static com.fine.theme.utils.FineClientProperties.GROUP_BUTTON_POSITION_RIGHT_BOTTOM;
import static com.fine.theme.utils.FineClientProperties.GROUP_BUTTON_POSITION_RIGHT_TOP;
import static com.fine.theme.utils.FineClientProperties.TAB_BUTTON_SELECTED_BACKGROUND;
import static com.formdev.flatlaf.FlatClientProperties.clientPropertyColor;
import static com.formdev.flatlaf.FlatClientProperties.clientPropertyInt;
/**
* 提供 {@link javax.swing.JToggleButton} 的UI类
* <p>
*
* @author vito
* @uiDefault ToggleButton.tab.arc int
* @since 11.0
* Created on 2023/11/3
*/
public class FineToggleButtonUI extends FlatToggleButtonUI {
@Styleable(dot = true)
protected int tabArc;
@Styleable(dot = true)
protected Color groupBackground;
@Styleable(dot = true)
protected Color groupSelectedBackground;
@Styleable(dot = true)
protected Color groupSelectedForeground;
public static ComponentUI createUI(JComponent c) {
return FlatUIUtils.canUseSharedUI(c)
? FlatUIUtils.createSharedUI(FlatToggleButtonUI.class, () -> new FineToggleButtonUI(true))
: new FineToggleButtonUI(false);
}
protected FineToggleButtonUI(boolean shared) {
super(shared);
}
@Override
protected void installDefaults(AbstractButton b) {
super.installDefaults(b);
tabArc = UIManager.getInt("ToggleButton.tab.arc");
groupBackground = FineUIUtils.getUIColor("ToggleButton.group.background", "ToggleButton.background");
groupSelectedBackground = FineUIUtils.getUIColor("ToggleButton.group.selectedBackground", "ToggleButton.selectedBackground");
groupSelectedForeground = FineUIUtils.getUIColor("ToggleButton.group.selectedForeground", "ToggleButton.selectedForeground");
}
@Nullable
static String getButtonTypeStr(AbstractButton c) {
Object value = c.getClientProperty(BUTTON_TYPE);
if (value instanceof String)
return (String) value;
return null;
}
static int getGroupButtonPosition(AbstractButton c) {
return clientPropertyInt(c, BUTTON_GROUP_POSITION, GROUP_BUTTON_POSITION_INNER);
}
static boolean isTabButton(Component c) {
return c instanceof JToggleButton && BUTTON_TYPE_TAB.equals(getButtonTypeStr((JToggleButton) c));
}
static boolean isGroupButton(Component c) {
return c instanceof UIButton && BUTTON_TYPE_GROUP.equals(getButtonTypeStr((UIButton) c));
}
@Override
public void paint(Graphics g, JComponent c) {
if (isGroupButton(c) || isTabButton(c)) {
((AbstractButton)c).setMargin(FineUIUtils.getUIInsets("ToggleButton.compact.margin", "ToggleButton.margin"));
}
super.paint(g, c);
}
@Override
protected void paintBackground(Graphics g, JComponent c) {
if (isTabButton(c)) {
paintTabButton(g, c);
} else if (isGroupButton(c)) {
paintGroupButton(g, c);
} else {
super.paintBackground(g, c);
}
}
protected void paintTabButton(Graphics g, JComponent c) {
int height = c.getHeight();
int width = c.getWidth();
boolean selected = ((AbstractButton) c).isSelected();
Color enabledColor = selected ? clientPropertyColor(c, TAB_BUTTON_SELECTED_BACKGROUND, tabSelectedBackground) : null;
// use component background if explicitly set
if (enabledColor == null) {
Color bg = c.getBackground();
if (isCustomBackground(bg)) {
enabledColor = bg;
}
}
// paint background
Color background = buttonStateColor(c, enabledColor,
null, tabFocusBackground, tabHoverBackground, null);
if (background != null) {
g.setColor(background);
g.fillRoundRect(0, 0, width, height, tabArc, tabArc);
}
}
protected void paintGroupButton(Graphics g, JComponent c) {
Color background = getBackground(c);
if (background == null) {
return;
}
Graphics2D g2 = (Graphics2D) g.create();
try {
FlatUIUtils.setRenderingHints(g2);
g2.setColor(FlatUIUtils.deriveColor(background, getBackgroundBase(c, true)));
int position = getGroupButtonPosition((AbstractButton) c);
if (position == GROUP_BUTTON_POSITION_INNER) {
float focusWidth = FlatUIUtils.getBorderFocusWidth(c);
FlatUIUtils.paintComponentBackground(g2, 0, 0, c.getWidth(), c.getHeight(), focusWidth, 0);
} else {
float arc = FlatUIUtils.getBorderArc( c ) / 2;
Shape path2D = getGroupButtonPath2D(c, position, arc);
g2.fill(path2D);
}
} finally {
g2.dispose();
}
}
@NotNull
private static Shape getGroupButtonPath2D(JComponent c, int position, float arc) {
Shape path2D;
switch (position) {
case GROUP_BUTTON_POSITION_LEFT:
path2D = FineUIUtils.createLeftRoundRectangle(0, 0, c.getWidth(), c.getHeight(), arc);
break;
case GROUP_BUTTON_POSITION_RIGHT:
path2D = FineUIUtils.createRightRoundRectangle(0, 0, c.getWidth(), c.getHeight(), arc);
break;
case GROUP_BUTTON_POSITION_LEFT_TOP:
path2D = FineUIUtils.createTopLeftRoundRectangle(0, 0, c.getWidth(), c.getHeight(), arc);
break;
case GROUP_BUTTON_POSITION_LEFT_BOTTOM:
path2D = FineUIUtils.createBottomLeftRoundRectangle(0, 0, c.getWidth(), c.getHeight(), arc);
break;
case GROUP_BUTTON_POSITION_RIGHT_TOP:
path2D = FineUIUtils.createTopRightRoundRectangle(0, 0, c.getWidth(), c.getHeight(), arc);
break;
case GROUP_BUTTON_POSITION_RIGHT_BOTTOM:
path2D = FineUIUtils.createBottomRightRoundRectangle(0, 0, c.getWidth(), c.getHeight(), arc);
break;
default:
path2D = new Rectangle();
}
return path2D;
}
@Override
protected Color getForeground(JComponent c) {
if (isGroupButton(c) && ((AbstractButton)c).isSelected()) {
return groupSelectedForeground;
}
return super.getForeground(c);
}
@Override
protected Color getBackground(JComponent c) {
if (isGroupButton(c)) {
return ((AbstractButton)c).isSelected() ? groupSelectedBackground : groupBackground;
}
return super.getBackground(c);
}
}

102
designer-base/src/main/java/com/fine/theme/light/ui/FineTooltipUI.java

@ -0,0 +1,102 @@
package com.fine.theme.light.ui;
import com.fine.theme.utils.FineUIScale;
import com.fine.theme.utils.FineUIUtils;
import com.formdev.flatlaf.ui.FlatToolTipUI;
import com.formdev.flatlaf.ui.FlatUIUtils;
import com.fr.base.BaseUtils;
import com.fr.stable.Constants;
import javax.swing.JComponent;
import javax.swing.JToolTip;
import javax.swing.SwingUtilities;
import javax.swing.plaf.ComponentUI;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.RenderingHints;
import java.util.List;
/**
* ToolTip UI类
*
* @author Leo.Qin
* @since 11.0
* Created on 2023/12/8
*/
public class FineTooltipUI extends FlatToolTipUI {
private final int defaultMaxWidth = 392;
private final int defaultArc = 5;
private int maxWidth;
private int arc;
private List<String> lines;
/**
* 创建UI
*/
public static ComponentUI createUI(JComponent c) {
return FlatUIUtils.createSharedUI(FineTooltipUI.class, FineTooltipUI::new);
}
@Override
public void paint(Graphics g, JComponent c) {
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(c.getBackground());
g2d.fillRoundRect(0, 0, c.getWidth(), c.getHeight(), arc, arc);
String text = ((JToolTip) c).getTipText();
if (text == null || text.isEmpty()) {
return;
}
Insets insets = c.getInsets();
FontMetrics fm = g2d.getFontMetrics();
int x = insets.left;
int y = insets.top + fm.getAscent();
g2d.setColor(c.getForeground());
for (String line : lines) {
g2d.drawString(line, x, y);
y += fm.getHeight();
}
}
@Override
protected void installDefaults(JComponent c) {
super.installDefaults(c);
c.setOpaque(false);
arc = FineUIScale.scale(FineUIUtils.getAndScaleInt("ToolTip.arc", defaultArc));
maxWidth = FineUIUtils.getAndScaleInt("ToolTip.maxWidth", defaultMaxWidth);
}
@Override
public Dimension getPreferredSize(JComponent c) {
String text = ((JToolTip) c).getTipText();
if (text == null || text.isEmpty()) {
return new Dimension();
}
Insets insets = c.getInsets();
int fontWidth = this.maxWidth - insets.left - insets.right;
lines = BaseUtils.getLineTextList(text, null, null, fontWidth, Constants.FR_PAINT_RESOLUTION);
FontMetrics fm = c.getFontMetrics(c.getFont());
int width = 0;
int height = fm.getHeight() * Math.max(lines.size(), 1);
for (String line : lines) {
width = Math.max(width, SwingUtilities.computeStringWidth(fm, line));
}
return new Dimension(insets.left + width + insets.right, insets.top + height + insets.bottom);
}
}

39
designer-base/src/main/java/com/fine/theme/light/ui/RectangleButtonUI.java

@ -0,0 +1,39 @@
package com.fine.theme.light.ui;
import com.formdev.flatlaf.ui.FlatButtonUI;
import com.formdev.flatlaf.ui.FlatUIUtils;
import javax.swing.JComponent;
import java.awt.*;
/**
* 矩形按钮UI忽略圆角属性
*
* @author Levy.Xie
* @since 11.0
* Created on 2023/11/30
*/
public class RectangleButtonUI extends FlatButtonUI {
public RectangleButtonUI(boolean shared) {
super(shared);
}
@Override
protected void paintBackground(Graphics g, JComponent c) {
Color background = getBackground(c);
if (background == null) {
return;
}
Graphics2D g2 = (Graphics2D) g.create();
try {
FlatUIUtils.setRenderingHints(g2);
g2.setColor(FlatUIUtils.deriveColor(background, getBackgroundBase(c, true)));
float focusWidth = FlatUIUtils.getBorderFocusWidth(c);
FlatUIUtils.paintComponentBackground(g2, 0, 0, c.getWidth(), c.getHeight(), focusWidth, 0);
} finally {
g2.dispose();
}
}
}

92
designer-base/src/main/java/com/fine/theme/light/ui/ReportScrollBarUI.java

@ -0,0 +1,92 @@
package com.fine.theme.light.ui;
import com.formdev.flatlaf.ui.FlatScrollBarUI;
import com.formdev.flatlaf.ui.FlatUIUtils;
import javax.swing.JComponent;
import javax.swing.JButton;
import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
/**
* 应用于主面板报表工作区的滚动条UI提供给 {@link com.fr.design.cell.bar.DynamicScrollBar} 的UI类
*
* @author Levy.Xie
* @since 11.0`
* Created on 2023/12/08
*/
public class ReportScrollBarUI extends FlatScrollBarUI {
/**
* 创建UI类
*
* @param c 组件
* @return ReportScrollBarUI
*/
public static ComponentUI createUI(JComponent c) {
return new ReportScrollBarUI();
}
@Override
public void installUI(JComponent c) {
super.installUI(c);
scrollBarWidth = UIManager.getInt("ScrollBar.largeBar.width");
thumbInsets = UIManager.getInsets("ScrollBar.largeBar.thumbInsets");
showButtons = UIManager.getBoolean("ScrollBar.largeBar.showButtons");
trackColor = UIManager.getColor("ScrollBar.largeBar.track");
}
@Override
public void uninstallUI(JComponent c) {
super.uninstallUI(c);
}
@Override
protected JButton createDecreaseButton(int orientation) {
return new ReportScrollBarButton(orientation);
}
@Override
protected JButton createIncreaseButton(int orientation) {
return new ReportScrollBarButton(orientation);
}
protected class ReportScrollBarButton extends FlatScrollBarButton {
protected final Color defaultButtonBackground = UIManager.getColor("ScrollBar.largeBar.buttonBackground");
protected ReportScrollBarButton(int direction) {
super(direction);
}
@Override
public void paint(Graphics g) {
Object[] oldRenderingHints = FlatUIUtils.setRenderingHints(g);
// paint hover or pressed background
if (isEnabled()) {
Color background = (pressedBackground != null && isPressed())
? pressedBackground
: (hoverBackground != null && isHover()
? hoverBackground
: null);
if (background == null) {
background = defaultButtonBackground;
}
g.setColor(deriveBackground(background));
paintBackground((Graphics2D) g);
}
// paint arrow
g.setColor(deriveForeground(getArrowColor()));
paintArrow((Graphics2D) g);
FlatUIUtils.resetRenderingHints(g, oldRenderingHints);
}
}
}

32
designer-base/src/main/java/com/fine/theme/light/ui/UIFlatTreeUI.java

@ -0,0 +1,32 @@
package com.fine.theme.light.ui;
import com.fine.theme.icon.LazyIcon;
import com.formdev.flatlaf.ui.FlatTreeUI;
import javax.swing.JComponent;
import javax.swing.plaf.ComponentUI;
/**
* 主题化的TreeUI继承自FlatTreeUI
*
* @author Levy.Xie
* @since 11.0
* Created on 2023/11/29
*/
public class UIFlatTreeUI extends FlatTreeUI {
/**
* 创建组件UI
* @param x 组件
* @return 返回组件UI
*/
public static ComponentUI createUI(JComponent x) {
return new UIFlatTreeUI();
}
protected void installDefaults() {
super.installDefaults();
setExpandedIcon(new LazyIcon("minus"));
setCollapsedIcon(new LazyIcon("plus"));
}
}

52
designer-base/src/main/java/com/fine/theme/light/ui/laf/FineDarkLaf.java

@ -0,0 +1,52 @@
package com.fine.theme.light.ui.laf;
import com.fine.swing.ui.layout.Layouts;
import com.fine.theme.icon.IconManager;
import com.fine.theme.light.ui.FineLightIconSet;
import com.formdev.flatlaf.util.UIScale;
import com.fr.stable.StringUtils;
/**
* Fine 暗色主题
*
* @author vito
* @since 11.0
* Created on 2023/9/12
*/
public class FineDarkLaf extends FineLaf {
private static final String USER_SCALE_FACTOR = "userScaleFactor";
private static final String NAME = "FineLaf Dark";
/**
* 安装外观
*
* @return 是否安装成功
*/
public static boolean setup() {
IconManager.addSet(new FineLightIconSet("fine-dark"));
Layouts.setScaleFactor(UIScale.getUserScaleFactor());
UIScale.addPropertyChangeListener(evt -> {
if (StringUtils.equals(evt.getPropertyName(), USER_SCALE_FACTOR)) {
Layouts.setScaleFactor((float) evt.getNewValue());
}
});
return setup(new FineDarkLaf());
}
@Override
public String getName() {
return NAME;
}
@Override
public String getDescription() {
return "Fine New Dark Look and Feel";
}
@Override
public boolean isDark() {
return true;
}
}

38
designer-base/src/main/java/com/fine/theme/light/ui/laf/FineLaf.java

@ -0,0 +1,38 @@
package com.fine.theme.light.ui.laf;
import com.formdev.flatlaf.FlatLaf;
import javax.swing.PopupFactory;
/**
* Fine designer new look and feel
* FineLaf.properties 定义公共属性如UI等
* 其他主题继承该主题进行自定义防止出现UI不存在等问题
*
* @author vito
* @since 11.0
* Created on 2023/12/18
*/
public abstract class FineLaf extends FlatLaf {
private static final String NAME = "FineLaf";
@Override
public String getName() {
return NAME;
}
@Override
public String getDescription() {
return "Fine New Look and Feel";
}
@Override
public void initialize() {
super.initialize();
// flat默认使用系统弹窗,3.3 版本之前无法实现圆角弹窗。
// popup弹窗不使用flat提供的工具,使用swing原生自带的
PopupFactory.setSharedInstance(new PopupFactory());
}
}

52
designer-base/src/main/java/com/fine/theme/light/ui/laf/FineLightLaf.java

@ -0,0 +1,52 @@
package com.fine.theme.light.ui.laf;
import com.fine.swing.ui.layout.Layouts;
import com.fine.theme.icon.IconManager;
import com.fine.theme.light.ui.FineLightIconSet;
import com.formdev.flatlaf.util.UIScale;
import com.fr.stable.StringUtils;
/**
* Fine 亮色主题
*
* @author vito
* @since 11.0
* Created on 2023/9/12
*/
public class FineLightLaf extends FineLaf {
public static final String USER_SCALE_FACTOR = "userScaleFactor";
private static final String NAME = "FineLaf Light";
/**
* 安装外观
*
* @return 是否安装成功
*/
public static boolean setup() {
IconManager.addSet(new FineLightIconSet("fine-light"));
Layouts.setScaleFactor(UIScale.getUserScaleFactor());
UIScale.addPropertyChangeListener(evt -> {
if (StringUtils.equals(evt.getPropertyName(), USER_SCALE_FACTOR)) {
Layouts.setScaleFactor((float) evt.getNewValue());
}
});
return setup(new FineLightLaf());
}
@Override
public String getName() {
return NAME;
}
@Override
public String getDescription() {
return "Fine New Light Look and Feel";
}
@Override
public boolean isDark() {
return false;
}
}

35
designer-base/src/main/java/com/fine/theme/utils/FineClientProperties.java

@ -0,0 +1,35 @@
package com.fine.theme.utils;
import com.formdev.flatlaf.FlatClientProperties;
/**
* FR-UI中使用的各类属性
*
* @author Levy.Xie
* @since 11.0
* Created on 2023/12/15
*/
public interface FineClientProperties extends FlatClientProperties {
//--------------------------- ButtonGroup -----------------------
String BUTTON_TYPE_GROUP = "group";
String BUTTON_BORDER = "buttonBorder";
String BUTTON_BORDER_LEFT_ROUND_RECT = "leftRoundRect";
String BUTTON_BORDER_RIGHT_ROUND_RECT = "rightRoundRect";
//--------------------------- PopupMenu -----------------------
String MENU_ITEM_TYPE = "MenuItemType";
String MENU_ITEM_TYPE_LOCK = "lock";
String BUTTON_GROUP_POSITION = "group_position";
int GROUP_BUTTON_POSITION_INNER = 0;
int GROUP_BUTTON_POSITION_LEFT = 1;
int GROUP_BUTTON_POSITION_RIGHT = 2;
int GROUP_BUTTON_POSITION_LEFT_TOP = 3;
int GROUP_BUTTON_POSITION_LEFT_BOTTOM = 4;
int GROUP_BUTTON_POSITION_RIGHT_TOP = 5;
int GROUP_BUTTON_POSITION_RIGHT_BOTTOM = 6;
}

86
designer-base/src/main/java/com/fine/theme/utils/FineUIScale.java

@ -0,0 +1,86 @@
package com.fine.theme.utils;
import com.formdev.flatlaf.util.UIScale;
import javax.swing.plaf.DimensionUIResource;
import javax.swing.plaf.InsetsUIResource;
import javax.swing.plaf.UIResource;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Insets;
/**
* UI缩放工具
*
* @author vito
* @since 11.0
* Created on 2023/11/15
*/
public class FineUIScale {
/**
* Multiplies the given value by the user scale factor.
*/
public static float scale(float value) {
return UIScale.scale(value);
}
/**
* Multiplies the given value by the user scale factor and rounds the result.
*/
public static int scale(int value) {
return UIScale.scale(value);
}
/**
* Similar as {@link #scale(int)} but always "rounds down".
* <p>
* For use in special cases. {@link #scale(int)} is the preferred method.
*/
public static int scale2(int value) {
return UIScale.scale2(value);
}
/**
* Divides the given value by the user scale factor.
*/
public static float unscale(float value) {
return UIScale.unscale(value);
}
/**
* Divides the given value by the user scale factor and rounds the result.
*/
public static int unscale(int value) {
return UIScale.unscale(value);
}
/**
* If user scale factor is not 1, scale the given graphics context by invoking
* {@link Graphics2D#scale(double, double)} with user scale factor.
*/
public static void scaleGraphics(Graphics2D g) {
UIScale.scaleGraphics(g);
}
/**
* Scales the given dimension with the user scale factor.
* <p>
* If user scale factor is 1, then the given dimension is simply returned.
* Otherwise, a new instance of {@link Dimension} or {@link DimensionUIResource}
* is returned, depending on whether the passed dimension implements {@link UIResource}.
*/
public static Dimension scale(Dimension dimension) {
return UIScale.scale(dimension);
}
/**
* Scales the given insets with the user scale factor.
* <p>
* If user scale factor is 1, then the given insets is simply returned.
* Otherwise, a new instance of {@link Insets} or {@link InsetsUIResource}
* is returned, depending on whether the passed dimension implements {@link UIResource}.
*/
public static Insets scale(Insets insets) {
return UIScale.scale(insets);
}
}

101
designer-base/src/main/java/com/fine/theme/utils/FineUIStyle.java

@ -0,0 +1,101 @@
package com.fine.theme.utils;
import com.finebi.cbb.utils.StringUtils;
import javax.swing.JComponent;
/**
* UI样式工具
*
* @author vito
* @since 11.0
* Created on 2024/1/4
*/
public interface FineUIStyle {
String IN_TOOLBAR_GROUP = "inToolbarGroup";
String STYLE_PRIMARY = "primary";
String STYLE_SECONDARY = "secondary";
String STYLE_TEXT = "text";
String STYLE_SIZE_MEDIUM = "mediumSize";
String STYLE_SIZE_SMALL = "smallSize";
String MENU_BAR = "menuBar";
String LIGHT_GREY = "lightGrey";
String IN_TOOLBAR_LEFT = "inToolbarLeft";
String IN_TOOLBAR_RIGHT = "inToolbarRight";
String NORMAL_COLOR = "normalColor";
String TOP_TOOLS = "topTools";
String BRAND_COLOR_LABEL = "brandColorLabel";
String BUTTON_TAB_ACTION = "tabAction";
String MENU_TOOL_BAR = "menuToolBar";
String MENU_ITEM_TOOL_BAR = "menuItemToolBar";
String POPUP_MENU_TOOL_BAR = "popupMenuToolBar";
/**
* 添加组件的样式类类似css该方法会接在原样式后方
* <code>
* FineClientProperties.appendStyle("primary small")
* </code>
*
* @param it 组件
* @param styleClass 样式字符串支持连续添加类用空格
*/
static void appendStyle(JComponent it, String styleClass) {
Object oriProperty = it.getClientProperty(FineClientProperties.STYLE_CLASS);
if (oriProperty instanceof String && StringUtils.isNotBlank((String) oriProperty)) {
styleClass = oriProperty + " " + styleClass;
}
it.putClientProperty(FineClientProperties.STYLE_CLASS, styleClass);
}
/**
* 设置组件的样式类类似css该方法会替换原样式
* <code>
* FineClientProperties.setStyle("primary small")
* </code>
*
* @param jComponent 组件
* @param styleClass 样式字符串支持连续添加类用空格
*/
static void setStyle(JComponent jComponent, String styleClass) {
jComponent.putClientProperty(FineClientProperties.STYLE_CLASS, styleClass);
}
/**
* 样式组合
*
* @param styleClasses 所有样式
* @return 样式列表
*/
static String joinStyle(String... styleClasses) {
final StringBuilder sb = new StringBuilder();
for (final String style : styleClasses) {
if (style == null) {
continue;
}
if (sb.length() > 0) {
sb.append(" ");
}
sb.append(style);
}
return sb.toString();
}
/**
* 包含样式
*
* @param jComponent 组件
* @param styleClass 样式
* @return 是否包含指定的样式
*/
static boolean hasStyle(JComponent jComponent, String styleClass) {
Object style = jComponent.getClientProperty(FineClientProperties.STYLE_CLASS);
if (style instanceof String && StringUtils.isNotBlank((String) style)) {
return ((String) style).contains(styleClass);
}
return false;
}
}

367
designer-base/src/main/java/com/fine/theme/utils/FineUIUtils.java

@ -0,0 +1,367 @@
package com.fine.theme.utils;
import com.formdev.flatlaf.ui.FlatUIUtils;
import com.fr.stable.os.OperatingSystem;
import com.fr.value.AtomicClearableLazyValue;
import javax.swing.UIManager;
import java.awt.Color;
import java.awt.Component;
import java.awt.Composite;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Insets;
import java.awt.geom.Path2D;
import java.awt.geom.RoundRectangle2D;
import java.lang.reflect.Field;
import static com.fine.theme.light.ui.FineButtonUI.isLeftRoundButton;
import static com.formdev.flatlaf.util.UIScale.scale;
/**
* UI绘制的一些常用方法
*
* @author vito
* @since 11.0
* Created on 2023/11/3
*/
public class FineUIUtils {
public static final int RETINA_SCALE_FACTOR = 2;
/**
* 判断是否支持retina制作一些特殊效果如HIDPI图片绘制
* retina 是一种特殊的效果使用4个像素点模拟一个像素点
* 因此在其他操作系统上即使是高分屏也不具备retina的效果
* 甚至还有劣化的效果以及更差的性能
*
* @since 2023.11.16
*/
private static final AtomicClearableLazyValue<Boolean> RETINA = AtomicClearableLazyValue.create(() -> {
// 经过测试win11,ubuntu等,没有retina效果
if (!OperatingSystem.isMacos()) {
return false;
}
GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice device = env.getDefaultScreenDevice();
try {
Field field = device.getClass().getDeclaredField("scale");
field.setAccessible(true);
Object scale = field.get(device);
if (scale instanceof Integer && (Integer) scale == RETINA_SCALE_FACTOR) {
return true;
}
} catch (Exception ignored) {
}
return false;
});
/**
* 是否支持 retina
*
* @return 是否支持 retina
*/
public static boolean getRetina() {
return RETINA.getValue();
}
/**
* 放弃 retina 判断结果用于清理或者切换环境
*/
public static void clearRetina() {
RETINA.drop();
}
/**
* 通过key获取UI的颜色如果没有则使用后备key获取
*
* @param key 颜色key
* @param defaultKey 颜色后备key
* @return 颜色
*/
public static Color getUIColor(String key, String defaultKey) {
Color color = UIManager.getColor(key);
return (color != null) ? color : UIManager.getColor(defaultKey);
}
/**
* 获取key指定的int值如果没有则使用后备key获取
*
* @param key int所在的key
* @param defaultKey 后备key
* @return 长度
*/
public static int getUIInt(String key, String defaultKey) {
Object value = UIManager.get(key);
return (value instanceof Integer) ? (Integer) value : UIManager.getInt(defaultKey);
}
/**
* 获取key指定的int值并根据dpi进行缩放
*
* @param key int所在的key
* @param defaultKey 后备key
* @return 长度
*/
public static int getAndScaleInt(String key, String defaultKey) {
int intNum = getUIInt(key, defaultKey);
return FineUIScale.scale(intNum);
}
/**
* 获取key指定的int值并根据dpi进行缩放
*
* @param key int所在的key
* @param defaultInt 默认值
* @return 长度
*/
public static int getAndScaleInt(String key, int defaultInt) {
int intNum = FlatUIUtils.getUIInt(key, defaultInt);
return FineUIScale.scale(intNum);
}
/**
* 通过key获取UI的边距如果没有则使用后备key获取
*
* @param key 边距key
* @param defaultKey 边距后备key
* @return 边距
*/
public static Insets getUIInsets(String key, String defaultKey) {
Insets margin = UIManager.getInsets(key);
return (margin != null) ? margin : UIManager.getInsets(defaultKey);
}
/**
* 通过key获取UI的边距如果没有则使用后备边距
*
* @param key 边距key
* @param defaultInsets 后备边距
* @return 边距
*/
public static Insets getUIInsets(String key, Insets defaultInsets) {
Insets margin = UIManager.getInsets(key);
return (margin != null) ? margin : defaultInsets;
}
/**
* 通过key获取UI的边距如果没有则使用后备边距并根据dpi进行缩放
*
* @param key 边距key
* @param defaultInsets 后备边距
* @return 根据dpi缩放后的边距
*/
public static Insets getAndScaleUIInsets(String key, Insets defaultInsets) {
Insets margin = UIManager.getInsets(key);
Insets insets = (margin != null) ? margin : defaultInsets;
return FineUIScale.scale(insets);
}
/**
* 绘制混合图像含圆角背景色设置
*
* @param g 图像
* @param composite 混合图像
* @param background 背景色
* @param width 宽度
* @param height 高度
* @param radius 圆角
*/
public static void paintWithComposite(Graphics g, Composite composite, Color background,
int width, int height, int radius) {
Graphics2D g2d = (Graphics2D) g;
FlatUIUtils.setRenderingHints(g2d);
Composite oldComposite = g2d.getComposite();
g2d.setComposite(composite);
g2d.setColor(background);
g2d.fill(new RoundRectangle2D.Float(0, 0, width, height, radius, radius));
g2d.setComposite(oldComposite);
}
/**
* 绘制部分圆角矩形边框
*
* @param g2 Graphics2D
* @param x x坐标
* @param y y坐标
* @param width 宽度
* @param height 高度
* @param borderWidth 边框宽度
* @param arc 圆角
*/
public static void paintPartRoundButtonBorder(Component c, Graphics2D g2, int x, int y, int width, int height,
float borderWidth, float arc) {
FlatUIUtils.setRenderingHints(g2);
arc = scale(arc);
float t = scale(borderWidth);
float t2x = t * 2;
Path2D path2D = new Path2D.Float(Path2D.WIND_EVEN_ODD);
if (isLeftRoundButton(c)) {
path2D.append(createLeftRoundRectangle(x, y, width, height, arc), false);
path2D.append(createLeftRoundRectangle(x + t, y + t, width - t, height - t2x, arc - t), false);
} else {
path2D.append(createRightRoundRectangle(x, y, width, height, arc), false);
path2D.append(createRightRoundRectangle(x, y + t, width - t, height - t2x, arc - t), false);
}
g2.fill(path2D);
}
/**
* 绘制圆角tab边框
*
* @param g2 Graphics2D
* @param x x坐标
* @param y y坐标
* @param width 宽度
* @param height 高度
* @param borderWidth 边框宽度
* @param arc 圆角
*/
public static void paintRoundTabBorder(Graphics2D g2, double x, double y, double width, double height,
float borderWidth, float arc) {
FlatUIUtils.setRenderingHints(g2);
arc = scale(arc);
float t = scale(borderWidth);
float t2x = t * 2;
Path2D path2D = new Path2D.Float(Path2D.WIND_EVEN_ODD);
path2D.append(createTopRoundRectangle(x, y, width, height, arc), false);
path2D.append(createTopRoundRectangle(x + t, y + t, width - t2x, height - t, arc - t), false);
g2.fill(path2D);
}
/**
* 创建一个部分圆角的矩形路径
*
* @param x x坐标
* @param y y坐标
* @param width 矩形宽度
* @param height 矩形高度
* @param arcTopLeft 左上圆角弧度
* @param arcTopRight 右上圆角弧度
* @param arcBottomRight 右下圆角弧度
* @param arcBottomLeft 左下圆角弧度
* @return 路径
*/
public static Path2D createPartRoundRectangle(double x, double y, double width, double height,
double arcTopLeft, double arcTopRight, double arcBottomRight, double arcBottomLeft) {
Path2D path = new Path2D.Double(Path2D.WIND_EVEN_ODD, 7);
path.moveTo(x + arcTopLeft, y);
path.lineTo(x + width - arcTopRight, y);
path.quadTo(x + width, y, x + width, y + arcTopRight);
path.lineTo(x + width, y + height - arcBottomRight);
path.quadTo(x + width, y + height, x + width - arcBottomRight, y + height);
path.lineTo(x + arcBottomLeft, y + height);
path.quadTo(x, y + height, x, y + height - arcBottomLeft);
path.lineTo(x, y + arcTopLeft);
path.quadTo(x, y, x + arcTopLeft, y);
path.closePath();
return path;
}
/**
* 创建一个左圆角矩形路径
*
* @param x x坐标
* @param y y坐标
* @param width 矩形宽度
* @param height 矩形高度
* @param arc 圆角弧度
* @return 路径
*/
public static Path2D createLeftRoundRectangle(float x, float y, float width, float height, float arc) {
return createPartRoundRectangle(x, y, width, height, arc, 0, 0, arc);
}
/**
* 创建一个右圆角矩形路径
*
* @param x x坐标
* @param y y坐标
* @param width 矩形宽度
* @param height 矩形高度
* @param arc 圆角弧度
* @return 路径
*/
public static Path2D createRightRoundRectangle(float x, float y, float width, float height, float arc) {
return createPartRoundRectangle(x, y, width, height, 0, arc, arc, 0);
}
/**
* 创建一个顶圆角矩形路径
*
* @param x x坐标
* @param y y坐标
* @param width 矩形宽度
* @param height 矩形高度
* @param arc 圆角弧度
* @return 路径
*/
public static Path2D createTopRoundRectangle(double x, double y, double width, double height, double arc) {
return createPartRoundRectangle(x, y, width, height, arc, arc, 0, 0);
}
/**
* 创建一个左上圆角的矩形路径
*
* @param x x坐标
* @param y y坐标
* @param width 矩形宽度
* @param height 矩形高度
* @param arc 圆角弧度
* @return 路径
*/
public static Path2D createTopLeftRoundRectangle(float x, float y, float width, float height, float arc) {
return createPartRoundRectangle(x, y, width, height, arc, 0, 0, 0);
}
/**
* 创建一个左下圆角的矩形路径
*
* @param x x坐标
* @param y y坐标
* @param width 矩形宽度
* @param height 矩形高度
* @param arc 圆角弧度
* @return 路径
*/
public static Path2D createBottomLeftRoundRectangle(float x, float y, float width, float height, float arc) {
return createPartRoundRectangle(x, y, width, height, 0, 0, 0, arc);
}
/**
* 创建一个右上圆角的矩形路径
*
* @param x x坐标
* @param y y坐标
* @param width 矩形宽度
* @param height 矩形高度
* @param arc 圆角弧度
* @return 路径
*/
public static Path2D createTopRightRoundRectangle(float x, float y, float width, float height, float arc) {
return createPartRoundRectangle(x, y, width, height, 0, arc, 0, 0);
}
/**
* 创建一个右下圆角的矩形路径
*
* @param x x坐标
* @param y y坐标
* @param width 矩形宽度
* @param height 矩形高度
* @param arc 圆角弧度
* @return 路径
*/
public static Path2D createBottomRightRoundRectangle(float x, float y, float width, float height, float arc) {
return createPartRoundRectangle(x, y, width, height, 0, 0, arc, 0);
}
}

8
designer-base/src/main/java/com/fr/design/actions/UpdateAction.java

@ -3,6 +3,7 @@
*/
package com.fr.design.actions;
import com.fine.theme.icon.LazyIcon;
import com.fr.base.NameStyle;
import com.fr.base.ScreenResolution;
import com.fr.base.Style;
@ -171,6 +172,11 @@ public abstract class UpdateAction extends ShortCut implements Action {
* @param smallIcon The small icon for the action.
*/
public void setSmallIcon(Icon smallIcon) {
if(smallIcon instanceof LazyIcon){
this.putValue(Action.SMALL_ICON, smallIcon);
this.putValue(UpdateAction.DISABLED_ICON,((LazyIcon) smallIcon).disabled());
return;
}
this.putValue(Action.SMALL_ICON, smallIcon);
}
@ -677,7 +683,7 @@ public abstract class UpdateAction extends ShortCut implements Action {
protected void setDisabledIcon4Button(AbstractButton button) {
Icon disabledIcon = (Icon) this.getValue(UpdateAction.DISABLED_ICON);
if (disabledIcon != null && disabledIcon instanceof SVGIcon) {
if (disabledIcon != null) {
button.setDisabledIcon(disabledIcon);
}
}

22
designer-base/src/main/java/com/fr/design/actions/core/ActionFactory.java

@ -30,8 +30,8 @@ import java.util.concurrent.CopyOnWriteArraySet;
* @version 2017年11月17日14点39分
*/
public class ActionFactory {
private static Set<Class<?>> actionClasses = new CopyOnWriteArraySet<>();
private static Set<Class<?>> floatActionClasses = new CopyOnWriteArraySet<>();
private static final Set<Class<? extends UpdateAction>> actionClasses = new CopyOnWriteArraySet<>();
private static final Set<Class<? extends UpdateAction>> floatActionClasses = new CopyOnWriteArraySet<>();
private static Class chartCollectionClass = null;
/**
@ -287,13 +287,13 @@ public class ActionFactory {
*
* @param cls 类型数组
*/
public static void registerCellInsertActionClass(Class<?>[] cls) {
public static void registerCellInsertActionClass(Class<? extends UpdateAction>[] cls) {
if (cls != null) {
actionClasses.addAll(Arrays.asList(cls));
}
}
public static void referCellInsertActionClass(Class<?>[] cls) {
public static void referCellInsertActionClass(Class<? extends UpdateAction>[] cls) {
if (cls != null) {
actionClasses.clear();
actionClasses.addAll(Arrays.asList(cls));
@ -331,13 +331,13 @@ public class ActionFactory {
public static MenuKeySet[] createCellInsertActionName() {
List<MenuKeySet> actionNames = new ArrayList<>();
JTemplate jTemplate = HistoryTemplateListPane.getInstance().getCurrentEditingTemplate();
for (Class<?> clazz : actionClasses) {
for (Class<? extends UpdateAction> clazz : actionClasses) {
if (clazz == null) {
continue;
}
if (jTemplate.acceptToolbarItem(clazz)) {
try {
Constructor<? extends UpdateAction> c = (Constructor<? extends UpdateAction>) clazz.getConstructor();
Constructor<? extends UpdateAction> c = clazz.getConstructor();
actionNames.add(c.newInstance().getMenuKeySet());
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
@ -352,13 +352,13 @@ public class ActionFactory {
*
* @param cls 插入类型数组
*/
public static void registerFloatInsertActionClass(Class<?>[] cls) {
public static void registerFloatInsertActionClass(Class<? extends UpdateAction>[] cls) {
if (cls != null) {
floatActionClasses.addAll(Arrays.asList(cls));
}
}
public static void referFloatInsertActionClass(Class<?>[] cls) {
public static void referFloatInsertActionClass(Class<? extends UpdateAction>[] cls) {
if (cls != null) {
floatActionClasses.clear();
floatActionClasses.addAll(Arrays.asList(cls));
@ -374,18 +374,18 @@ public class ActionFactory {
*/
public static UpdateAction[] createFloatInsertAction(Class cls, Object obj) {
List<UpdateAction> actions = new ArrayList<>();
for (Class<?> clazz : floatActionClasses) {
for (Class<? extends UpdateAction> clazz : floatActionClasses) {
if (clazz == null) {
continue;
}
try {
Constructor<? extends UpdateAction> c = (Constructor<? extends UpdateAction>) clazz.getConstructor(cls);
Constructor<? extends UpdateAction> c = clazz.getConstructor(cls);
actions.add(c.newInstance(obj));
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
return actions.toArray(new UpdateAction[actions.size()]);
return actions.toArray(new UpdateAction[0]);
}
private static QuickEditor createEditor(Class clazz, Map<Class, QuickEditor> editorMap, Map<Class, Class<? extends QuickEditor>> editorClassMap) {

3
designer-base/src/main/java/com/fr/design/actions/edit/CopyAction.java

@ -3,6 +3,7 @@
*/
package com.fr.design.actions.edit;
import com.fine.theme.icon.LazyIcon;
import com.fr.design.actions.TemplateComponentAction;
import com.fr.design.base.mode.DesignModeContext;
import com.fr.design.designer.TargetComponent;
@ -21,7 +22,7 @@ public class CopyAction extends TemplateComponentAction {
this.setName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_M_Edit_Copy"));
this.setMnemonic('C');
this.setSmallIcon("/com/fr/design/standard/copy/copy");
this.setSmallIcon(new LazyIcon("copy"));
this.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, DEFAULT_MODIFIER));
this.setEnabled(!DesignModeContext.isBanCopyAndCut());
}

4
designer-base/src/main/java/com/fr/design/actions/edit/CutAction.java

@ -3,10 +3,10 @@
*/
package com.fr.design.actions.edit;
import com.fine.theme.icon.LazyIcon;
import com.fr.design.actions.TemplateComponentAction;
import com.fr.design.base.mode.DesignModeContext;
import com.fr.design.designer.TargetComponent;
import com.fr.general.IOUtils;
import javax.swing.KeyStroke;
import java.awt.event.KeyEvent;
@ -25,7 +25,7 @@ public class CutAction extends TemplateComponentAction {
this.setName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_M_Edit_Cut"));
this.setMnemonic('T');
this.setSmallIcon("/com/fr/design/standard/cut/cut");
this.setSmallIcon(new LazyIcon("cut"));
this.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, DEFAULT_MODIFIER));
this.setEnabled(!DesignModeContext.isBanCopyAndCut());
}

3
designer-base/src/main/java/com/fr/design/actions/edit/PasteAction.java

@ -3,6 +3,7 @@
*/
package com.fr.design.actions.edit;
import com.fine.theme.icon.LazyIcon;
import com.fr.design.actions.TemplateComponentAction;
import com.fr.design.base.mode.DesignModeContext;
import com.fr.design.designer.TargetComponent;
@ -24,7 +25,7 @@ public class PasteAction extends TemplateComponentAction {
this.setName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_M_Edit_Paste"));
this.setMnemonic('P');
this.setSmallIcon("/com/fr/design/standard/paste/paste");
this.setSmallIcon(new LazyIcon("paste"));
this.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V, DEFAULT_MODIFIER));
}

3
designer-base/src/main/java/com/fr/design/actions/file/DelFileAction.java

@ -1,5 +1,6 @@
package com.fr.design.actions.file;
import com.fine.theme.icon.LazyIcon;
import com.fr.design.actions.UpdateAction;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.file.FileOperations;
@ -22,7 +23,7 @@ public class DelFileAction extends UpdateAction {
public DelFileAction() {
this.setName(Toolkit.i18nText("Fine-Design_Basic_Remove"));
this.setSmallIcon("/com/fr/design/standard/remove/remove");
this.setSmallIcon(new LazyIcon("remove"));
}
@Override

3
designer-base/src/main/java/com/fr/design/actions/file/LocateAction.java

@ -1,5 +1,6 @@
package com.fr.design.actions.file;
import com.fine.theme.icon.LazyIcon;
import com.fr.design.actions.UpdateAction;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.file.TemplateTreePane;
@ -28,7 +29,7 @@ public class LocateAction extends UpdateAction {
public LocateAction() {
this.setName(Toolkit.i18nText("Fine-Design_Basic_Locate"));
this.setSmallIcon("/com/fr/design/standard/locate/locate");
this.setSmallIcon(new LazyIcon("locate"));
}
@Override

3
designer-base/src/main/java/com/fr/design/actions/file/RenameAction.java

@ -1,5 +1,6 @@
package com.fr.design.actions.file;
import com.fine.theme.icon.LazyIcon;
import com.fr.base.BaseUtils;
import com.fr.chartx.TwoTuple;
import com.fr.design.DesignerEnvManager;
@ -62,7 +63,7 @@ public class RenameAction extends UpdateAction {
public RenameAction() {
this.setName(Toolkit.i18nText("Fine-Design_Basic_Rename"));
this.setSmallIcon("/com/fr/design/standard/rename/rename");
this.setSmallIcon(new LazyIcon("rename"));
}
@Override

8
designer-base/src/main/java/com/fr/design/actions/help/alphafine/component/CustomSortPane.java

@ -74,10 +74,10 @@ public class CustomSortPane extends JPanel {
}
private void createToolbarPane() {
top = new UIButton(IconUtils.readIcon("com/fr/design/mainframe/alphafine/images/top.svg"), false);
bottom = new UIButton(IconUtils.readIcon("com/fr/design/mainframe/alphafine/images/bottom.svg"), false);
up = new UIButton(IconUtils.readIcon("com/fr/design/mainframe/alphafine/images/up.svg"), false);
down = new UIButton(IconUtils.readIcon("com/fr/design/mainframe/alphafine/images/down.svg"), false);
top = new UIButton(IconUtils.readIcon("com/fr/design/mainframe/alphafine/images/top.svg"));
bottom = new UIButton(IconUtils.readIcon("com/fr/design/mainframe/alphafine/images/bottom.svg"));
up = new UIButton(IconUtils.readIcon("com/fr/design/mainframe/alphafine/images/up.svg"));
down = new UIButton(IconUtils.readIcon("com/fr/design/mainframe/alphafine/images/down.svg"));
top.setDisabledIcon(IconUtils.readIcon("com/fr/design/mainframe/alphafine/images/top_disable.svg"));
bottom.setDisabledIcon(IconUtils.readIcon("com/fr/design/mainframe/alphafine/images/bottom_disable.svg"));
up.setDisabledIcon(IconUtils.readIcon("com/fr/design/mainframe/alphafine/images/up_disable.svg"));

5
designer-base/src/main/java/com/fr/design/actions/server/ProcedureListAction.java

@ -1,6 +1,6 @@
package com.fr.design.actions.server;
import com.fr.base.BaseUtils;
import com.fine.theme.icon.LazyIcon;
import com.fr.design.DesignModelAdapter;
import com.fr.design.actions.UpdateAction;
import com.fr.design.data.DesignTableDataManager;
@ -11,7 +11,6 @@ import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.DesignerFrame;
import com.fr.file.ProcedureConfig;
import com.fr.transaction.CallBackAdaptor;
import com.fr.transaction.Configurations;
import com.fr.transaction.WorkerFacade;
@ -22,7 +21,7 @@ public class ProcedureListAction extends UpdateAction {
public ProcedureListAction() {
this.setName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Datasource_Stored_Procedure") + "(P)" + "...");
this.setMnemonic('P');
this.setSmallIcon(BaseUtils.readIcon("/com/fr/design/images/data/store_procedure.png"));
this.setSmallIcon(new LazyIcon("store_procedure"));
}
/**

10
designer-base/src/main/java/com/fr/design/constants/LayoutConstants.java

@ -42,4 +42,14 @@ public class LayoutConstants {
* 图表属性表中二级菜单距离右边框的距离
*/
public static final int CHART_ATTR_TOMARGIN = 46;
/**
* 主题化布局水平间隙
*/
public static final int HORIZONTAL_GAP = 10;
/**
* 主题化布局垂直间隙
*/
public static final int VERTICAL_GAP = 10;
}

6
designer-base/src/main/java/com/fr/design/data/BasicTableDataTreePane.java

@ -1,6 +1,6 @@
package com.fr.design.data;
import com.fr.base.BaseUtils;
import com.fine.theme.icon.LazyIcon;
import com.fr.base.TableData;
import com.fr.base.svg.IconUtils;
import com.fr.data.MultiResultTableData;
@ -431,7 +431,7 @@ public abstract class BasicTableDataTreePane extends DockingView implements Resp
public PreviewTableDataAction(TableDataTree dataTree) {
this.setName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Preview"));
this.setMnemonic('p');
this.setSmallIcon("/com/fr/design/standard/previewdateset/preview");
this.setSmallIcon(new LazyIcon("preview"));
this.dataTree = dataTree;
}
@ -508,7 +508,7 @@ public abstract class BasicTableDataTreePane extends DockingView implements Resp
public ConnectionTableAction() {
this.setName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Server_Define_Data_Connection"));
this.setMnemonic('D');
this.setSmallIcon("/com/fr/design/standard/connection", false);
this.setSmallIcon(new LazyIcon("connection"));
}
@Override

48
designer-base/src/main/java/com/fr/design/data/datapane/TableDataCreatorProducer.java

@ -4,11 +4,25 @@
package com.fr.design.data.datapane;
import com.fr.data.impl.*;
import com.fine.theme.icon.LazyIcon;
import com.fr.data.impl.ClassTableData;
import com.fr.data.impl.ConditionTableData;
import com.fr.data.impl.DBTableData;
import com.fr.data.impl.EmbeddedTableData;
import com.fr.data.impl.FileTableData;
import com.fr.data.impl.RecursionTableData;
import com.fr.data.impl.storeproc.StoreProcedure;
import com.fr.design.ExtraDesignClassManager;
import com.fr.design.data.tabledata.tabledatapane.*;
import com.fr.design.data.tabledata.tabledatapane.ClassTableDataPane;
import com.fr.design.data.tabledata.tabledatapane.DBTableDataPane;
import com.fr.design.data.tabledata.tabledatapane.EmbeddedTableDataPane;
import com.fr.design.data.tabledata.tabledatapane.FileTableDataSmallHeightPane;
import com.fr.design.data.tabledata.tabledatapane.FileTableDataSmallPane;
import com.fr.design.data.tabledata.tabledatapane.GlobalMultiTDTableDataPane;
import com.fr.design.data.tabledata.tabledatapane.GlobalTreeTableDataPane;
import com.fr.design.data.tabledata.tabledatapane.MultiTDTableDataPane;
import com.fr.design.data.tabledata.tabledatapane.ProcedureDataPane;
import com.fr.design.data.tabledata.tabledatapane.TreeTableDataPane;
import com.fr.stable.ArrayUtils;
import java.util.ArrayList;
@ -33,33 +47,33 @@ public class TableDataCreatorProducer {
public TableDataNameObjectCreator[] createReportTableDataCreator() {
TableDataNameObjectCreator dataBase = new TableDataNameObjectCreator(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_DS_Database_Query"),
"ds",
"/com/fr/design/standard/database_normal.svg", DBTableData.class, DBTableDataPane.class);
new LazyIcon("database"), DBTableData.class, DBTableDataPane.class);
TableDataNameObjectCreator ds_Class = new TableDataNameObjectCreator(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tabledata_Type_Class"),
"Class",
"/com/fr/design/standard/class_table_data_normal.svg", ClassTableData.class, ClassTableDataPane.class);
new LazyIcon("class_table_data"), ClassTableData.class, ClassTableDataPane.class);
TableDataNameObjectCreator table = new TableDataNameObjectCreator(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tabledata_Type_Embedded"),
"Embedded",
"/com/fr/design/standard/data_table_normal.svg", EmbeddedTableData.class, EmbeddedTableDataPane.class);
new LazyIcon("data_table"), EmbeddedTableData.class, EmbeddedTableDataPane.class);
TableDataNameObjectCreator multiTable = new TableDataNameObjectCreator(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tabledata_Type_Relation"),
"Multi",
"/com/fr/design/standard/multi_normal.svg", ConditionTableData.class, MultiTDTableDataPane.class) {
new LazyIcon("multi"), ConditionTableData.class, MultiTDTableDataPane.class) {
public boolean isNeedParameterWhenPopulateJControlPane() {
return true;
}
};
TableDataNameObjectCreator fileTable = new TableDataNameObjectCreator(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tabledata_Type_File"),
"File",
"/com/fr/design/standard/file_normal.svg", FileTableData.class, FileTableDataSmallHeightPane.class);
new LazyIcon("file"), FileTableData.class, FileTableDataSmallHeightPane.class);
TableDataNameObjectCreator treeTable = new TableDataNameObjectCreator(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tabledata_Type_Tree"),
"Tree",
"/com/fr/design/standard/tree_normal.svg", RecursionTableData.class, TreeTableDataPane.class) {
new LazyIcon("tree"), RecursionTableData.class, TreeTableDataPane.class) {
public boolean isNeedParameterWhenPopulateJControlPane() {
return true;
}
};
TableDataNameObjectCreator storeProcedure = new TableDataNameObjectCreator(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Datasource_Stored_Procedure"),
"Proc",
"/com/fr/design/standard/store_procedure_normal.svg",
new LazyIcon("store_procedure"),
StoreProcedure.class, ProcedureDataPane.class) {
@Override
public boolean shouldInsertSeparator() {
@ -72,33 +86,33 @@ public class TableDataCreatorProducer {
public TableDataNameObjectCreator[] createServerTableDataCreator() {
TableDataNameObjectCreator dataBase = new TableDataNameObjectCreator(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_DS_Database_Query"),
"/com/fr/design/standard/server_database_normal.svg", DBTableData.class,
new LazyIcon("server_database"), DBTableData.class,
DBTableDataPane.class);
TableDataNameObjectCreator ds_Class = new TableDataNameObjectCreator(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tabledata_Type_Class"),
"/com/fr/design/standard/class_table_data_normal.svg", ClassTableData.class,
new LazyIcon("class_table_data"), ClassTableData.class,
ClassTableDataPane.class);
TableDataNameObjectCreator table = new TableDataNameObjectCreator(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tabledata_Type_Embedded"),
"/com/fr/design/standard/data_table_normal.svg", EmbeddedTableData.class,
new LazyIcon("data_table"), EmbeddedTableData.class,
EmbeddedTableDataPane.class);
TableDataNameObjectCreator fileTable = new TableDataNameObjectCreator(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tabledata_Type_File"),
"/com/fr/design/standard/file_normal.svg", FileTableData.class,
new LazyIcon("file"), FileTableData.class,
FileTableDataSmallPane.class);
TableDataNameObjectCreator treeTable = new TableDataNameObjectCreator(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tabledata_Type_Tree"),
"/com/fr/design/standard/tree_normal.svg",
new LazyIcon("tree"),
RecursionTableData.class, GlobalTreeTableDataPane.class) {
public boolean isNeedParameterWhenPopulateJControlPane() {
return true;
}
};
TableDataNameObjectCreator multiTable = new TableDataNameObjectCreator(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tabledata_Type_Relation"),
"/com/fr/design/standard/multi_normal.svg",
new LazyIcon("multi"),
ConditionTableData.class, GlobalMultiTDTableDataPane.class) {
public boolean isNeedParameterWhenPopulateJControlPane() {
return true;
}
};
TableDataNameObjectCreator storeProcedure = new TableDataNameObjectCreator(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tabledata_Type_Stored_Procedure"),
"/com/fr/design/standard/store_procedure_normal.svg",
new LazyIcon("store_procedure"),
StoreProcedure.class, ProcedureDataPane.class) {
@Override
public boolean shouldInsertSeparator() {

35
designer-base/src/main/java/com/fr/design/data/datapane/TableDataNameObjectCreator.java

@ -1,7 +1,5 @@
package com.fr.design.data.datapane;
import com.fr.base.BaseUtils;
import com.fr.base.svg.IconUtils;
import com.fr.base.svg.SVGLoader;
import com.fr.data.impl.DBTableData;
import com.fr.design.actions.tabledata.TableDataAction;
@ -52,6 +50,9 @@ public class TableDataNameObjectCreator extends NameObjectCreator {
prefix = action.getPrefix();
}
/**
* 改用{@link TableDataNameObjectCreator#TableDataNameObjectCreator(String, Icon, Class, Class)}
*/
public TableDataNameObjectCreator(String menuName, String iconPath, Class clazz, Class<? extends BasicBeanPane> updatePane) {
super(menuName, iconPath, clazz, updatePane);
if (iconPath != null) {
@ -60,6 +61,14 @@ public class TableDataNameObjectCreator extends NameObjectCreator {
}
}
public TableDataNameObjectCreator(String menuName, Icon icon, Class clazz, Class<? extends BasicBeanPane> updatePane) {
super(menuName, icon, clazz, updatePane);
}
/**
* 改用{@link TableDataNameObjectCreator#TableDataNameObjectCreator(String, String, Icon, Class, Class)}
*/
@Deprecated
public TableDataNameObjectCreator(String menuName, String prefix, String iconPath, Class clazz, Class<? extends BasicBeanPane> updatePane) {
super(menuName, iconPath, clazz, updatePane);
if (iconPath != null) {
@ -69,6 +78,15 @@ public class TableDataNameObjectCreator extends NameObjectCreator {
this.prefix = prefix;
}
public TableDataNameObjectCreator(String menuName, String prefix, Icon icon, Class clazz, Class<? extends BasicBeanPane> updatePane) {
super(menuName, icon, clazz, updatePane);
this.prefix = prefix;
}
/**
* 改用{@link TableDataNameObjectCreator#TableDataNameObjectCreator(String, Icon, Class, Class, Class)}
*/
@Deprecated
public TableDataNameObjectCreator(String menuName, String iconPath, Class clazz, Class clazz4Init, Class<? extends BasicBeanPane> updatePane) {
super(menuName, iconPath, clazz, clazz4Init, updatePane);
if (iconPath != null) {
@ -77,6 +95,14 @@ public class TableDataNameObjectCreator extends NameObjectCreator {
}
}
public TableDataNameObjectCreator(String menuName, Icon icon, Class clazz, Class clazz4Init, Class<? extends BasicBeanPane> updatePane) {
super(menuName, icon, clazz, clazz4Init, updatePane);
}
/**
* 改用{@link TableDataNameObjectCreator#TableDataNameObjectCreator(String, String, Icon, Class, Class, Class)}
*/
@Deprecated
public TableDataNameObjectCreator(String menuName, String prefix, String iconPath, Class clazz, Class clazz4Init, Class<? extends BasicBeanPane> updatePane) {
super(menuName, iconPath, clazz, clazz4Init, updatePane);
if (iconPath != null) {
@ -86,6 +112,11 @@ public class TableDataNameObjectCreator extends NameObjectCreator {
this.prefix = prefix;
}
public TableDataNameObjectCreator(String menuName, String prefix, Icon icon, Class clazz, Class clazz4Init, Class<? extends BasicBeanPane> updatePane) {
super(menuName, icon, clazz, clazz4Init, updatePane);
this.prefix = prefix;
}
@Override
protected void doSthChanged4Icon(Object ob) {

15
designer-base/src/main/java/com/fr/design/data/datapane/TableDataTree.java

@ -1,23 +1,22 @@
package com.fr.design.data.datapane;
import com.fine.theme.icon.LazyIcon;
import com.fr.base.svg.IconUtils;
import com.fr.data.MultiResultTableData;
import com.fr.design.constants.UIConstants;
import com.fr.design.data.datapane.management.search.TableDataTreeSearchManager;
import com.fr.design.data.tabledata.wrapper.TableDataWrapper;
import com.fr.design.gui.itree.filetree.FineTreeCellRender;
import com.fr.design.gui.itree.refreshabletree.ExpandMutableTreeNode;
import com.fr.design.gui.itree.refreshabletree.UserObjectRefreshJTree;
import com.fr.design.icon.IconPathConstants;
import com.fr.general.ComparatorUtils;
import com.fr.general.NameObject;
import javax.swing.BorderFactory;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;
import java.awt.Color;
import java.awt.Component;
import java.util.ArrayList;
import java.util.HashMap;
@ -44,7 +43,7 @@ public class TableDataTree extends UserObjectRefreshJTree<TableDataSourceOP> {
}
// CellRenderer
private DefaultTreeCellRenderer tableDataTreeCellRenderer = new DefaultTreeCellRenderer() {
private DefaultTreeCellRenderer tableDataTreeCellRenderer = new FineTreeCellRender() {
private static final long serialVersionUID = 1L;
@Override
@ -54,7 +53,7 @@ public class TableDataTree extends UserObjectRefreshJTree<TableDataSourceOP> {
Object userObj = treeNode.getUserObject();
if (userObj instanceof String) {
// p:这个是column field.
this.setIcon(IconUtils.readIcon("/com/fr/design/standard/field"));
this.setIcon(new LazyIcon("field"));
this.setText((String) userObj);
} else if (userObj instanceof NameObject) {
NameObject nameObject = (NameObject) userObj;
@ -72,16 +71,12 @@ public class TableDataTree extends UserObjectRefreshJTree<TableDataSourceOP> {
this.setIcon(IconUtils.readIcon(IconPathConstants.DS_QUERY_ICON_PATH));
}
} else {
this.setIcon(IconUtils.readIcon("/com/fr/design/images/data/store_procedure.png"));
this.setIcon(new LazyIcon("store_procedure"));
}
} else if (userObj == PENDING) {
this.setIcon(null);
this.setText(PENDING.toString());
}
this.setBorder(BorderFactory.createEmptyBorder(1, 0, 1, 0));
this.setBackgroundNonSelectionColor(UIConstants.TREE_BACKGROUND);
this.setTextSelectionColor(Color.WHITE);
this.setBackgroundSelectionColor(UIConstants.FLESH_BLUE);
return this;
}
};

32
designer-base/src/main/java/com/fr/design/data/datapane/TableDataTreePane.java

@ -1,5 +1,6 @@
package com.fr.design.data.datapane;
import com.fine.theme.icon.LazyIcon;
import com.fr.base.TableData;
import com.fr.data.MultiResultTableData;
import com.fr.data.TableDataSource;
@ -9,7 +10,6 @@ import com.fr.design.DesignModelAdapter;
import com.fr.design.DesignerEnvManager;
import com.fr.design.ExtraDesignClassManager;
import com.fr.design.actions.UpdateAction;
import com.fr.design.constants.UIConstants;
import com.fr.design.data.BasicTableDataTreePane;
import com.fr.design.data.BasicTableDataUtils;
import com.fr.design.data.DesignTableDataManager;
@ -69,17 +69,16 @@ import com.fr.stable.core.PropertyChangeAdapter;
import com.fr.workspace.WorkContext;
import org.jetbrains.annotations.NotNull;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.ToolTipManager;
import javax.swing.border.EmptyBorder;
import javax.swing.tree.TreePath;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.dnd.DnDConstants;
import java.awt.event.ActionEvent;
@ -183,7 +182,6 @@ public class TableDataTreePane extends BasicTableDataTreePane {
popupMenu.add(copyAction.createMenuItem());
popupMenu.add(pasteAction.createMenuItem());
popupMenu.add(removeAction.createMenuItem());
popupMenu.addSeparator();
// 监听
tableDataTree.addMouseListener(new MouseAdapter() {
@Override
@ -229,7 +227,7 @@ public class TableDataTreePane extends BasicTableDataTreePane {
private TreeSearchToolbarPane initToolBarPane() {
// toolbar
addMenuDef = new MenuDef(Toolkit.i18nText("Fine-Design_Basic_Action_Add"));
addMenuDef.setDisabledIcon("/com/fr/design/standard/addpopup/addPopup", true);
addMenuDef.setIcon(new LazyIcon("add_popup"));
createAddMenuDef();
// 创建插件监听
createPluginListener();
@ -247,14 +245,10 @@ public class TableDataTreePane extends BasicTableDataTreePane {
toolbarDef = new ToolBarDef();
toolbarDef.addShortCut(addMenuDef, SeparatorDef.DEFAULT, editAction, removeAction, SeparatorDef.DEFAULT, previewTableDataAction, connectionTableAction, esdAction, esdOffAction, switchAction);
UIToolbar toolBar = ToolBarDef.createJToolBar();
toolBar.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, UIConstants.TOOLBAR_BORDER_COLOR));
toolBar.setBorderPainted(true);
toolbarDef.updateToolBar(toolBar);
TreeSearchToolbarPane searchLayerdPane = new TreeSearchToolbarPane(toolBar);
searchLayerdPane.setPreferredSize(new Dimension(this.getWidth(), 23));
return searchLayerdPane;
return new TreeSearchToolbarPane(toolBar);
}
/**
@ -275,6 +269,7 @@ public class TableDataTreePane extends BasicTableDataTreePane {
treePane.add(northPane, BorderLayout.NORTH);
treePane.add(remindPane, BorderLayout.CENTER);
treePane.setBorder(new EmptyBorder(10, 10, 10, 10));
return treePane;
}
@ -813,7 +808,6 @@ public class TableDataTreePane extends BasicTableDataTreePane {
return false;
}
};
buttonGroup.setNeedLeftRightOutLine(false);
}
@ -895,7 +889,7 @@ public class TableDataTreePane extends BasicTableDataTreePane {
@Override
public String getIconResource() {
return "/com/fr/design/standard/batchesdon/batch_esd_on";
return "batch_esd_on";
}
@Override
@ -942,7 +936,7 @@ public class TableDataTreePane extends BasicTableDataTreePane {
@Override
public String getIconResource() {
return "/com/fr/design/standard/batchesdoff/batch_esd_off";
return "batch_esd_off";
}
@Override
@ -970,7 +964,7 @@ public class TableDataTreePane extends BasicTableDataTreePane {
public AbstractESDAction() {
this.setName(getName());
this.setMnemonic('R');
this.setSmallIcon(getIconResource());
this.setSmallIcon(new LazyIcon(getIconResource()));
}
@Override
@ -1036,7 +1030,7 @@ public class TableDataTreePane extends BasicTableDataTreePane {
public EditAction() {
this.setName(Toolkit.i18nText("Fine-Design_Basic_Edit"));
this.setMnemonic('E');
this.setSmallIcon("/com/fr/design/standard/editdataset/edit");
this.setSmallIcon(new LazyIcon("edit"));
}
@Override
@ -1101,7 +1095,7 @@ public class TableDataTreePane extends BasicTableDataTreePane {
public RemoveAction() {
this.setName(Toolkit.i18nText("Fine-Design_Basic_Remove"));
this.setMnemonic('R');
this.setSmallIcon("/com/fr/design/standard/remove/remove");
this.setSmallIcon(new LazyIcon("remove"));
}
@Override
@ -1177,7 +1171,7 @@ public class TableDataTreePane extends BasicTableDataTreePane {
public CopyAction() {
this.setName(Toolkit.i18nText("Fine-Design_Basic_Copy"));
this.setMnemonic('C');
this.setSmallIcon("/com/fr/design/standard/copy/copy");
this.setSmallIcon(new LazyIcon("copy"));
}
@Override
@ -1193,7 +1187,7 @@ public class TableDataTreePane extends BasicTableDataTreePane {
public PasteAction() {
this.setName(Toolkit.i18nText("Fine-Design_Basic_Action_Paste_Name"));
this.setMnemonic('P');
this.setSmallIcon("/com/fr/design/images/m_edit/paste");
this.setSmallIcon(new LazyIcon("paste"));
}
@Override
@ -1227,7 +1221,7 @@ public class TableDataTreePane extends BasicTableDataTreePane {
public SwitchAction() {
this.setName(Toolkit.i18nText("Fine-Design_Basic_Search"));
this.setMnemonic('S');
this.setSmallIcon("/com/fr/design/standard/search", false);
this.setSmallIcon(new LazyIcon("search"));
}
@Override

45
designer-base/src/main/java/com/fr/design/data/datapane/VerticalChoosePane.java

@ -1,23 +1,22 @@
package com.fr.design.data.datapane;
import com.fine.swing.ui.layout.Layouts;
import com.fr.design.constants.LayoutConstants;
import com.fr.design.data.datapane.preview.PreviewLabel;
import com.fr.design.data.datapane.preview.PreviewLabel.Previewable;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.mainframe.DesignerBean;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.design.utils.gui.UIComponentUtils;
import com.fr.design.widget.FRWidgetFactory;
import javax.swing.*;
import java.awt.*;
import static com.fine.swing.ui.layout.Layouts.cell;
import static com.fine.swing.ui.layout.Layouts.flex;
import static com.fine.swing.ui.layout.Layouts.row;
public class VerticalChoosePane extends ChoosePane implements DesignerBean {
private static final int RIGHTBORDER = 5;
private static final int MAX_WIDTH = 60;
public VerticalChoosePane(Previewable previewable) {
@ -31,35 +30,23 @@ public class VerticalChoosePane extends ChoosePane implements DesignerBean {
@Override
protected void initComponentsLayout(PreviewLabel previewLabel, int labelSize) {
double p = TableLayout.PREFERRED;
double f = TableLayout.FILL;
double[] columnSize = {p, f};
double[] rowSize = {p, p, p};
int[][] rowCount = {{1, 1}, {1, 1}, {1, 1}};
JPanel rs = new JPanel(new BorderLayout(0, 0));
rs.add(tableNameComboBox, BorderLayout.CENTER);
rs.add(GUICoreUtils.createFlowPane(new Component[]{new RefreshLabel(this), previewLabel}, FlowLayout.LEFT, LayoutConstants.HGAP_LARGE), BorderLayout.EAST);
rs.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, -RIGHTBORDER));
UILabel l1 = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Database"), UILabel.LEFT);
UILabel l2 = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Model"), UILabel.LEFT);
UILabel l3 = FRWidgetFactory.createLineWrapLabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Database_Select_Table"), MAX_WIDTH, UILabel.LEFT);
if (labelSize > 0) {
Dimension pSize = new Dimension(labelSize, 20);
l1.setPreferredSize(pSize);
l2.setPreferredSize(pSize);
l3.setPreferredSize(pSize);
}
Component[][] components = new Component[][]{
new Component[]{l1, dsNameComboBox},
new Component[]{l2, schemaBox},
new Component[]{l3, UIComponentUtils.wrapWithBorderLayoutPane(rs)}
};
JPanel content = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, LayoutConstants.VGAP_HUGER, LayoutConstants.VGAP_LARGE);
this.setLayout(new BorderLayout());
this.add(content, BorderLayout.CENTER);
this.add(Layouts.column(LayoutConstants.VERTICAL_GAP,
row(cell(l1).weight(1), cell(dsNameComboBox).weight(2)),
row(cell(l2).weight(1), cell(schemaBox).weight(2)),
row(
cell(l3).weight(1),
cell(tableNameComboBox).weight(1.2),
flex(0.1),
cell(new RefreshLabel(this)).weight(0.3),
flex(0.1),
cell(previewLabel).weight(0.3))
).getComponent(), BorderLayout.CENTER);
}

4
designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionTableProcedurePane.java

@ -7,7 +7,6 @@ import com.fr.data.impl.AbstractDatabaseConnection;
import com.fr.data.impl.Connection;
import com.fr.design.border.UIRoundedBorder;
import com.fr.design.constants.UIConstants;
import com.fr.design.data.tabledata.tabledatapane.DBTableDataPane;
import com.fr.design.data.tabledata.tabledatapane.loading.SwitchableTableDataPane;
import com.fr.design.dialog.BasicPane;
import com.fr.design.gui.icheckbox.UICheckBox;
@ -27,7 +26,6 @@ import javax.swing.ToolTipManager;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
@ -164,7 +162,7 @@ public class ConnectionTableProcedurePane extends BasicPane {
JPanel panel = FRGUIPaneFactory.createBorderLayout_S_Pane();
JPanel searchPane = new JPanel(new BorderLayout(10, 0));
searchPane.setBorder(BorderFactory.createLineBorder(UIConstants.TOOLBAR_BORDER_COLOR));
searchPane.setBackground(Color.WHITE);
// searchPane.setBackground(Color.WHITE);
searchField = new UITextField();
searchField.setBorderPainted(false);
searchField.setPlaceholder(Toolkit.i18nText("Fine-Design_Basic_Table_Search"));

140
designer-base/src/main/java/com/fr/design/data/datapane/management/search/pane/FineSearchPane.java

@ -0,0 +1,140 @@
package com.fr.design.data.datapane.management.search.pane;
import com.fine.theme.icon.LazyIcon;
import com.fine.theme.light.ui.FineInputUI;
import com.fine.theme.utils.FineUIUtils;
import com.fr.design.event.HoverAware;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.itextfield.UITextField;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.event.DocumentListener;
import java.awt.BorderLayout;
import java.awt.Insets;
import java.awt.event.ActionListener;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
/**
* 搜索面板
*
* @author Leo.Qin
* @since 11.0
* Created on 2023/12/13
*/
public class FineSearchPane extends JPanel implements HoverAware {
private final Insets defaultLabelInsets = new Insets(3, 6, 3, 4);
private final Insets defaultButtonInsets = new Insets(4, 4, 4, 4);
private UITextField searchTextField;
private UIButton clearButton;
private static final String UI_CLASS_ID = "InputUI";
@Override
public String getUIClassID() {
return UI_CLASS_ID;
}
private boolean hover;
public FineSearchPane() {
this.setLayout(new BorderLayout());
initComponents();
}
private void initComponents() {
// 左侧搜索图标
UILabel searchLabel = new UILabel(new LazyIcon("search"));
Insets labelInsets = FineUIUtils.getAndScaleUIInsets("SearchPanel.labelBorderInsets", defaultLabelInsets);
searchLabel.setBorder(BorderFactory.createEmptyBorder(labelInsets.top, labelInsets.left, labelInsets.bottom, labelInsets.right));
// 中间输入框
searchTextField = new UITextField();
searchTextField.setBorder(null);
searchTextField.setOpaque(false);
searchTextField.addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e) {
hover = true;
repaint();
}
@Override
public void mouseExited(MouseEvent e) {
hover = false;
repaint();
}
});
// 右侧返回图标
clearButton = new UIButton(new LazyIcon("clear"));
clearButton.setUI(new FineInputUI.FineInputButtonUI(false));
Insets buttonInsets = FineUIUtils.getAndScaleUIInsets("SearchPanel.buttonBorderInsets", defaultButtonInsets);
clearButton.setBorder(BorderFactory.createEmptyBorder(buttonInsets.top, buttonInsets.left, buttonInsets.bottom, buttonInsets.right));
this.add(searchLabel, BorderLayout.WEST);
this.add(searchTextField, BorderLayout.CENTER);
this.add(clearButton, BorderLayout.EAST);
}
@Override
public boolean isHovered() {
return hover;
}
/**
* 添加KeyListener
*
* @param listener the key listener.
*/
public void addKeyListener(KeyListener listener) {
searchTextField.addKeyListener(listener);
}
public void setPlaceholder(String placeHolder) {
searchTextField.setPlaceholder(placeHolder);
}
public void setClearToolTipText(String text) {
clearButton.setToolTipText(text);
}
/**
* 添加DocumentListener
*
* @param listener
*/
public void addDocumentListener(DocumentListener listener) {
searchTextField.getDocument().addDocumentListener(listener);
}
/**
* 按钮添加监听器
*
* @param listener
*/
public void addClearActionListener(ActionListener listener) {
clearButton.addActionListener(listener);
}
public String getText() {
return searchTextField.getText();
}
public void setText(String text) {
searchTextField.setText(text);
}
@Override
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
searchTextField.setEnabled(enabled);
clearButton.setEnabled(enabled);
}
}

2
designer-base/src/main/java/com/fr/design/data/datapane/management/search/pane/TableDataSearchRemindPane.java

@ -106,7 +106,7 @@ public class TableDataSearchRemindPane extends JPanel implements TreeSearchStatu
emptyPicLabel.setHorizontalAlignment(SwingConstants.CENTER);
emptyPicLabel.setPreferredSize(new Dimension(240, 100));
UILabel textLabel = new UILabel(Toolkit.i18nText("Fine-Design_Tree_Search_Not_Match"), SwingConstants.CENTER);
textLabel.setForeground(Color.gray);
// textLabel.setForeground(Color.gray);
textLabel.setHorizontalAlignment(SwingConstants.CENTER);
textLabel.setPreferredSize(new Dimension(240, 20));
notFoundPane.add(emptyPicLabel);

95
designer-base/src/main/java/com/fr/design/data/datapane/management/search/pane/TreeSearchToolbarPane.java

@ -1,35 +1,27 @@
package com.fr.design.data.datapane.management.search.pane;
import com.fr.base.svg.IconUtils;
import com.fine.theme.utils.FineUIScale;
import com.fr.design.DesignModelAdapter;
import com.fr.design.constants.UIConstants;
import com.fr.design.data.datapane.TableDataTreePane;
import com.fr.design.data.datapane.management.search.TableDataTreeSearchManager;
import com.fr.design.search.event.TreeSearchStatusChangeEvent;
import com.fr.design.search.event.TreeSearchStatusChangeListener;
import com.fr.design.search.TreeSearchStatus;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.gui.itoolbar.UIToolbar;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.search.TreeSearchStatus;
import com.fr.design.search.event.TreeSearchStatusChangeEvent;
import com.fr.design.search.event.TreeSearchStatusChangeListener;
import com.fr.stable.StringUtils;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
/**
* @author Yvan
@ -53,13 +45,7 @@ public class TreeSearchToolbarPane extends JPanel implements TreeSearchStatusCha
/**
* 搜索面板
*/
private JPanel searchPane;
/**
* 搜索输入框
*/
private UITextField searchTextField;
private FineSearchPane searchPane;
/**
* 内容面板
*/
@ -74,7 +60,7 @@ public class TreeSearchToolbarPane extends JPanel implements TreeSearchStatusCha
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
TableDataTreeSearchManager.getInstance().startSearch(searchTextField.getText());
TableDataTreeSearchManager.getInstance().startSearch(searchPane.getText());
}
}
};
@ -86,54 +72,25 @@ public class TreeSearchToolbarPane extends JPanel implements TreeSearchStatusCha
initSearchPane();
initContentPane();
add(contentPane, BorderLayout.CENTER);
setPreferredSize(new Dimension(240, 30));
TableDataTreeSearchManager.getInstance().registerTreeSearchStatusChangeListener(this);
}
private void initContentPane() {
cardLayout = new CardLayout();
contentPane = new JPanel(cardLayout);
Insets insets = UIManager.getInsets("TreeSearchToolbarPane.borderInsets");
Insets scaledInsets = FineUIScale.scale(insets);
contentPane.setBorder(BorderFactory.createEmptyBorder(scaledInsets.top, scaledInsets.left, scaledInsets.bottom, scaledInsets.right));
contentPane.add(searchPane, SEARCH_PANE);
contentPane.add(toolbarPane, TOOLBAR_PANE);
cardLayout.show(contentPane, TOOLBAR_PANE);
}
private void initSearchPane() {
searchPane = new JPanel(FRGUIPaneFactory.createBorderLayout());
searchPane.setBorder(BorderFactory.createLineBorder(UIConstants.TOOLBAR_BORDER_COLOR));
searchPane.setBackground(Color.WHITE);
// 左侧搜索图标
UILabel searchLabel = new UILabel(IconUtils.readIcon("/com/fr/design/standard/search"));
searchLabel.setBorder(BorderFactory.createEmptyBorder(0, 12, 0, 0));
searchLabel.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
// do nothing
}
});
searchPane = new FineSearchPane();
// 中间输入框
searchTextField = new UITextField(){
@Override
public Insets getInsets() {
return new Insets(2, 4, 0, 4);
}
};
searchTextField.setBorderPainted(false);
searchTextField.setPlaceholder(Toolkit.i18nText("Fine-Design_Tree_Search_Press_Enter_For_Search"));
searchTextField.addFocusListener(new FocusListener() {
@Override
public void focusGained(FocusEvent e) {
searchPane.setBorder(BorderFactory.createLineBorder(UIConstants.NORMAL_BLUE));
searchPane.repaint();
}
@Override
public void focusLost(FocusEvent e) {
searchPane.setBorder(BorderFactory.createLineBorder(UIConstants.TOOLBAR_BORDER_COLOR));
searchPane.repaint();
}
});
this.searchTextField.getDocument().addDocumentListener(new DocumentListener() {
searchPane.setPlaceholder(Toolkit.i18nText("Fine-Design_Tree_Search_Press_Enter_For_Search"));
searchPane.addDocumentListener(new DocumentListener() {
@Override
public void insertUpdate(DocumentEvent e) {
}
@ -147,25 +104,15 @@ public class TreeSearchToolbarPane extends JPanel implements TreeSearchStatusCha
public void changedUpdate(DocumentEvent e) {
}
});
this.searchTextField.addKeyListener(enterPressed);
// 右侧返回图标
UILabel returnLabel = new UILabel(IconUtils.readIcon("/com/fr/design/standard/clear"));
returnLabel.setToolTipText(Toolkit.i18nText("Fine-Design_Tree_Search_Return"));
returnLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 11));
returnLabel.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
TableDataTreeSearchManager.getInstance().outOfSearchMode();
}
});
searchPane.add(searchLabel, BorderLayout.WEST);
searchPane.add(searchTextField, BorderLayout.CENTER);
searchPane.add(returnLabel, BorderLayout.EAST);
searchPane.addKeyListener(enterPressed);
searchPane.setClearToolTipText(Toolkit.i18nText("Fine-Design_Tree_Search_Return"));
searchPane.addClearActionListener(e -> TableDataTreeSearchManager.getInstance().outOfSearchMode());
}
private void dealWithTextChange() {
if (StringUtils.isEmpty(searchTextField.getText()) && TableDataTreeSearchManager.getInstance().isInSearchMode()) {
if (StringUtils.isEmpty(searchPane.getText()) && TableDataTreeSearchManager.getInstance().isInSearchMode()) {
// 如果是搜索模式下,看作是用户删除输入框文字,仅复原TableDataTreePane
TableDataTreeSearchManager.getInstance().restoreTreePane();
TableDataTreePane.getInstance(DesignModelAdapter.getCurrentModelAdapter()).refreshDockingView();
@ -186,7 +133,7 @@ public class TreeSearchToolbarPane extends JPanel implements TreeSearchStatusCha
}
public void setPlaceHolder(String placeHolder) {
this.searchTextField.setPlaceholder(placeHolder);
searchPane.setPlaceholder(placeHolder);
}
/**
@ -198,7 +145,7 @@ public class TreeSearchToolbarPane extends JPanel implements TreeSearchStatusCha
public void updateTreeSearchChange(TreeSearchStatusChangeEvent event) {
TreeSearchStatus treeSearchStatus = event.getTreeSearchStatus();
if (treeSearchStatus == TreeSearchStatus.NOT_IN_SEARCH_MODE) {
this.searchTextField.setText(StringUtils.EMPTY);
searchPane.setText(StringUtils.EMPTY);
switchPane(TOOLBAR_PANE);
} else {
switchPane(SEARCH_PANE);

5
designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/ProcedureListPane.java

@ -1,5 +1,6 @@
package com.fr.design.data.tabledata.tabledatapane;
import com.fine.theme.icon.LazyIcon;
import com.fr.data.TableDataSource;
import com.fr.data.impl.storeproc.StoreProcedure;
import com.fr.design.data.DesignTableDataManager;
@ -14,7 +15,7 @@ import com.fr.stable.Nameable;
import com.fr.stable.StringUtils;
import com.fr.stable.core.PropertyChangeAdapter;
import javax.swing.*;
import javax.swing.DefaultListModel;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@ -101,7 +102,7 @@ public class ProcedureListPane extends JListControlPane {
* @return 面板组件
*/
public NameableCreator[] createNameableCreators() {
return new NameableCreator[] { new NameObjectCreator("Proc", "/com/fr/design/images/data/store_procedure.png", StoreProcedure.class,
return new NameableCreator[]{new NameObjectCreator("Proc", new LazyIcon("store_procedure"), StoreProcedure.class,
ProcedureDataPane.class) };
}

8
designer-base/src/main/java/com/fr/design/data/tabledata/wrapper/MultiResultTableDataWrapperHelper.java

@ -1,7 +1,7 @@
package com.fr.design.data.tabledata.wrapper;
import com.fine.theme.icon.LazyIcon;
import com.fr.base.TableData;
import com.fr.base.svg.IconUtils;
import com.fr.design.data.datapane.TableDataCreatorProducer;
import com.fr.design.data.datapane.TableDataNameObjectCreator;
import com.fr.design.fun.ServerTableDataDefineProvider;
@ -25,7 +25,7 @@ import java.util.Map;
*/
class MultiResultTableDataWrapperHelper {
private static final Map<Class<? extends TableData>, Icon> TABLE_DATA_ICON_PATHS = new HashMap<>();
private static final String DEFAULT_MULTI_RESULT_TD_ICON = "/com/fr/design/standard/multi";
private static final String DEFAULT_MULTI_RESULT_TD_ICON = "multi";
static {
@ -45,10 +45,10 @@ class MultiResultTableDataWrapperHelper {
return TABLE_DATA_ICON_PATHS.computeIfAbsent(tableDataClass, cls -> {
for (TableDataNameObjectCreator creator : TableDataCreatorProducer.getInstance().createReportTableDataCreator()) {
if (creator.createObject().getClass().isAssignableFrom(tableDataClass)) {
return IconUtils.readIcon(creator.getIconPath());
return creator.menuIcon();
}
}
return IconUtils.readIcon(DEFAULT_MULTI_RESULT_TD_ICON);
return new LazyIcon(DEFAULT_MULTI_RESULT_TD_ICON);
});
}
}

19
designer-base/src/main/java/com/fr/design/data/tabledata/wrapper/ServerTableDataWrapper.java

@ -1,8 +1,7 @@
package com.fr.design.data.tabledata.wrapper;
import com.fr.base.BaseUtils;
import com.fine.theme.icon.LazyIcon;
import com.fr.base.TableData;
import com.fr.base.svg.IconUtils;
import com.fr.base.svg.SVGLoader;
import com.fr.data.impl.ClassTableData;
import com.fr.data.impl.DBTableData;
@ -12,7 +11,7 @@ import com.fr.data.impl.storeproc.StoreProcedure;
import com.fr.design.icon.WarningIcon;
import com.fr.stable.StringUtils;
import javax.swing.*;
import javax.swing.Icon;
public final class ServerTableDataWrapper extends AbstractTableDataWrapper {
public ServerTableDataWrapper(TableData tabledata) {
@ -27,21 +26,21 @@ public final class ServerTableDataWrapper extends AbstractTableDataWrapper {
public Icon getIcon() {
if (tabledata instanceof DBTableData) {
if (StringUtils.isBlank(((DBTableData) tabledata).getQuery())) {
return new WarningIcon(SVGLoader.load("/com/fr/design/standard/server_database_normal.svg"));
return new WarningIcon(SVGLoader.load("/com/fr/design/standard/server_database.svg"));
}
else {
return IconUtils.readIcon("/com/fr/design/standard/server_database");
return new LazyIcon("server_database");
}
} else if (tabledata instanceof ClassTableData) {
return IconUtils.readIcon("/com/fr/design/standard/class_table_data");
return new LazyIcon("class_table_data");
} else if (tabledata instanceof EmbeddedTableData) {
return IconUtils.readIcon("/com/fr/design/standard/data_table");
return new LazyIcon("data_table");
}else if(tabledata instanceof RecursionTableData){
return IconUtils.readIcon("/com/fr/design/standard/tree");
return new LazyIcon("tree");
} else if (tabledata instanceof StoreProcedure) {
return IconUtils.readIcon("/com/fr/design/standard/store_procedure");
return new LazyIcon("store_procedure");
}
return IconUtils.readIcon("/com/fr/design/standard/server_database");
return new LazyIcon("server_database");
}
/**

4
designer-base/src/main/java/com/fr/design/data/tabledata/wrapper/StoreProcedureDataWrapper.java

@ -1,7 +1,7 @@
package com.fr.design.data.tabledata.wrapper;
import com.fine.theme.icon.LazyIcon;
import com.fr.base.TableData;
import com.fr.base.svg.IconUtils;
import com.fr.data.impl.storeproc.ProcedureDataModel;
import com.fr.data.impl.storeproc.StoreProcedure;
import com.fr.data.operator.DataOperator;
@ -150,7 +150,7 @@ public final class StoreProcedureDataWrapper implements TableDataWrapper {
@Override
public Icon getIcon() {
return IconUtils.readIcon("/com/fr/design/standard/store_procedure");
return new LazyIcon("store_procedure");
}
/**

4
designer-base/src/main/java/com/fr/design/data/tabledata/wrapper/StoreProcedureNameWrapper.java

@ -1,7 +1,7 @@
package com.fr.design.data.tabledata.wrapper;
import com.fine.theme.icon.LazyIcon;
import com.fr.base.TableData;
import com.fr.base.svg.IconUtils;
import com.fr.data.impl.storeproc.ProcedureDataModel;
import com.fr.data.impl.storeproc.StoreProcedure;
import com.fr.design.data.DesignTableDataManager;
@ -71,7 +71,7 @@ public final class StoreProcedureNameWrapper implements TableDataWrapper {
@Override
public Icon getIcon() {
return IconUtils.readIcon("/com/fr/design/standard/store_procedure");
return new LazyIcon("store_procedure");
}
private void createStore(boolean needLoadingBar) {

37
designer-base/src/main/java/com/fr/design/data/tabledata/wrapper/TableDataFactory.java

@ -1,5 +1,6 @@
package com.fr.design.data.tabledata.wrapper;
import com.fine.theme.icon.LazyIcon;
import com.fr.base.TableData;
import com.fr.data.TableDataSource;
import com.fr.data.impl.ClassTableData;
@ -29,6 +30,7 @@ import com.fr.stable.StringUtils;
import com.fr.workspace.WorkContext;
import com.fr.workspace.server.authority.user.UserAuthority;
import javax.swing.Icon;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Iterator;
@ -55,15 +57,15 @@ public abstract class TableDataFactory {
* 同一类型的只能加一次,就加最上层的类,因为要排序如果将所有的 FileTableData都加进来那么FileTableData的排序就不正确了
*/
static {
defaultMap.put(DBTableData.class.getName(), new TableDataNameObjectCreator(null, "/com/fr/design/standard/database_normal.svg", DBTableData.class, DBTableDataPane.class));
defaultMap.put(ClassTableData.class.getName(), new TableDataNameObjectCreator(null, "/com/fr/design/standard/class_table_data_normal.svg", ClassTableData.class, ClassTableDataPane.class));
defaultMap.put(EmbeddedTableData.class.getName(), new TableDataNameObjectCreator(null, "/com/fr/design/standard/data_table_normal.svg", EmbeddedTableData.class, EmbeddedTableDataPane.class));
defaultMap.put(DecoratedTableData.class.getName(), new TableDataNameObjectCreator(null, "/com/fr/design/standard/multi_normal.svg", DecoratedTableData.class, DecoratedTableDataPane.class));
defaultMap.put(StoreProcedure.class.getName(), new TableDataNameObjectCreator(null, "/com/fr/design/standard/store_procedure_normal.svg", StoreProcedure.class, ProcedureDataPane.class));
defaultMap.put(MultiTDTableData.class.getName(), new TableDataNameObjectCreator(null, "/com/fr/design/standard/multi_normal.svg", MultiTDTableData.class, MultiTDTableDataPane.class));
defaultMap.put(FileTableData.class.getName(), new TableDataNameObjectCreator(null, "/com/fr/design/standard/file_normal.svg", FileTableData.class, FileTableDataPane.class));
defaultMap.put(RecursionTableData.class.getName(), new TableDataNameObjectCreator(null, "/com/fr/design/standard/tree_normal.svg", RecursionTableData.class, TreeTableDataPane.class));
defaultMap.put(MultiFieldTableData.class.getName(), new TableDataNameObjectCreator(null, "/com/fr/design/standard/database_normal.svg", MultiFieldTableData.class, null));
defaultMap.put(DBTableData.class.getName(), new TableDataNameObjectCreator(null, new LazyIcon("database"), DBTableData.class, DBTableDataPane.class));
defaultMap.put(ClassTableData.class.getName(), new TableDataNameObjectCreator(null, new LazyIcon("class_table_data"), ClassTableData.class, ClassTableDataPane.class));
defaultMap.put(EmbeddedTableData.class.getName(), new TableDataNameObjectCreator(null, new LazyIcon("data_table"), EmbeddedTableData.class, EmbeddedTableDataPane.class));
defaultMap.put(DecoratedTableData.class.getName(), new TableDataNameObjectCreator(null, new LazyIcon("multi"), DecoratedTableData.class, DecoratedTableDataPane.class));
defaultMap.put(StoreProcedure.class.getName(), new TableDataNameObjectCreator(null, new LazyIcon("store_procedure"), StoreProcedure.class, ProcedureDataPane.class));
defaultMap.put(MultiTDTableData.class.getName(), new TableDataNameObjectCreator(null, new LazyIcon("multi"), MultiTDTableData.class, MultiTDTableDataPane.class));
defaultMap.put(FileTableData.class.getName(), new TableDataNameObjectCreator(null, new LazyIcon("file"), FileTableData.class, FileTableDataPane.class));
defaultMap.put(RecursionTableData.class.getName(), new TableDataNameObjectCreator(null, new LazyIcon("tree"), RecursionTableData.class, TreeTableDataPane.class));
defaultMap.put(MultiFieldTableData.class.getName(), new TableDataNameObjectCreator(null, new LazyIcon("database"), MultiFieldTableData.class, null));
map.putAll(defaultMap);
}
@ -143,15 +145,26 @@ public abstract class TableDataFactory {
/**
* 获取数据集所对应的图标路径
*
* @param tabledata
* @return
* 获取图标直接使用 {@link #getIcon(TableData)}
*/
@Deprecated
public static String getIconPath(TableData tabledata) {
TableDataNameObjectCreator tableDataNameObjectCreator = getTableDataNameObjectCreator(tabledata);
if (tableDataNameObjectCreator != null && tableDataNameObjectCreator.getIconPath() != null) {
return tableDataNameObjectCreator.getIconPath();
}
return "/com/fr/design/standard/database_normal.svg";
return "database";
}
/**
* 获取数据集所对应的图标
*/
public static Icon getIcon(TableData tabledata) {
TableDataNameObjectCreator tableDataNameObjectCreator = getTableDataNameObjectCreator(tabledata);
if (tableDataNameObjectCreator != null && tableDataNameObjectCreator.menuIcon() != null) {
return tableDataNameObjectCreator.menuIcon();
}
return new LazyIcon(getIconPath(tabledata));
}
/**

9
designer-base/src/main/java/com/fr/design/data/tabledata/wrapper/TemplateTableDataWrapper.java

@ -1,14 +1,13 @@
package com.fr.design.data.tabledata.wrapper;
import javax.swing.Icon;
import com.fr.base.TableData;
import com.fr.base.svg.IconUtils;
import com.fr.base.svg.SVGLoader;
import com.fr.data.impl.DBTableData;
import com.fr.design.icon.WarningIcon;
import com.fr.stable.StringUtils;
import javax.swing.Icon;
public final class TemplateTableDataWrapper extends AbstractTableDataWrapper {
public TemplateTableDataWrapper(TableData tabledata) {
super(tabledata);
@ -21,9 +20,9 @@ public final class TemplateTableDataWrapper extends AbstractTableDataWrapper {
@Override
public Icon getIcon() {
if (tabledata instanceof DBTableData && StringUtils.isBlank(((DBTableData) tabledata).getQuery())) {
return new WarningIcon(SVGLoader.load("/com/fr/design/standard/database_normal.svg"));
return new WarningIcon(SVGLoader.load("/com/fr/design/standard/database.svg"));
}
return IconUtils.readIcon(TableDataFactory.getIconPath(tabledata));
return TableDataFactory.getIcon(tabledata);
}
@Override

2
designer-base/src/main/java/com/fr/design/dialog/MultiTabPane.java

@ -81,7 +81,7 @@ public abstract class MultiTabPane<T> extends FurtherBasicBeanPane<T>{
}
protected void initLayout() {
this.setLayout(new BorderLayout(0, 4));
this.setLayout(new BorderLayout());
this.add(tabPane, BorderLayout.NORTH);
this.add(centerPane, BorderLayout.CENTER);
}

11
designer-base/src/main/java/com/fr/design/dialog/UIDialog.java

@ -1,5 +1,9 @@
package com.fr.design.dialog;
import com.fine.swing.ui.layout.Layouts;
import com.fine.theme.utils.FineUIStyle;
import com.formdev.flatlaf.util.ScaledEmptyBorder;
import com.fr.design.constants.LayoutConstants;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.utils.gui.GUICoreUtils;
@ -77,8 +81,8 @@ public abstract class UIDialog extends JDialog {
private void initComponents(boolean isNeedButtonPane) {
JPanel contentPane = (JPanel) this.getContentPane();
contentPane.setBorder(BorderFactory.createEmptyBorder(2, 4, 4, 4));
contentPane.setLayout(new BorderLayout(0, 4));
contentPane.setBorder(new ScaledEmptyBorder(10, 10, 10, 10));
contentPane.setLayout(new BorderLayout(0, 10));
this.applyClosingAction();
this.applyEscapeAction();
contentPane.add(pane, BorderLayout.CENTER);
@ -94,7 +98,7 @@ public abstract class UIDialog extends JDialog {
private JPanel createControlButtonPane() {
JPanel controlPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
JPanel buttonsPane = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 0));
JPanel buttonsPane = Layouts.row(LayoutConstants.HORIZONTAL_GAP).getComponent();
controlPane.add(buttonsPane, BorderLayout.EAST);
//增加一个自定义按钮, 可以用于eg: 设为全局配置
@ -148,6 +152,7 @@ public abstract class UIDialog extends JDialog {
okButton = new UIButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_OK"));
okButton.setName(OK_BUTTON);
okButton.setMnemonic('O');
FineUIStyle.setStyle(okButton, FineUIStyle.STYLE_PRIMARY);
buttonsPane.add(okButton);
okButton.addActionListener(new ActionListener() {

47
designer-base/src/main/java/com/fr/design/editor/DoubleDeckValueEditorPane.java

@ -1,7 +1,9 @@
package com.fr.design.editor;
import com.fine.swing.ui.layout.Layouts;
import com.fr.base.BaseFormula;
import com.fr.design.DesignerEnvManager;
import com.fr.design.constants.LayoutConstants;
import com.fr.design.dialog.BasicPane;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.editor.editor.ColumnIndexEditor;
@ -25,12 +27,12 @@ import com.fr.general.ComparatorUtils;
import com.fr.stable.StringUtils;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import static com.fine.swing.ui.layout.Layouts.cell;
/**
* Created by MoMeak on 2017/7/26.
*/
@ -45,7 +47,6 @@ public class DoubleDeckValueEditorPane extends BasicPane implements UIObserver,
private UIButton arrowButton;
private JPopupMenu menu;
private JPanel centerPane;
private CardLayout cardLayout;
private Object value;
private UIButtonGroup upButton;
private GlobalNameListener globalNameListener = null;
@ -76,42 +77,38 @@ public class DoubleDeckValueEditorPane extends BasicPane implements UIObserver,
private void initComponents(final Editor[] cards, String popupName, String textEditorValue, int centerPaneWidth) {
this.setLayout(new BorderLayout(0, 4));
this.setLayout(new BorderLayout());
this.cards = cards;
final String[] nameArray = new String[cards.length];
for (int i = 0; i < cards.length; i++) {
nameArray[i] = cards[i].getName();
}
upButton = new UIButtonGroup(nameArray);
upButton = new UIButtonGroup<>(nameArray);
upButton.setAllToolTips(nameArray);
this.add(upButton, BorderLayout.NORTH);
centerPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
setCurrentEditor(0);
centerPane.setPreferredSize(new Dimension(centerPaneWidth, centerPane.getPreferredSize().height));
menu = createPopMenu();
upButton.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
if (globalNameListener != null) {
globalNameListener.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_CellWrite_InsertRow_Policy"));
}
Object oldValue = currentEditor.getValue();
setCurrentEditor(upButton.getSelectedIndex());
currentEditor.selected();
value = currentEditor.getValue();
if (uiObserverListener != null) {
uiObserverListener.doChange();
}
DoubleDeckValueEditorPane.this.firePropertyChange("value", oldValue, value);
upButton.addChangeListener(e -> {
if (globalNameListener != null) {
globalNameListener.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_CellWrite_InsertRow_Policy"));
}
Object oldValue = currentEditor.getValue();
setCurrentEditor(upButton.getSelectedIndex());
currentEditor.selected();
value = currentEditor.getValue();
if (uiObserverListener != null) {
uiObserverListener.doChange();
}
DoubleDeckValueEditorPane.this.firePropertyChange("value", oldValue, value);
});
this.add(centerPane, BorderLayout.CENTER);
this.add(Layouts.column(LayoutConstants.VERTICAL_GAP,
cell(upButton),
cell(centerPane)
).getComponent(), BorderLayout.CENTER);
}

2
designer-base/src/main/java/com/fr/design/editor/editor/ColumnIndexEditor.java

@ -41,8 +41,6 @@ public class ColumnIndexEditor extends Editor<Object> {
}
this.add(valueColumnIndexComboBox, BorderLayout.CENTER);
this.setName(name);
valueColumnIndexComboBox.setBorder(null);
}
@Override

2
designer-base/src/main/java/com/fr/design/editor/editor/TextEditor.java

@ -5,7 +5,6 @@ package com.fr.design.editor.editor;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.stable.StringUtils;
import java.awt.BorderLayout;
@ -40,7 +39,6 @@ public class TextEditor extends Editor<String> {
public TextEditor(String value) {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
textField = new UITextField();
textField.setBorder(null);
this.add(textField, BorderLayout.CENTER);
this.textField.addKeyListener(textKeyListener);

13
designer-base/src/main/java/com/fr/design/event/HoverAware.java

@ -0,0 +1,13 @@
package com.fr.design.event;
/**
* 组件判断是否被hover的能力接口
*
* @author Levy.Xie
* @since 11.0
* Created on 2023/12/07
*/
public interface HoverAware {
boolean isHovered();
}

25
designer-base/src/main/java/com/fr/design/extra/exe/callback/ModifyStatusCallback.java

@ -7,6 +7,7 @@ import com.fr.design.extra.PluginOperateUtils;
import com.fr.design.i18n.Toolkit;
import com.fr.design.plugin.DesignerPluginContext;
import com.fr.design.ui.util.UIUtil;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.manage.control.PluginTaskCallback;
import com.fr.plugin.manage.control.PluginTaskResult;
@ -32,17 +33,19 @@ public class ModifyStatusCallback implements PluginTaskCallback {
@Override
public void done(PluginTaskResult result) {
String pluginInfo = PluginOperateUtils.getSuccessInfo(result);
if (result.isSuccess()) {
jsCallback.execute("success");
String modifyMessage = isActive ?
pluginInfo + Toolkit.i18nText("Fine-Design_Basic_Plugin_Has_Been_Disabled_Duplicate") :
pluginInfo + Toolkit.i18nText("Fine-Design_Plugin_Has_Been_Actived_Duplicate");
FineLoggerFactory.getLogger().info(modifyMessage);
FineJOptionPane.showMessageDialog(DesignerPluginContext.getPluginDialog(), modifyMessage);
} else {
FineJOptionPane.showMessageDialog(DesignerPluginContext.getPluginDialog(), pluginInfo, Toolkit.i18nText("Fine-Design_Basic_Plugin_Warning"), JOptionPane.ERROR_MESSAGE);
}
UIUtil.invokeLaterIfNeeded(() -> {
String pluginInfo = PluginOperateUtils.getSuccessInfo(result);
if (result.isSuccess()) {
jsCallback.execute("success");
String modifyMessage = isActive ?
pluginInfo + Toolkit.i18nText("Fine-Design_Basic_Plugin_Has_Been_Disabled_Duplicate") :
pluginInfo + Toolkit.i18nText("Fine-Design_Plugin_Has_Been_Actived_Duplicate");
FineLoggerFactory.getLogger().info(modifyMessage);
FineJOptionPane.showMessageDialog(DesignerPluginContext.getPluginDialog(), modifyMessage);
} else {
FineJOptionPane.showMessageDialog(DesignerPluginContext.getPluginDialog(), pluginInfo, Toolkit.i18nText("Fine-Design_Basic_Plugin_Warning"), JOptionPane.ERROR_MESSAGE);
}
});
}
}

47
designer-base/src/main/java/com/fr/design/extra/exe/callback/UninstallPluginCallback.java

@ -5,6 +5,7 @@ import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.extra.PluginOperateUtils;
import com.fr.design.i18n.Toolkit;
import com.fr.design.ui.util.UIUtil;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.context.PluginMarker;
import com.fr.plugin.error.PluginErrorCode;
@ -17,34 +18,36 @@ import com.fr.plugin.manage.control.PluginTaskResult;
public class UninstallPluginCallback extends AbstractPluginTaskCallback {
private JSCallback jsCallback;
public UninstallPluginCallback(PluginMarker pluginMarker, JSCallback jsCallback){
public UninstallPluginCallback(PluginMarker pluginMarker, JSCallback jsCallback) {
this.jsCallback = jsCallback;
this.pluginMarker = pluginMarker;
}
@Override
public void done(PluginTaskResult result) {
String pluginInfo = PluginOperateUtils.getSuccessInfo(result);
if (result.isSuccess()) {
jsCallback.execute("success");
String successInfo = pluginInfo + Toolkit.i18nText("Fine-Design_Basic_Plugin_Delete_Success");
FineLoggerFactory.getLogger().info(successInfo);
FineJOptionPane.showMessageDialog(null, successInfo);
}else if (result.errorCode() == PluginErrorCode.NeedUninstallDependingPluginFirst) {
int rv = FineJOptionPane.showConfirmDialog(
null,
Toolkit.i18nText("Fine-Design_Basic_Plugin_Delete_Dependence"),
Toolkit.i18nText("Fine-Design_Basic_Plugin_Warning"),
FineJOptionPane.OK_CANCEL_OPTION,
FineJOptionPane.INFORMATION_MESSAGE
);
if (rv == FineJOptionPane.OK_OPTION) {
PluginManager.getController().uninstall(pluginMarker, true, new UninstallPluginCallback(pluginMarker, jsCallback));
UIUtil.invokeLaterIfNeeded(() -> {
String pluginInfo = PluginOperateUtils.getSuccessInfo(result);
if (result.isSuccess()) {
jsCallback.execute("success");
String successInfo = pluginInfo + Toolkit.i18nText("Fine-Design_Basic_Plugin_Delete_Success");
FineLoggerFactory.getLogger().info(successInfo);
FineJOptionPane.showMessageDialog(null, successInfo);
} else if (result.errorCode() == PluginErrorCode.NeedUninstallDependingPluginFirst) {
int rv = FineJOptionPane.showConfirmDialog(
null,
Toolkit.i18nText("Fine-Design_Basic_Plugin_Delete_Dependence"),
Toolkit.i18nText("Fine-Design_Basic_Plugin_Warning"),
FineJOptionPane.OK_CANCEL_OPTION,
FineJOptionPane.INFORMATION_MESSAGE
);
if (rv == FineJOptionPane.OK_OPTION) {
PluginManager.getController().uninstall(pluginMarker, true, new UninstallPluginCallback(pluginMarker, jsCallback));
}
} else {
jsCallback.execute("failed");
FineLoggerFactory.getLogger().info(Toolkit.i18nText("Fine-Design_Basic_Plugin_Delete_Failed"));
FineJOptionPane.showMessageDialog(null, pluginInfo, Toolkit.i18nText("Fine-Design_Basic_Plugin_Warning"), FineJOptionPane.ERROR_MESSAGE);
}
} else {
jsCallback.execute("failed");
FineLoggerFactory.getLogger().info(Toolkit.i18nText("Fine-Design_Basic_Plugin_Delete_Failed"));
FineJOptionPane.showMessageDialog(null, pluginInfo, Toolkit.i18nText("Fine-Design_Basic_Plugin_Warning"), FineJOptionPane.ERROR_MESSAGE);
}
});
}
}

7
designer-base/src/main/java/com/fr/design/file/DefaultTemplateTreeDefineProcessor.java

@ -1,5 +1,6 @@
package com.fr.design.file;
import com.fine.theme.icon.LazyIcon;
import com.fr.design.actions.UpdateAction;
import com.fr.design.actions.file.DelFileAction;
import com.fr.design.actions.file.LocateAction;
@ -147,7 +148,7 @@ public class DefaultTemplateTreeDefineProcessor extends AbstractTemplateTreeDefi
public CopyAction() {
this.setName(Toolkit.i18nText("Fine-Design_Basic_Copy"));
this.setMnemonic('C');
this.setSmallIcon("/com/fr/design/images/m_edit/copy");
this.setSmallIcon(new LazyIcon("monochrome_copy"));
}
@Override
@ -190,7 +191,7 @@ public class DefaultTemplateTreeDefineProcessor extends AbstractTemplateTreeDefi
public PasteAction() {
this.setName(Toolkit.i18nText("Fine-Design_Basic_Action_Paste_Name"));
this.setMnemonic('P');
this.setSmallIcon("/com/fr/design/images/m_edit/paste");
this.setSmallIcon(new LazyIcon("monochrome_paste"));
}
@Override
@ -315,7 +316,7 @@ public class DefaultTemplateTreeDefineProcessor extends AbstractTemplateTreeDefi
public MoveAction() {
this.setName(Toolkit.i18nText("Fine-Design_Basic_Move"));
this.setSmallIcon("/com/fr/design/images/m_edit/move");
this.setSmallIcon(new LazyIcon("move"));
}
@Override

731
designer-base/src/main/java/com/fr/design/file/MultiTemplateTabPane.java

File diff suppressed because it is too large Load Diff

173
designer-base/src/main/java/com/fr/design/file/NewTemplatePane.java

@ -1,173 +0,0 @@
package com.fr.design.file;
import com.fr.base.BaseUtils;
import com.fr.base.vcs.DesignerMode;
import com.fr.design.constants.UIConstants;
import com.fr.design.mainframe.DesignerContext;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
/**
* Author : daisy
* Date: 13-8-27
* Time: 下午6:07
*/
public abstract class NewTemplatePane extends JComponent implements MouseListener, MouseMotionListener {
private static final Icon GRAY_NEW_CPT = BaseUtils.readIcon("/com/fr/design/images/buttonicon/additicon_grey.png");
private static final int ICON_START_X = 5;
private static final int HEIGHT = 26;
private Graphics2D g2d;
private Icon newWorkBookIconMode = null;
public NewTemplatePane() {
newWorkBookIconMode = getNew();
this.setLayout(new BorderLayout(0, 0));
this.addMouseListener(this);
this.addMouseMotionListener(this);
this.setBorder(null);
this.setForeground(new Color(99, 99, 99));
}
public Dimension getPreferredSize() {
Dimension dim = super.getPreferredSize();
dim.width = HEIGHT;
return dim;
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g2d = (Graphics2D) g;
g2d.setColor(UIConstants.TEMPLATE_TAB_PANE_BACKGROUND);
g2d.fill(new Rectangle2D.Double(0, 0, getWidth(),getHeight()));
int sheetIconY = (getHeight() - newWorkBookIconMode.getIconHeight()) / 2;
newWorkBookIconMode.paintIcon(this, g2d, ICON_START_X, sheetIconY);
// paintUnderLine(g2d);
}
private void paintUnderLine(Graphics2D g2d) {
//画下面的那条线
g2d.setPaint(UIConstants.LINE_COLOR);
g2d.draw(new Line2D.Double((float) 0, (float) (getHeight()-1), getWidth(), (float) (getHeight()-1)));
}
/**
*鼠标点击
* @param e 事件
*/
public void mouseClicked(MouseEvent e) {
if (needGrayNewCpt()) {
newWorkBookIconMode = GRAY_NEW_CPT;
}
}
/**
*鼠标按下
* @param e 事件
*/
public void mousePressed(MouseEvent e) {
int evtX = e.getX();
if (needGrayNewCpt()) {
newWorkBookIconMode = GRAY_NEW_CPT;
}
if (isOverNewIcon(evtX) && newWorkBookIconMode != GRAY_NEW_CPT) {
newWorkBookIconMode = getMousePressNew();
createNewTemplate();
}
this.repaint();
}
/**
* 新建模板
*/
protected void createNewTemplate() {
DesignerContext.getDesignerFrame().addAndActivateJTemplate();
}
/**
*鼠标松开
* @param e 事件
*/
public void mouseReleased(MouseEvent e) {
if (needGrayNewCpt()) {
newWorkBookIconMode = GRAY_NEW_CPT;
}
}
/**
*鼠标进入
* @param e 事件
*/
public void mouseEntered(MouseEvent e) {
if (needGrayNewCpt()) {
newWorkBookIconMode = GRAY_NEW_CPT;
}
}
/**
*鼠标离开
* @param e 事件
*/
public void mouseExited(MouseEvent e) {
if (needGrayNewCpt()) {
newWorkBookIconMode = GRAY_NEW_CPT;
} else {
newWorkBookIconMode = getNew();
}
this.repaint();
}
/**
*鼠标拖拽
* @param e 事件
*/
public void mouseDragged(MouseEvent e) {
}
/**
*鼠标移动
* @param e 事件
*/
public void mouseMoved(MouseEvent e) {
int evtX = e.getX();
if (needGrayNewCpt()) {
newWorkBookIconMode = GRAY_NEW_CPT;
} else if (isOverNewIcon(evtX)) {
newWorkBookIconMode = getMouseOverNew();
}
this.repaint();
}
private boolean needGrayNewCpt() {
return DesignerMode.isAuthorityEditing() || DesignerMode.isVcsMode();
}
private boolean isOverNewIcon(int evtX) {
return (evtX >= ICON_START_X && evtX <= ICON_START_X + newWorkBookIconMode.getIconWidth());
}
public void setButtonGray(boolean isGray) {
newWorkBookIconMode = isGray ? GRAY_NEW_CPT : getNew();
}
public abstract Icon getNew();
public abstract Icon getMouseOverNew();
public abstract Icon getMousePressNew();
}

91
designer-base/src/main/java/com/fr/design/foldablepane/HeaderPane.java

@ -1,36 +1,46 @@
package com.fr.design.foldablepane;
import com.fine.theme.icon.LazyIcon;
import com.fine.theme.utils.FineUIScale;
import com.formdev.flatlaf.util.ScaledEmptyBorder;
import com.fr.base.GraphHelper;
import com.fr.design.constants.UIConstants;
import com.fr.design.gui.syntax.ui.rsyntaxtextarea.RSyntaxUtilities;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Map;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
/**
* Created by MoMeak on 2017/7/5.
*/
public class HeaderPane extends JPanel {
private static final long serialVersionUID = 1L;
private static final int TITLE_X = 5;
private static final int LEFT_X = 16;
private static final int LEFT_Y = 6;
private static final int NORMAL_FONTSIZE = 12;
private final Insets defaultInsets = new Insets(0, 6, 0, 6);
private final int defaultWidth = 248;
private final int defaultHeight = 24;
private int headWidth;
private int headHeight;
private Color bgColor;
private boolean isShow;
private boolean isPressed = false;
private String title;
private Image image;
private int fontSize;
private final Icon triangleDown;
private final Icon triangleRight;
public void setPressed(boolean pressed) {
this.isPressed = pressed;
}
public void setShow(boolean isShow) {
this.isShow = isShow;
}
@ -55,58 +65,41 @@ public class HeaderPane extends JPanel {
@Override
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
BufferedImage panelImage = createPanelImage();
g2d.drawImage(panelImage, null, 0, 0);
GraphHelper.drawString(g2d, this.title, TITLE_X, headHeight - fontSize / 2 - 1);
}
g2d.setColor(getBackground());
g2d.fillRect(0, 0, this.getWidth(), this.getHeight());
private BufferedImage createPanelImage() {
BufferedImage panelImage = new BufferedImage(getWidth(), headHeight, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = panelImage.createGraphics();
g2d.setColor(isPressed ? UIConstants.POPUP_TITLE_BACKGROUND : UIConstants.COMPONENT_BACKGROUND_COLOR);
headWidth = this.getWidth();
g2d.fillRect(0, 0, headWidth, headHeight);
g2d.setFont(new Font("SimSun", 0, fontSize));
g2d.setPaint(bgColor);
Map<?, ?> desktopHints = RSyntaxUtilities.getDesktopAntiAliasHints();
if (desktopHints != null) {
g2d.setRenderingHints(desktopHints);
}
int leftWdith = headWidth - LEFT_X;
int iconY = (this.getHeight() - triangleDown.getIconHeight()) / 2;
if (this.isShow) {
image = UIConstants.DRAG_DOWN_SELECTED_SMALL;
g2d.drawImage(image, leftWdith, LEFT_Y, null);
triangleDown.paintIcon(this, g2d, 0, iconY);
} else {
image = UIConstants.DRAG_LEFT_NORMAL_SMALL;
g2d.drawImage(image, leftWdith, LEFT_Y, null);
triangleRight.paintIcon(this, g2d, 0, iconY);
}
return panelImage;
}
@Override
public Dimension getPreferredSize() {
return new Dimension(this.getWidth(), headHeight);
}
g2d.setFont(getFont());
g2d.setPaint(getForeground());
g2d.setComposite(AlphaComposite.SrcOver.derive((float) getForeground().getAlpha() / 255));
@Override
public Dimension getSize() {
return new Dimension(this.getWidth(), headHeight);
FontMetrics metrics = g2d.getFontMetrics();
int ascent = metrics.getAscent();
int descent = metrics.getDescent();
double titleY = (double) (getHeight() - (ascent + descent)) / 2 + ascent;
GraphHelper.drawString(g2d, this.title, triangleDown.getIconWidth() + FineUIScale.scale(UIManager.getInt("ExpandablePane.HeaderPane.hGap")), titleY);
g2d.dispose();
}
public HeaderPane(Color bgColor) {
this.bgColor = bgColor;
this.isShow = true;
triangleDown = new LazyIcon("triangle_down");
triangleRight = new LazyIcon("triangle_right");
this.setForeground(UIManager.getColor("ExpandablePane.HeaderPane.foreground"));
this.setFont(getFont().deriveFont(Font.BOLD));
this.setBorder(new ScaledEmptyBorder(17, 0, 17, 0));
}
public HeaderPane(Color bgColor, String title, int headHeight) {
this(bgColor);
this.title = title;
this.headHeight = headHeight;
this.fontSize = NORMAL_FONTSIZE;
}
public static void main(String[] args) {

8
designer-base/src/main/java/com/fr/design/foldablepane/UIExpandablePane.java

@ -1,7 +1,9 @@
package com.fr.design.foldablepane;
import javax.swing.*;
import java.awt.*;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
@ -11,7 +13,6 @@ import java.awt.event.MouseEvent;
*/
public class UIExpandablePane extends JPanel {
private static final int LEFT_BORDER = 5;
private static final long serialVersionUID = 1L;
private HeaderPane headerPanel;
private JPanel contentPanel;
@ -53,7 +54,6 @@ public class UIExpandablePane extends JPanel {
}
protected void setcontentPanelontentPanelBorder (){
contentPanel.setBorder(BorderFactory.createEmptyBorder(0 ,LEFT_BORDER, 0, 0));
}

191
designer-base/src/main/java/com/fr/design/formula/FormulaPane.java

@ -1,5 +1,10 @@
package com.fr.design.formula;
import com.fine.swing.ui.layout.Layouts;
import com.fine.theme.icon.LazyIcon;
import com.fine.theme.light.ui.FineRoundBorder;
import com.fine.theme.utils.FineUIScale;
import com.formdev.flatlaf.ui.FlatUIUtils;
import com.fr.base.BaseFormula;
import com.fr.base.BaseUtils;
import com.fr.base.Parameter;
@ -10,6 +15,7 @@ import com.fr.base.io.IOFile;
import com.fr.data.TableDataSource;
import com.fr.design.actions.UpdateAction;
import com.fr.design.border.UIRoundedBorder;
import com.fr.design.constants.LayoutConstants;
import com.fr.design.constants.UIConstants;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.BasicPane;
@ -67,7 +73,7 @@ import com.fr.stable.script.Tiny;
import com.fr.stable.script.TinyHunter;
import java.awt.Window;
import javax.swing.BorderFactory;
import javax.swing.SwingConstants;
import javax.swing.DefaultListCellRenderer;
import javax.swing.DefaultListModel;
import javax.swing.Icon;
@ -93,7 +99,6 @@ import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
@ -121,6 +126,10 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import static com.fine.swing.ui.layout.Layouts.row;
import static com.fine.swing.ui.layout.Layouts.cell;
import static com.fine.swing.ui.layout.Layouts.flex;
/**
* 公式编辑面板
*
@ -129,13 +138,11 @@ import java.util.Set;
*/
@EnableMetrics
public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
public static final int DEFUAL_FOMULA_LENGTH = 103;
public static final int DEFUAL_FOMULA_LENGTH = FineUIScale.scale(103);
public static final String ELLIPSIS = "...";
public static final char KEY_CODE_A = 'A';
public static final char KEY_CODE_Z = 'z';
public static final String NEWLINE = "\n";
public static final String FORMULA_ICON = "/com/fr/design/images/m_file/formula.png";
public static final String PARAM_ICON = "/com/fr/design/images/m_file/param.png";
private VariableTreeAndDescriptionArea variableTreeAndDescriptionArea;
private RSyntaxTextArea formulaTextArea;
private UITextField keyWordTextField = new UITextField(18);
@ -157,8 +164,6 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
private DefaultCompletionProvider completionProvider;
private static final Map<String, String> PARAM_PREFIX_MAP = new HashMap<>();
public static final int DESCRIPTION_TEXT_AREA_ROW = 16, DESCRIPTION_TEXT_AREA_COLUMN = 27;
public FormulaPane() {
initComponents();
}
@ -256,26 +261,17 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
});
}
private void initTipsPane() {
private JPanel initTipsPane() {
// tipsPane
JPanel containerSPane = new JPanel(new BorderLayout(4, 1));
JPanel labelPane = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0), true);
JPanel searchPane = new JPanel(new FlowLayout(FlowLayout.RIGHT, 0, 0), true);
containerSPane.setPreferredSize(new Dimension(892, 23));
this.add(containerSPane, BorderLayout.NORTH);
UIButton searchButton = new UIButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaPane_Search"));
UILabel formulaLabel = new UILabel(
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Input_Formula_In_The_Text_Area_Below") + ":");
formulaLabel.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
labelPane.add(formulaLabel, BorderLayout.WEST);
keyWordTextField.setPreferredSize(new Dimension(240, 23));
searchPane.add(keyWordTextField, BorderLayout.EAST);
searchPane.add(searchButton, BorderLayout.EAST);
containerSPane.add(labelPane, BorderLayout.WEST);
containerSPane.add(searchPane, BorderLayout.EAST);
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Input_Formula_In_The_Text_Area_Below") + ":", SwingConstants.LEFT);
JPanel containerSPane = row(
cell(formulaLabel),
flex(),
cell(keyWordTextField),
cell(searchButton)
).getComponent();
initKeyWordTextFieldKeyListener();
tipsList = new JList(listModel);
@ -289,14 +285,22 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
fixFunctionNameList(tipsList.getSelectedValue().toString());
}
});
return containerSPane;
}
protected void initComponents() {
this.setLayout(new BorderLayout(4, 4));
this.setLayout(new BorderLayout());
initTextPane();
initTipsPane();
initVariableTreeAndDescriptionArea();
JPanel textPane = initTextPane();
JPanel tipsPane = initTipsPane();
JPanel variablePane = initVariableTreeAndDescriptionArea();
this.add(Layouts.column(LayoutConstants.VERTICAL_GAP,
cell(tipsPane),
cell(textPane).weight(1),
cell(variablePane).weight(2)
).getComponent());
refocusInWindow();
}
@ -304,37 +308,31 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
SwingUtilities.invokeLater(() -> formulaTextArea.requestFocusInWindow());
}
private void initVariableTreeAndDescriptionArea() {
private JPanel initVariableTreeAndDescriptionArea() {
variableTreeAndDescriptionArea = new VariableTreeAndDescriptionArea();
this.add(variableTreeAndDescriptionArea, BorderLayout.SOUTH);
return variableTreeAndDescriptionArea;
}
private void initTextPane() {
private JPanel initTextPane() {
JPanel textPane = new JPanel(new BorderLayout(0, LayoutConstants.VERTICAL_GAP));
JPanel checkBoxAndButtonPane = new JPanel(new BorderLayout());
// text
JPanel textPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
this.add(textPane, BorderLayout.CENTER);
JPanel checkBoxandbuttonPane = FRGUIPaneFactory.createX_AXISBoxInnerContainer_S_Pane();
initFormulaTextArea();
UIScrollPane formulaTextAreaScrollPane = new UIScrollPane(formulaTextArea);
formulaTextAreaScrollPane.setBorder(null);
textPane.add(formulaTextAreaScrollPane, BorderLayout.CENTER);
textPane.add(checkBoxandbuttonPane, BorderLayout.SOUTH);
formulaTextAreaScrollPane.setBorder(new FineRoundBorder());
// buttonPane
JPanel buttonPane = row(8).getComponent();
UIButton checkValidButton = new UIButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Check_Valid"));
UIButton calButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Formula_Cal_Button"));
checkValidButton.addActionListener(checkValidActionListener);
calButton.addActionListener(calculateActionListener);
buttonPane.add(checkValidButton);
buttonPane.add(calButton);
//靠左流式布局
JPanel checkBoxPane = FRGUIPaneFactory.createNormalFlowInnerContainer_S_Pane();
checkBoxandbuttonPane.add(checkBoxPane, BorderLayout.WEST);
//靠右流式布局
JPanel buttonPane = FRGUIPaneFactory.createRightFlowInnerContainer_S_Pane();
buttonPane.add(checkValidButton, BorderLayout.EAST);
buttonPane.add(calButton, BorderLayout.EAST);
checkBoxandbuttonPane.add(buttonPane, BorderLayout.EAST);
// checkBoxPane
JPanel checkBoxPane = row(8).getComponent();
if (autoCompletionCheck == null) {
autoCompletionCheck = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_AutoCompletion"));
autoCompletionCheck.setSelected(true);
@ -343,10 +341,16 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
checkBeforeColse = new UICheckBox(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Before_Closed"));
checkBeforeColse.setSelected(true);
}
checkBoxPane.add(autoCompletionCheck, BorderLayout.WEST);
checkBoxPane.add(checkBeforeColse, BorderLayout.WEST);
checkBoxPane.add(autoCompletionCheck);
checkBoxPane.add(checkBeforeColse);
extendCheckBoxPane(checkBoxPane);
// layout
checkBoxAndButtonPane.add(checkBoxPane, BorderLayout.WEST);
checkBoxAndButtonPane.add(buttonPane, BorderLayout.EAST);
textPane.add(formulaTextAreaScrollPane, BorderLayout.CENTER);
textPane.add(checkBoxAndButtonPane, BorderLayout.SOUTH);
ParameterTableModel model = new ParameterTableModel(0);
editor4CalPane = new UITableEditorPane<>(model);
formulaTextArea.addFocusListener(new FocusListener() {
@ -364,6 +368,7 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
uninstallAutoCompletion();
}
});
return textPane;
}
private CompletionProvider createCompletionProvider() {
@ -371,7 +376,7 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
completionProvider = new DefaultCompletionProvider();
NameAndDescription[] nameAndDescriptions = FunctionConstants.ALL.getDescriptions();
for (NameAndDescription nameAndDescription : nameAndDescriptions) {
completionProvider.addCompletion(new FormulaCompletion(completionProvider, nameAndDescription.getName(), BaseUtils.readIcon(FORMULA_ICON)));
completionProvider.addCompletion(new FormulaCompletion(completionProvider, nameAndDescription.getName(), new LazyIcon("formula")));
}
VariableResolver variableResolver = VariableResolver.DEFAULT;
@ -395,7 +400,7 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
paramWithoutPre = parameter;
PARAM_PREFIX_MAP.put(paramWithoutPre, StringUtils.EMPTY);
}
completionProvider.addCompletion(new FormulaCompletion(completionProvider, paramWithoutPre, BaseUtils.readIcon(PARAM_ICON)));
completionProvider.addCompletion(new FormulaCompletion(completionProvider, paramWithoutPre, new LazyIcon("param")));
}
return completionProvider;
@ -646,7 +651,7 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
popupMenu = new JPopupMenu();
JScrollPane tipsScrollPane = new JScrollPane(tipsList);
popupMenu.add(tipsScrollPane);
tipsScrollPane.setPreferredSize(new Dimension(240, 146));
tipsScrollPane.setPreferredSize(new Dimension(FineUIScale.scale(240), FineUIScale.scale(146)));
tipsScrollPane.setBorder(new UIRoundedBorder(UIConstants.LINE_COLOR, 1, UIConstants.ARC));
popupMenu.show(keyWordTextField, 0, 23);
}
@ -743,9 +748,10 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
}
public BasicDialog showLargeWindow(Window window, DialogActionListener l) {
Dimension dimension = DesignSizeI18nManager.getInstance().i18nDimension(this.getClass().getName());
BasicDialog basicDialog = super.showWindowWithCustomSize(window, l, dimension);
basicDialog.setMinimumSize(new Dimension(900, 600));
int width = FineUIScale.scale(900);
int height = FineUIScale.scale(600);
BasicDialog basicDialog = super.showWindowWithCustomSize(window, l, new Dimension(width, height));
basicDialog.setMinimumSize(new Dimension(width, height));
basicDialog.setResizable(true);
return basicDialog;
}
@ -1068,15 +1074,15 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
this.initComponents();
}
private void initFunctionTypeList(JPanel functionPane) {
private JPanel initFunctionTypeList() {
functionTypeList = new QuickList(functionTypeListModel);
UIScrollPane functionTypeScrollPane = new UIScrollPane(functionTypeList);
functionTypeScrollPane.setBorder(new UIRoundedBorder(UIConstants.LINE_COLOR, 1, UIConstants.ARC));
functionTypeScrollPane.setPreferredSize(new Dimension(140, 200));
functionPane.add(this.createNamePane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Function_Category") + ":", functionTypeScrollPane), BorderLayout.WEST);
functionTypeScrollPane.setBorder(new FineRoundBorder());
functionTypeList.setBackground(FlatUIUtils.getUIColor("background.normal", Color.WHITE));
initTypeListCellRenderer();
initGroupTypeModel();
initTypeListSelectionListener();
return this.createNamePane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Function_Category"), functionTypeScrollPane);
}
private void initTypeListCellRenderer() {
@ -1183,23 +1189,21 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
});
}
private void initFunctionNameList(JPanel functionPane) {
private JPanel initFunctionNameList() {
functionNameList = new JList(new DefaultListModel());
UIScrollPane functionNameScrollPane = new UIScrollPane(functionNameList);
functionNameScrollPane.setPreferredSize(new Dimension(140, 200));
functionPane.add(
this.createNamePane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Function_Name") + ":", functionNameScrollPane),
BorderLayout.CENTER);
functionNameScrollPane.setBorder(new UIRoundedBorder(UIConstants.LINE_COLOR, 1, UIConstants.ARC));
functionNameScrollPane.setBorder(new FineRoundBorder());
functionNameList.setBackground(FlatUIUtils.getUIColor("background.normal", Color.WHITE));
initFunctionNameListCellRenderer();
initFunctionNameListSelectionListener();
initFunctionNameListMouseListener();
return this.createNamePane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Function_Name"), functionNameScrollPane);
}
private void initDescriptionTextArea() {
// Description
descriptionTextArea = new UITextArea(DESCRIPTION_TEXT_AREA_ROW, DESCRIPTION_TEXT_AREA_COLUMN);
descriptionTextArea.setBackground(Color.white);
descriptionTextArea = new UITextArea();
descriptionTextArea.setBackground(FlatUIUtils.getUIColor("background.normal", Color.WHITE));
descriptionTextArea.setLineWrap(true);
descriptionTextArea.setWrapStyleWord(true);
descriptionTextArea.setEditable(false);
@ -1265,14 +1269,12 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
}
private void initVariablesTree() {
JPanel panel = FRGUIPaneFactory.createBorderLayout_S_Pane();
// vairable.
private JPanel initVariablesTree() {
// variable
variablesTree = new JTree();
UIScrollPane variablesTreePane = new UIScrollPane(variablesTree);
variablesTreePane.setBorder(new UIRoundedBorder(UIConstants.LINE_COLOR, 1, UIConstants.ARC));
panel.add(this.createNamePane(
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaPane_Variables") + ":", variablesTreePane), BorderLayout.WEST);
variablesTreePane.setBorder(new FineRoundBorder());
variablesTree.setBackground(FlatUIUtils.getUIColor("background.normal", Color.WHITE));
variablesTree.setRootVisible(false);
variablesTree.setShowsRootHandles(true);
variablesTree.addMouseListener(applyTextMouseListener);
@ -1282,23 +1284,34 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
UIScrollPane desScrollPane = new UIScrollPane(descriptionTextArea);
desScrollPane.setBorder(null);
panel.add(this.createNamePane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaPane_Formula_Description") + ":", desScrollPane), BorderLayout.CENTER);
initVariablesTreeSelectionListener();
this.add(panel, BorderLayout.CENTER);
return Layouts.row(LayoutConstants.HORIZONTAL_GAP,
cell(this.createNamePane(
Toolkit.i18nText("Fine-Design_Basic_FormulaPane_Variables"), variablesTreePane)
).weight(1),
cell(this.createNamePane(
Toolkit.i18nText("Fine-Design_Basic_FormulaPane_Formula_Description"), desScrollPane)
).weight(1)
).getComponent();
}
private void initComponents() {
this.setLayout(new BorderLayout(4, 4));
initVariablesTree();
initFunctionPane();
}
private void initFunctionPane() {
JPanel functionPane = new JPanel(new BorderLayout(4, 4));
this.add(functionPane, BorderLayout.WEST);
initFunctionTypeList(functionPane);
initFunctionNameList(functionPane);
this.setLayout(new BorderLayout());
JPanel variablesTreePane = initVariablesTree();
JPanel functionPane = initFunctionPane();
this.add(Layouts.row(LayoutConstants.HORIZONTAL_GAP,
cell(functionPane).weight(1),
cell(variablesTreePane).weight(2)
).getComponent());
}
private JPanel initFunctionPane() {
JPanel functionTypePane = initFunctionTypeList();
JPanel functionNamePane = initFunctionNameList();
functionTypeList.setSelectedIndex(0);
return Layouts.row(LayoutConstants.HORIZONTAL_GAP,
cell(functionTypePane).weight(1), cell(functionNamePane).weight(1)
).getComponent();
}
@Override
@ -1314,7 +1327,7 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
public LookDetailAction() {
this.setName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaPane_Function_Detail"));
this.setMnemonic('L');
this.setSmallIcon(BaseUtils.readIcon("/com/fr/design/images/m_file/preview.png"));
this.setSmallIcon(new LazyIcon("preview"));
}
// 弹出的窗口中显示函数的用法明细
@ -1347,7 +1360,7 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
}
private JPanel createNamePane(String name, JComponent comp) {
JPanel namePane = new JPanel(new BorderLayout(4, 4));
JPanel namePane = new JPanel(new BorderLayout(0, 4));
namePane.add(new UILabel(name), BorderLayout.NORTH);
namePane.add(comp, BorderLayout.CENTER);
return namePane;
@ -1421,7 +1434,7 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
DefaultMutableTreeNode bindCellNode = new DefaultMutableTreeNode(new TextUserObject("$$$"));
rootNode.add(bindCellNode);
}
// todo: 缺一些icon
rootNode.add(new TextFolderUserObject(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Data_Fields"),
BaseUtils.readIcon("/com/fr/design/images/dialog/table.png"),
variableResolver.resolveColumnNames()).createMutableTreeNode());
@ -1436,7 +1449,7 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
variableResolver.resolveTableDataParameterVariables()).createMutableTreeNode());
rootNode.add(new TextFolderUserObject(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_ParameterD_Report_Parameter"),
BaseUtils.readIcon("/com/fr/design/images/m_report/p.gif"),
new LazyIcon("param"),
variableResolver.resolveReportParameterVariables()).createMutableTreeNode());
rootNode.add(new TextFolderUserObject(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_M_Server_Global_Parameters"),

4
designer-base/src/main/java/com/fr/design/formula/FormulaPaneWhenReserveFormula.java

@ -40,8 +40,8 @@ public class FormulaPaneWhenReserveFormula extends FormulaPane {
reserveCheckBox4Write = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Write_Save_Formula"));
reserveCheckBox4Write.setSelected(false);
checkBoxPane.add(reserveCheckBox4Result, BorderLayout.WEST);
checkBoxPane.add(reserveCheckBox4Write, BorderLayout.WEST);
checkBoxPane.add(reserveCheckBox4Result);
checkBoxPane.add(reserveCheckBox4Write);
}
@Override

22
designer-base/src/main/java/com/fr/design/formula/TinyFormulaPane.java

@ -1,21 +1,19 @@
package com.fr.design.formula;
import com.fine.theme.icon.LazyIcon;
import com.formdev.flatlaf.util.ScaledEmptyBorder;
import com.fr.base.BaseFormula;
import com.fr.base.BaseUtils;
import com.fr.design.beans.BasicBeanPane;
import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.event.UIObserver;
import com.fr.design.event.UIObserverListener;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.layout.TableLayout;
import com.fr.design.mainframe.DesignerContext;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
@ -40,9 +38,8 @@ public class TinyFormulaPane extends BasicBeanPane<String> implements UIObserver
formulaTextField.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_ExpandD_Sort_After_Expand"));
// 添加一公式编辑器按钮
formulaTextFieldButton = new UIButton(BaseUtils.readIcon("/com/fr/design/images/m_insert/formula.png"));
formulaTextFieldButton = new UIButton(new LazyIcon("formula"));
formulaTextFieldButton.setToolTipText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula") + "...");
formulaTextFieldButton.setPreferredSize(new Dimension(24, 20));
formulaTextFieldButton.setOpaque(false);
formulaTextFieldButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
formulaTextFieldButton.addActionListener(new ActionListener() {
@ -73,12 +70,10 @@ public class TinyFormulaPane extends BasicBeanPane<String> implements UIObserver
}
protected void initLayout() {
double p = TableLayout.PREFERRED;
double f = TableLayout.FILL;
JPanel pane = new JPanel(new BorderLayout(0,0));
JPanel pane1 = new JPanel(new BorderLayout(0,0));
JPanel pane = new JPanel(new BorderLayout());
JPanel pane1 = new JPanel(new BorderLayout());
pane1.add(formulaTextField, BorderLayout.NORTH);
pane1.setBorder(BorderFactory.createEmptyBorder(0,0,0,5));
pane1.setBorder(new ScaledEmptyBorder(0,0,0,5));
pane.add(pane1,BorderLayout.CENTER);
pane.add(formulaTextFieldButton,BorderLayout.EAST);
@ -112,11 +107,6 @@ public class TinyFormulaPane extends BasicBeanPane<String> implements UIObserver
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Present_Formula_Present");
}
@Override
public Dimension getPreferredSize() {
return new Dimension(super.getPreferredSize().width, 20);
}
@Override
public void registerChangeListener(UIObserverListener listener) {
if(formulaTextField != null) {

30
designer-base/src/main/java/com/fr/design/gui/UILookAndFeel.java

@ -7,27 +7,30 @@ import com.fr.design.gui.borders.UITableHeaderBorder;
import com.fr.design.gui.borders.UITableHeaderRolloverBorder;
import com.fr.design.gui.borders.UITextFieldBorder;
import com.fr.design.gui.frpane.UIBasicOptionPaneUI;
import com.fr.design.gui.ibutton.UIBasicButtonUI;
import com.fr.design.gui.frpane.UITabbedPaneUI;
import com.fr.design.gui.ibutton.UIButtonBorder;
import com.fr.design.gui.ibutton.UIButtonUI;
import com.fr.design.gui.ibutton.UIRadioButtonMenuItemUI;
import com.fr.design.gui.ibutton.UIRadioButtonUI;
import com.fr.design.gui.icheckbox.UICheckBoxUI;
import com.fr.design.gui.icombobox.UIBasicComboBoxUI;
import com.fr.design.gui.icombobox.UIComboBoxUI;
import com.fr.design.gui.icontainer.UIScrollPaneBorder;
import com.fr.design.gui.icontainer.UIScrollPaneUI;
import com.fr.design.gui.icontainer.UITableScrollPaneBorder;
import com.fr.design.gui.imenu.UIBasicMenuItemUI;
import com.fr.design.gui.imenu.UIBasicMenuUI;
import com.fr.design.gui.imenu.UIMenuBarUI;
import com.fr.design.gui.imenu.UIMenuItemUI;
import com.fr.design.gui.imenu.UIPopupMenuBorder;
import com.fr.design.gui.imenu.UIPopupMenuSeparatorUI;
import com.fr.design.gui.iprogressbar.UIProgressBarBorder;
import com.fr.design.gui.iprogressbar.UIProgressBarUI;
import com.fr.design.gui.iscrollbar.UIBasicScrollBarUI;
import com.fr.design.gui.iscrollbar.UIScrollBarUI;
import com.fr.design.gui.ispinner.UISpinnerUI;
import com.fr.design.gui.isplitpanedivider.UISplitPaneUI;
import com.fr.design.gui.itable.UIBasicTableUI;
import com.fr.design.gui.itoolbar.UIToolBarBorder;
import com.fr.design.gui.itoolbar.UIToolBarSeparatorUI;
import com.fr.design.gui.itoolbar.UIToolBarUI;
import com.fr.design.gui.itooltip.UIToolTipBorder;
import com.fr.design.gui.itree.UITreeUI;
import com.fr.design.i18n.Toolkit;
@ -89,16 +92,20 @@ public class UILookAndFeel extends MetalLookAndFeel {
"RadioButtonUI", UIRadioButtonUI.class.getName(),
"CheckBoxUI", UICheckBoxUI.class.getName(),
"ToolBarSeparatorUI", UIToolBarSeparatorUI.class.getName(),
"ScrollBarUI", UIBasicScrollBarUI.class.getName(),
"ComboBoxUI", UIBasicComboBoxUI.class.getName(),
"ButtonUI", UIBasicButtonUI.class.getName(),
"ToggleButtonUI", UIBasicButtonUI.class.getName(),
"ScrollBarUI", UIScrollBarUI.class.getName(),
"ComboBoxUI", UIComboBoxUI.class.getName(),
"ButtonUI", UIButtonUI.class.getName(),
"ToggleButtonUI", UIButtonUI.class.getName(),
"TableUI", UIBasicTableUI.class.getName(),
"ProgressBarUI", UIProgressBarUI.class.getName(),
"MenuUI", UIBasicMenuUI.class.getName(),
"MenuItemUI", UIBasicMenuItemUI.class.getName(),
"MenuItemUI", UIMenuItemUI.class.getName(),
"RadioButtonMenuItemUI", UIRadioButtonMenuItemUI.class.getName(),
"OptionPaneUI", UIBasicOptionPaneUI.class.getName(),
"ToolBarUI", UIToolBarUI.class.getName(),
"MenuBarUI", UIMenuBarUI.class.getName(),
// "PopupMenuUI", PopupMenuUI.class.getName(),
"TabbedPaneUI", UITabbedPaneUI.class.getName(),
});
}
@ -219,5 +226,8 @@ public class UILookAndFeel extends MetalLookAndFeel {
return new ImageIcon(url);
}
@Override
public String getName() {
return "FR UI 10";
}
}

43
designer-base/src/main/java/com/fr/design/gui/controlpane/AbstractNameableCreator.java

@ -1,13 +1,12 @@
package com.fr.design.gui.controlpane;
import com.fr.base.BaseUtils;
import com.fr.base.svg.IconUtils;
import com.fr.design.beans.BasicBeanPane;
import com.fr.general.ComparatorUtils;
import com.fr.general.NameObject;
import com.fr.js.JavaScript;
import javax.swing.*;
import javax.swing.Icon;
public abstract class AbstractNameableCreator implements NameableCreator {
@ -24,13 +23,28 @@ public abstract class AbstractNameableCreator implements NameableCreator {
this.clazzOfEditor = clazzOfEditor;
}
/**
* 改用 {@link AbstractNameableCreator#AbstractNameableCreator(String, Icon, Class)}
*/
@Deprecated
public AbstractNameableCreator(String menuName, String iconPath, Class clazz) {
this.menuName = menuName;
this.menuIcon = IconUtils.readIcon(iconPath);
this.clazzOfObject = clazz;
this.clazzOfInitCase = clazz;
}
public AbstractNameableCreator(String menuName, Icon icon, Class clazz) {
this.menuName = menuName;
this.menuIcon = icon;
this.clazzOfObject = clazz;
this.clazzOfInitCase = clazz;
}
/**
* 改用{@link AbstractNameableCreator#AbstractNameableCreator(String, Icon, Class, Class)}
*/
@Deprecated
public AbstractNameableCreator(String menuName, String iconPath, Class clazz, Class<? extends BasicBeanPane> clazzOfEditor) {
this.menuName = menuName;
this.menuIcon = IconUtils.readIcon(iconPath);
@ -38,7 +52,19 @@ public abstract class AbstractNameableCreator implements NameableCreator {
this.clazzOfEditor = clazzOfEditor;
this.clazzOfInitCase = clazz;
}
public AbstractNameableCreator(String menuName, Icon icon, Class clazz, Class<? extends BasicBeanPane> clazzOfEditor) {
this.menuName = menuName;
this.menuIcon = icon;
this.clazzOfObject = clazz;
this.clazzOfEditor = clazzOfEditor;
this.clazzOfInitCase = clazz;
}
/**
* 改用{@link AbstractNameableCreator#AbstractNameableCreator(String, Icon, Class, Class, Class)}
*/
@Deprecated
public AbstractNameableCreator(String menuName, String iconPath, Class clazz, Class clazz4Init, Class<? extends BasicBeanPane> clazzOfEditor) {
this.menuName = menuName;
this.menuIcon = IconUtils.readIcon(iconPath);
@ -48,6 +74,15 @@ public abstract class AbstractNameableCreator implements NameableCreator {
this.clazzOfInitCase = clazz4Init;
}
public AbstractNameableCreator(String menuName, Icon icon, Class clazz, Class clazz4Init, Class<? extends BasicBeanPane> clazzOfEditor) {
this.menuName = menuName;
this.menuIcon = icon;
this.clazzOfObject = clazz;
this.clazzOfEditor = clazzOfEditor;
this.clazzOfInitCase = clazz;
this.clazzOfInitCase = clazz4Init;
}
/**
* get menuName
* @return

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save