Browse Source

Pull request #6205: 无jira任务, feature/x 合 release/11.0 解决冲突

Merge in DESIGN/design from ~HENRY.WANG/design:release/11.0 to release/11.0

* commit '39214973b972665bdabe206ab35b3c65e9f74700': (185 commits)
  REPORT-59545 设计器很多报错提示弹窗的交互有问题
  REPORT-60392
  REPORT-60625【固定布局-原布局推荐4.1】决策报表-自适应布局-右侧显示组件库面板时,选中组件无法按delete键删除,显示设置页面时可以delete删除组件
  REPORT-60392 【固定布局-原布局推荐4.1】决策报表-自适应布局-新建空白模板/带布局模板,右侧组件目录树处,body名字变空了
  REPORT-60489 主题面板引导长按滑动时候会有异常
  REPORT-60477 完成弹窗的按钮有重影,使用UIButton实现
  REPORT-60492 && REPORT-60480 解决window上不显示和错位问题
  REPORT-60693 开启引导的时候设计器窗口最大化
  REPORT-60561 全局自适应-样式细节优化
  REPORT-60644 单元格样式设置调整,ui显示有问题
  REPORT-60434 【主题获取】在线组件右键,鼠标移动点击详情时,偶现详细消失
  REPORT-60485 解决引导页中模板保存点取消也显示完成弹窗
  解决冲突
  CHART-20675 主题样式图表预览图调整
  REPORT-59902 主题切换交互框架优化
  REPORT-59089 【主题切换】主题比较多有滚动条,右侧主题的勾选图标有点显示不全
  REPORT-60484 解决切换工作目录会多次注册问题
  REPORT-60513 功能入口提示增加遮罩
  REPORT-60516 10.0release设计器打开cpt很慢
  REPORT-60637 国际化
  ...
bugfix/11.0
Henry.Wang 3 years ago
parent
commit
f918a213bc
  1. 11
      designer-base/src/main/java/com/fr/design/actions/UpdateAction.java
  2. 31
      designer-base/src/main/java/com/fr/design/actions/server/GlobalTableDataAction.java
  3. 11
      designer-base/src/main/java/com/fr/design/beans/ErrorMsgTextFieldAdapter.java
  4. 46
      designer-base/src/main/java/com/fr/design/beans/UITextFieldAdapter.java
  5. 19
      designer-base/src/main/java/com/fr/design/border/UITitledBorder.java
  6. 32
      designer-base/src/main/java/com/fr/design/border/UITitledMatteBorder.java
  7. 32
      designer-base/src/main/java/com/fr/design/cell/CellStylePreviewPane.java
  8. 28
      designer-base/src/main/java/com/fr/design/data/datapane/TableDataPaneListPane.java
  9. 50
      designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionComboBoxPanel.java
  10. 48
      designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListDialogActionAdapter.java
  11. 66
      designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java
  12. 6
      designer-base/src/main/java/com/fr/design/dialog/UIDialog.java
  13. 3
      designer-base/src/main/java/com/fr/design/file/MutilTempalteTabPane.java
  14. 2
      designer-base/src/main/java/com/fr/design/formula/FormulaPane.java
  15. 11
      designer-base/src/main/java/com/fr/design/fun/RegPaneProvider.java
  16. 11
      designer-base/src/main/java/com/fr/design/fun/TextFieldAdapterProvider.java
  17. 22
      designer-base/src/main/java/com/fr/design/fun/impl/AbstractRegPaneProvider.java
  18. 22
      designer-base/src/main/java/com/fr/design/fun/impl/AbstractTextFieldAdapterProvider.java
  19. 3
      designer-base/src/main/java/com/fr/design/gui/chart/ChartEditPaneProvider.java
  20. 60
      designer-base/src/main/java/com/fr/design/gui/frpane/RegFieldPane.java
  21. 6
      designer-base/src/main/java/com/fr/design/gui/ispinner/UISpinner.java
  22. 85
      designer-base/src/main/java/com/fr/design/gui/style/AlignmentPane.java
  23. 86
      designer-base/src/main/java/com/fr/design/gui/style/TextFontTippedPane.java
  24. 483
      designer-base/src/main/java/com/fr/design/gui/style/TextFormatPane.java
  25. 24
      designer-base/src/main/java/com/fr/design/gui/style/TranslucentBorderSpecialPane.java
  26. 871
      designer-base/src/main/java/com/fr/design/javascript/ExportJavaScriptPane.java
  27. 9
      designer-base/src/main/java/com/fr/design/login/service/DesignerPassportManager.java
  28. 5
      designer-base/src/main/java/com/fr/design/mainframe/DesktopCardPane.java
  29. 1
      designer-base/src/main/java/com/fr/design/mainframe/EastRegionContainerPane.java
  30. 88
      designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java
  31. 1
      designer-base/src/main/java/com/fr/design/mainframe/NorthRegionContainerPane.java
  32. 10
      designer-base/src/main/java/com/fr/design/mainframe/OpenFailedPane.java
  33. 189
      designer-base/src/main/java/com/fr/design/mainframe/guide/base/Guide.java
  34. 51
      designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideBuilder.java
  35. 55
      designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideGroup.java
  36. 32
      designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideLifecycle.java
  37. 28
      designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideLifecycleAdaptor.java
  38. 113
      designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideManager.java
  39. 29
      designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideVersion.java
  40. 129
      designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideView.java
  41. 155
      designer-base/src/main/java/com/fr/design/mainframe/guide/collect/GuideCollector.java
  42. 480
      designer-base/src/main/java/com/fr/design/mainframe/guide/scene/AbstractGuideScene.java
  43. 123
      designer-base/src/main/java/com/fr/design/mainframe/guide/scene/ClickScene.java
  44. 37
      designer-base/src/main/java/com/fr/design/mainframe/guide/scene/DisplayScene.java
  45. 64
      designer-base/src/main/java/com/fr/design/mainframe/guide/scene/DragScene.java
  46. 18
      designer-base/src/main/java/com/fr/design/mainframe/guide/scene/GuideScene.java
  47. 21
      designer-base/src/main/java/com/fr/design/mainframe/guide/scene/GuideSceneLifecycle.java
  48. 18
      designer-base/src/main/java/com/fr/design/mainframe/guide/scene/GuideSceneLifecycleAdaptor.java
  49. 5
      designer-base/src/main/java/com/fr/design/mainframe/guide/scene/SceneFilter.java
  50. 60
      designer-base/src/main/java/com/fr/design/mainframe/guide/scene/drag/DragAndDropDragGestureListener.java
  51. 97
      designer-base/src/main/java/com/fr/design/mainframe/guide/tip/BubbleTip.java
  52. 14
      designer-base/src/main/java/com/fr/design/mainframe/guide/tip/GuideTip.java
  53. 74
      designer-base/src/main/java/com/fr/design/mainframe/guide/ui/BubbleHint.java
  54. 78
      designer-base/src/main/java/com/fr/design/mainframe/guide/ui/ExpandPane.java
  55. 134
      designer-base/src/main/java/com/fr/design/mainframe/guide/ui/GuideCompleteDialog.java
  56. 53
      designer-base/src/main/java/com/fr/design/mainframe/guide/ui/GuideLoadingGlassPane.java
  57. 233
      designer-base/src/main/java/com/fr/design/mainframe/guide/ui/GuideManageDialog.java
  58. 28
      designer-base/src/main/java/com/fr/design/mainframe/guide/ui/ImagePanel.java
  59. 152
      designer-base/src/main/java/com/fr/design/mainframe/guide/ui/bubble/Bubble.java
  60. 267
      designer-base/src/main/java/com/fr/design/mainframe/guide/ui/bubble/BubbleWithClose.java
  61. 98
      designer-base/src/main/java/com/fr/design/mainframe/guide/utils/ScreenImage.java
  62. 76
      designer-base/src/main/java/com/fr/design/mainframe/theme/FormThemeProfilePane.java
  63. 45
      designer-base/src/main/java/com/fr/design/mainframe/theme/ReportThemeProfilePane.java
  64. 1
      designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeBlock.java
  65. 297
      designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeEditorPane.java
  66. 30
      designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeGridControlPane.java
  67. 341
      designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeGridPagesPane.java
  68. 18
      designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeGridPane.java
  69. 8
      designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemePreviewPane.java
  70. 518
      designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeProfilePane.java
  71. 64
      designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeDialog.java
  72. 58
      designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeGridPagesDialog.java
  73. 107
      designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeManageDialog.java
  74. 25
      designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeProfileDialog.java
  75. 106
      designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeUsingDialog.java
  76. 30
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ComponentStyleEditPane.java
  77. 4
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/cell/CellStyleEditPane.java
  78. 4
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/cell/NoBorderPaneCellStyleEditPane.java
  79. 19
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/LabelUtils.java
  80. 1
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/TabbedPane.java
  81. 27
      designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ComponentPreviewPane.java
  82. 13
      designer-base/src/main/java/com/fr/design/mainframe/theme/preview/FormThemePreviewPane.java
  83. 67
      designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ecpreview/ECPreviewPane.java
  84. 50
      designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ecpreview/ECReportPreviewPane.java
  85. 100
      designer-base/src/main/java/com/fr/design/mainframe/theme/ui/AutoCheckTextField.java
  86. 26
      designer-base/src/main/java/com/fr/design/mainframe/theme/ui/AutoCheckThemeNameTextField.java
  87. 114
      designer-base/src/main/java/com/fr/design/mainframe/theme/ui/BreadcrumbBar.java
  88. 8
      designer-base/src/main/java/com/fr/design/mainframe/toolbar/ToolBarMenuDock.java
  89. 61
      designer-base/src/main/java/com/fr/design/os/impl/DatabaseDialogAction.java
  90. 2
      designer-base/src/main/java/com/fr/design/report/fit/menupane/ReportFitAttrAction.java
  91. 9
      designer-base/src/main/java/com/fr/design/report/fit/menupane/TemplateFitAttrPane.java
  92. 22
      designer-base/src/main/java/com/fr/design/style/color/NewColorSelectPane.java
  93. 5
      designer-base/src/main/java/com/fr/design/ui/ModernUIPane.java
  94. 60
      designer-base/src/main/java/com/fr/design/utils/ComponentUtils.java
  95. 25
      designer-base/src/main/java/com/fr/design/worker/open/OpenWorker.java
  96. 8
      designer-base/src/main/java/com/fr/design/write/submit/CustomJobPane.java
  97. 2
      designer-base/src/main/java/com/fr/env/ErrorDialog.java
  98. 3
      designer-base/src/main/java/com/fr/env/SyncFailedPluginsDialog.java
  99. 22
      designer-base/src/main/java/com/fr/file/FILEChooserPane.java
  100. 2
      designer-base/src/main/java/com/fr/nx/app/designer/toolbar/TransformResultInfo.java
  101. Some files were not shown because too many files have changed in this diff Show More

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

@ -345,6 +345,17 @@ public abstract class UpdateAction extends ShortCut implements Action {
return (JComponent) object;
}
public JComponent createToolBarComponentByName(String componentName) {
Object object = this.getValue(componentName);
if (!(object instanceof AbstractButton)) {
UIButton button = null;
button = new UIButton();
object = initButton(button, componentName);
}
return (JComponent) object;
}
protected JComponent initButton(UIButton button, String name) {
// 添加一个名字作为自动化测试用
button.setName(getName());

31
designer-base/src/main/java/com/fr/design/actions/server/GlobalTableDataAction.java

@ -25,9 +25,6 @@ import com.fr.esd.event.DsNameTarget;
import com.fr.esd.event.StrategyEventsNotifier;
import com.fr.file.TableDataConfig;
import com.fr.transaction.CallBackAdaptor;
import com.fr.transaction.Configurations;
import com.fr.transaction.WorkerFacade;
import com.fr.report.LockItem;
import javax.swing.KeyStroke;
@ -106,33 +103,17 @@ public class GlobalTableDataAction extends UpdateAction implements ResponseDataS
globalTableDataDialog.setDoOKSucceed(false);
return;
}
globalTableDataPane.update(tableDataConfig);
DesignTableDataManager.clearGlobalDs();
// 保存时 移除服务器数据集列名缓存
for (String name : tableDataConfig.getTableDatas().keySet()) {
DesignTableDataManager.removeSelectedColumnNames(name);
}
Configurations.modify(new WorkerFacade(TableDataConfig.class) {
@Override
public void run() {
globalTableDataPane.update(tableDataConfig);
}
}.addCallBack(new CallBackAdaptor() {
@Override
public boolean beforeCommit() {
//如果更新失败,则不关闭对话框,也不写xml文件,并且将对话框定位在请重命名的那个对象页面
return doWithDatasourceManager(tableDataConfig, globalTableDataPane, globalTableDataDialog);
}
@Override
public void afterCommit() {
// 刷新共有数据集
TableDataTreePane.getInstance(DesignModelAdapter.getCurrentModelAdapter());
fireDSChanged(globalTableDataPane.getDsChangedNameMap());
// 关闭服务器数据集页面,为其解锁
EditLockUtils.unlock(LockItem.SERVER_TABLE_DATA);
}
}));
// 刷新共有数据集
TableDataTreePane.getInstance(DesignModelAdapter.getCurrentModelAdapter());
fireDSChanged(globalTableDataPane.getDsChangedNameMap());
// 关闭服务器数据集页面,为其解锁
EditLockUtils.unlock(LockItem.SERVER_TABLE_DATA);
}
@Override

11
designer-base/src/main/java/com/fr/design/beans/ErrorMsgTextFieldAdapter.java

@ -0,0 +1,11 @@
package com.fr.design.beans;
import javax.swing.JComponent;
public interface ErrorMsgTextFieldAdapter {
void setText(String str);
String getText();
JComponent getErrorMsgTextField();
}

46
designer-base/src/main/java/com/fr/design/beans/UITextFieldAdapter.java

@ -0,0 +1,46 @@
package com.fr.design.beans;
import com.fr.design.gui.itextfield.UITextField;
import javax.swing.JComponent;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
public class UITextFieldAdapter implements ErrorMsgTextFieldAdapter {
private final UITextField uiTextField = new UITextField();
public UITextFieldAdapter(){
addDocumentListener();
}
@Override
public void setText(String str) {
uiTextField.setText(str);
}
@Override
public String getText() {
return uiTextField.getText();
}
public void addDocumentListener() {
uiTextField.getDocument().addDocumentListener(new DocumentListener() {
public void changedUpdate(DocumentEvent e) {
uiTextField.setToolTipText(uiTextField.getText());
}
public void insertUpdate(DocumentEvent e) {
uiTextField.setToolTipText(uiTextField.getText());
}
public void removeUpdate(DocumentEvent e) {
uiTextField.setToolTipText(uiTextField.getText());
}
});
}
@Override
public JComponent getErrorMsgTextField() {
return uiTextField;
}
}

19
designer-base/src/main/java/com/fr/design/border/UITitledBorder.java

@ -22,24 +22,7 @@ public class UITitledBorder extends TitledBorder {
}
private UITitledBorder(String title) {
super(
BorderFactory.createCompoundBorder(
BorderFactory.createEmptyBorder(
0,
0,
5,
0),
new UIRoundedBorder(
UIConstants.TITLED_BORDER_COLOR,
1,
10)
),
title,
TitledBorder.LEADING,
TitledBorder.TOP,
null,
new Color(1, 159, 222)
);
this(title, 10);
}
/**

32
designer-base/src/main/java/com/fr/design/border/UITitledMatteBorder.java

@ -0,0 +1,32 @@
package com.fr.design.border;
import com.fr.design.constants.UIConstants;
import javax.swing.BorderFactory;
import javax.swing.border.TitledBorder;
import java.awt.Color;
public class UITitledMatteBorder extends TitledBorder {
public static UITitledMatteBorder createTitledTopBorder(String title, Color color) {
return new UITitledMatteBorder(title, 1, 0, 0, 0, color);
}
public static UITitledMatteBorder createTitledBorder(String title, Color color) {
return new UITitledMatteBorder(title, 1, 1, 1, 1, color);
}
public static UITitledMatteBorder createTitledBorder(String title, int top, int left, int bottom, int right, Color color) {
return new UITitledMatteBorder(title, top, left, bottom, right, color);
}
private UITitledMatteBorder(String title, int top, int left, int bottom, int right, Color color) {
super(
BorderFactory.createMatteBorder(top, left, bottom, right, UIConstants.TITLED_BORDER_COLOR),
title,
TitledBorder.LEADING,
TitledBorder.TOP,
null,
color
);
}
}

32
designer-base/src/main/java/com/fr/design/cell/CellStylePreviewPane.java

@ -6,6 +6,9 @@ import com.fr.base.Style;
import com.fr.general.IOUtils;
import javax.swing.JPanel;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
@ -40,10 +43,22 @@ public class CellStylePreviewPane extends JPanel {
@Override
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
int resolution = ScreenResolution.getScreenResolution();
g.clearRect(0, 0, getWidth(), getHeight());
int width = getWidth();
int height = getHeight();
paintTransparentBackground(g2d, style);
paintCellStyle(g2d, style);
}
private void paintTransparentBackground(Graphics2D g2d, Style style) {
Color fontColor = style.getFRFont().getForeground();
float g = fontColor.getRed() * 0.299F + fontColor.getGreen() * 0.587F * fontColor.getBlue() * 0.114F;
float alpha = 1.0F;
if (g < 50) {
alpha = 0.2F;
} else if (g < 160){
alpha = 0.5F;
}
float scaleWidth = 1.0F * getWidth() / transparentBackgroundWidth;
float scaleHeight = 1.0F * getHeight() / transparentBackgroundHeight;
@ -54,7 +69,18 @@ public class CellStylePreviewPane extends JPanel {
} else {
scaleHeight = scaleWidth = maxScale;
}
Composite oldComposite = g2d.getComposite();
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
g2d.drawImage(transparentBackgroundImage, 0, 0, (int) (transparentBackgroundWidth * scaleWidth), (int) (transparentBackgroundHeight * scaleHeight), null);
g2d.setComposite(oldComposite);
}
private void paintCellStyle(Graphics2D g2d, Style style) {
int resolution = ScreenResolution.getScreenResolution();
int width = getWidth();
int height = getHeight();
if (style == Style.DEFAULT_STYLE) {
// 如果是默认的style,就只写"Report"上去

28
designer-base/src/main/java/com/fr/design/data/datapane/TableDataPaneListPane.java

@ -1,6 +1,8 @@
package com.fr.design.data.datapane;
import com.fr.base.TableData;
import com.fr.base.TableDataBean;
import com.fr.config.RemoteConfigEvent;
import com.fr.data.TableDataSource;
import com.fr.data.api.StoreProcedureAssist;
import com.fr.data.impl.storeproc.StoreProcedure;
@ -12,22 +14,26 @@ import com.fr.design.gui.controlpane.JListControlPane;
import com.fr.design.gui.controlpane.NameableCreator;
import com.fr.design.gui.ilist.ListModelElement;
import com.fr.design.i18n.Toolkit;
import com.fr.event.EventDispatcher;
import com.fr.file.ProcedureConfig;
import com.fr.file.TableDataConfig;
import com.fr.file.TableDataOperator;
import com.fr.general.ComparatorUtils;
import com.fr.general.NameObject;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.ArrayUtils;
import com.fr.stable.Nameable;
import com.fr.stable.StringUtils;
import com.fr.stable.core.PropertyChangeAdapter;
import com.fr.third.org.apache.commons.collections4.MapUtils;
import com.fr.workspace.WorkContext;
import javax.swing.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -231,15 +237,25 @@ public class TableDataPaneListPane extends JListControlPane implements TableData
@Override
public void update(TableDataConfig tableDataConfig) {
tableDataConfig.removeAllTableData();
ProcedureConfig.getInstance().removeAllProcedure();
Nameable[] tableDataArray = this.update();
Map<String, TableData> tableDataMap = new LinkedHashMap<String, TableData>();
List<TableDataBean> tableDataBeans = new ArrayList<>();
Map<String, String> map = MapUtils.invertMap(getDsNameChangedMap());
for (int i = 0; i < tableDataArray.length; i++) {
NameObject nameObject = (NameObject) tableDataArray[i];
tableDataMap.put(nameObject.getName(), (TableData) nameObject.getObject());
String oldName = map.get(nameObject.getName());
if (oldName == null) {
oldName = StringUtils.EMPTY;
}
tableDataBeans.add(new TableDataBean(nameObject.getName(), oldName, (TableData) nameObject.getObject()));
}
try {
WorkContext.getCurrent().get(TableDataOperator.class).saveTableData(tableDataBeans);
if (!WorkContext.getCurrent().isLocal()) {
EventDispatcher.fire(RemoteConfigEvent.EDIT, TableDataConfig.class.getSimpleName());
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
tableDataConfig.setTableDatas(tableDataMap);
}
@Override

50
designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionComboBoxPanel.java

@ -5,20 +5,13 @@ import com.fr.data.impl.AbstractDatabaseConnection;
import com.fr.data.impl.Connection;
import com.fr.data.impl.NameDatabaseConnection;
import com.fr.design.DesignerEnvManager;
import com.fr.design.actions.server.ConnectionListAction;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.editlock.ConnectionLockChangeChecker;
import com.fr.design.editlock.EditLockUtils;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ibutton.UILockButton;
import com.fr.design.mainframe.DesignerContext;
import com.fr.file.ConnectionConfig;
import com.fr.general.ComparatorUtils;
import com.fr.stable.StringUtils;
import com.fr.transaction.CallBackAdaptor;
import com.fr.transaction.Configurations;
import com.fr.transaction.WorkerFacade;
import com.fr.workspace.WorkContext;
import com.fr.workspace.server.connection.DBConnectAuth;
import com.fr.report.LockItem;
@ -133,48 +126,7 @@ public class ConnectionComboBoxPanel extends ItemEditableComboBoxPanel {
return;
}
// 锁定成功,执行后续操作
final ConnectionListPane connectionListPane = new ConnectionListPane();
final ConnectionConfig connectionConfig = ConnectionConfig.getInstance();
ConnectionConfig cloned = connectionConfig.mirror();
connectionListPane.populate(cloned);
final BasicDialog connectionListDialog = connectionListPane.showLargeWindow(
SwingUtilities.getWindowAncestor(ConnectionComboBoxPanel.this), null);
connectionListDialog.addDialogActionListener(new DialogActionAdapter() {
public void doOk() {
if (!connectionListPane.isNamePermitted()) {
connectionListDialog.setDoOKSucceed(false);
return;
}
Configurations.modify(new WorkerFacade(ConnectionConfig.class) {
@Override
public void run() {
connectionListPane.update(connectionConfig);
}
}.addCallBack(new CallBackAdaptor() {
@Override
public boolean beforeCommit() {
//如果更新失败,则不关闭对话框,也不写xml文件,并且将对话框定位在请重命名的那个对象页面
return ConnectionListAction.doWithDatasourceManager(connectionConfig, connectionListPane, connectionListDialog);
}
@Override
public void afterCommit() {
DesignerContext.getDesignerBean("databasename").refreshBeanElement();
// 关闭定义数据连接页面,为其解锁
EditLockUtils.unlock(LockItem.CONNECTION);
}
}));
}
@Override
public void doCancel() {
// 关闭定义数据连接页面,为其解锁
super.doCancel();
EditLockUtils.unlock(LockItem.CONNECTION);
}
});
connectionListDialog.setVisible(true);
ConnectionListPane.showDialog(SwingUtilities.getWindowAncestor(ConnectionComboBoxPanel.this));
refreshItems();
}

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

@ -0,0 +1,48 @@
package com.fr.design.data.datapane.connect;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.editlock.EditLockUtils;
import com.fr.design.mainframe.DesignerContext;
import com.fr.file.ConnectionConfig;
import com.fr.report.LockItem;
/**
* @author hades
* @version 11.0
* Created by hades on 2021/9/8
*/
public class ConnectionListDialogActionAdapter extends DialogActionAdapter {
private final ConnectionManagerPane connectionManagerPane;
private final BasicDialog connectionListDialog;
private final ConnectionConfig connectionConfig;
public ConnectionListDialogActionAdapter(ConnectionManagerPane connectionManagerPane,
BasicDialog connectionListDialog,
ConnectionConfig connectionConfig) {
this.connectionManagerPane = connectionManagerPane;
this.connectionListDialog = connectionListDialog;
this.connectionConfig = connectionConfig;
}
@Override
public void doOk() {
if (!connectionManagerPane.isNamePermitted()) {
connectionListDialog.setDoOKSucceed(false);
return;
}
connectionManagerPane.update(connectionConfig);
DesignerContext.getDesignerBean("databasename").refreshBeanElement();
// 关闭定义数据连接页面,为其解锁
EditLockUtils.unlock(LockItem.CONNECTION);
}
@Override
public void doCancel() {
// 关闭定义数据连接页面,为其解锁
super.doCancel();
EditLockUtils.unlock(LockItem.CONNECTION);
}
}

66
designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java

@ -1,23 +1,32 @@
package com.fr.design.data.datapane.connect;
import com.fr.config.RemoteConfigEvent;
import com.fr.data.impl.Connection;
import com.fr.data.impl.ConnectionBean;
import com.fr.data.impl.JDBCDatabaseConnection;
import com.fr.data.impl.JNDIDatabaseConnection;
import com.fr.design.ExtraDesignClassManager;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.fun.ConnectionProvider;
import com.fr.design.gui.controlpane.JListControlPane;
import com.fr.design.gui.controlpane.NameObjectCreator;
import com.fr.design.gui.controlpane.NameableCreator;
import com.fr.design.i18n.Toolkit;
import com.fr.event.EventDispatcher;
import com.fr.file.ConnectionConfig;
import com.fr.general.ComparatorUtils;
import com.fr.general.NameObject;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.ArrayUtils;
import com.fr.stable.Nameable;
import com.fr.stable.StringUtils;
import com.fr.stable.core.PropertyChangeAdapter;
import com.fr.third.org.apache.commons.collections4.MapUtils;
import com.fr.workspace.WorkContext;
import com.fr.file.ConnectionOperator;
import java.awt.Window;
import javax.swing.*;
import java.util.ArrayList;
import java.util.Arrays;
@ -67,8 +76,19 @@ public class ConnectionListPane extends JListControlPane implements ConnectionSh
protected void rename(String oldName, String newName) {
renameMap.remove(selectedName);
renameMap.put(selectedName, newName);
//如果a改成了b,b又被改成了c,就认为是a改成了c
for (Map.Entry<String, String> entry : renameMap.entrySet()) {
if (StringUtils.equals(oldName, entry.getValue())) {
oldName = entry.getKey();
break;
}
}
if (StringUtils.equals(oldName, newName)) {
//a -> b;b -> a,说明没改
renameMap.remove(oldName);
} else {
renameMap.put(oldName, newName);
}
}
/**
@ -149,14 +169,42 @@ public class ConnectionListPane extends JListControlPane implements ConnectionSh
public void update(ConnectionConfig connectionConfig) {
// Nameable[]居然不能强转成NameObject[],一定要这么写...
Nameable[] res = this.update();
NameObject[] res_array = new NameObject[res.length];
java.util.Arrays.asList(res).toArray(res_array);
List<ConnectionBean> connectionBeans = new ArrayList<>();
Map<String, String> map = MapUtils.invertMap(getRenameMap());
for (int i = 0; i < res.length; i++) {
NameObject nameObject = (NameObject) res[i];
String oldName = map.get(nameObject.getName());
if (oldName == null) {
oldName = StringUtils.EMPTY;
}
connectionBeans.add(new ConnectionBean(nameObject.getName(), oldName, (Connection) nameObject.getObject()));
}
try {
WorkContext.getCurrent().get(ConnectionOperator.class).saveConnection(connectionBeans);
if (!WorkContext.getCurrent().isLocal()) {
EventDispatcher.fire(RemoteConfigEvent.EDIT, ConnectionConfig.class.getSimpleName());
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
connectionConfig.removeAllConnection();
public static void showDialog(Window parent) {
final ConnectionConfig connectionConfig = ConnectionConfig.getInstance();
final ConnectionManagerPane connectionManagerPane = new ConnectionManagerPane() {
@Override
public void complete() {
ConnectionConfig cloned = connectionConfig.mirror();
populate(cloned);
}
for (int i = 0; i < res_array.length; i++) {
NameObject nameObject = res_array[i];
connectionConfig.addConnection(nameObject.getName(), (Connection) nameObject.getObject());
}
@Override
protected void renameConnection(String oldName, String newName) {
connectionConfig.renameConnection(oldName, newName);
}
};
final BasicDialog connectionListDialog = connectionManagerPane.showLargeWindow(parent, null);
connectionListDialog.addDialogActionListener(new ConnectionListDialogActionAdapter(connectionManagerPane, connectionListDialog, connectionConfig));
connectionListDialog.setVisible(true);
}
}

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

@ -175,7 +175,11 @@ public abstract class UIDialog extends JDialog {
try {
checkValid();
} catch (Exception exp) {
FineJOptionPane.showMessageDialog(this, exp.getMessage());
FineJOptionPane.showMessageDialog(
this,
exp.getMessage(),
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"),
JOptionPane.WARNING_MESSAGE);
return;
}

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

@ -4,6 +4,7 @@ package com.fr.design.file;
import com.fr.base.BaseUtils;
import com.fr.base.GraphHelper;
import com.fr.base.vcs.DesignerMode;
import com.fr.design.base.mode.DesignModeContext;
import com.fr.design.constants.UIConstants;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.gui.imenu.UIMenuItem;
@ -763,7 +764,7 @@ public class MutilTempalteTabPane extends JComponent {
/**
* 关闭掉一个模板之后激活新的待显示模板
*/
private void activePrevTemplateAfterClose() {
public void activePrevTemplateAfterClose() {
if (openedTemplate.isEmpty()) {
//新建并激活模板
DesignerContext.getDesignerFrame().addAndActivateJTemplate();

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

@ -655,7 +655,7 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
FormulaPane.this,
formulaValidMessage + ".",
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"),
JOptionPane.INFORMATION_MESSAGE);
JOptionPane.WARNING_MESSAGE);
}
};

11
designer-base/src/main/java/com/fr/design/fun/RegPaneProvider.java

@ -0,0 +1,11 @@
package com.fr.design.fun;
import com.fr.design.gui.frpane.RegFieldPane;
import com.fr.stable.fun.mark.Immutable;
public interface RegPaneProvider extends Immutable {
int CURRENT_LEVEL = 1;
String XML_TAG = "RegPaneProvider";
RegFieldPane createRegPane();
}

11
designer-base/src/main/java/com/fr/design/fun/TextFieldAdapterProvider.java

@ -0,0 +1,11 @@
package com.fr.design.fun;
import com.fr.design.beans.ErrorMsgTextFieldAdapter;
import com.fr.stable.fun.mark.Immutable;
public interface TextFieldAdapterProvider extends Immutable {
String XML_TAG = "ErrorMesPaneWrapperProvider";
int CURRENT_LEVEL = 1;
ErrorMsgTextFieldAdapter createTextFieldAdapter();
}

22
designer-base/src/main/java/com/fr/design/fun/impl/AbstractRegPaneProvider.java

@ -0,0 +1,22 @@
package com.fr.design.fun.impl;
import com.fr.design.fun.RegPaneProvider;
import com.fr.stable.fun.mark.API;
/**
* @author Joe
* 2021/10/8 15:19
*/
@API(level = RegPaneProvider.CURRENT_LEVEL)
public abstract class AbstractRegPaneProvider implements RegPaneProvider {
@Override
public int currentAPILevel() {
return CURRENT_LEVEL;
}
@Override
public int layerIndex() {
return DEFAULT_LAYER_INDEX;
}
}

22
designer-base/src/main/java/com/fr/design/fun/impl/AbstractTextFieldAdapterProvider.java

@ -0,0 +1,22 @@
package com.fr.design.fun.impl;
import com.fr.design.fun.TextFieldAdapterProvider;
import com.fr.stable.fun.mark.API;
/**
* @author Joe
* 2021/10/8 15:17
*/
@API(level = TextFieldAdapterProvider.CURRENT_LEVEL)
public abstract class AbstractTextFieldAdapterProvider implements TextFieldAdapterProvider {
@Override
public int currentAPILevel() {
return CURRENT_LEVEL;
}
@Override
public int layerIndex() {
return DEFAULT_LAYER_INDEX;
}
}

3
designer-base/src/main/java/com/fr/design/gui/chart/ChartEditPaneProvider.java

@ -16,4 +16,7 @@ public interface ChartEditPaneProvider {
default void removeChartEditPaneActionListener(ChartEditPaneActionListener l) {
}
default void resetLastChartCollection() {
}
}

60
designer-base/src/main/java/com/fr/design/gui/frpane/RegFieldPane.java

@ -1,21 +1,25 @@
package com.fr.design.gui.frpane;
import com.fr.design.ExtraDesignClassManager;
import com.fr.design.beans.ErrorMsgTextFieldAdapter;
import com.fr.design.beans.UITextFieldAdapter;
import com.fr.design.constants.LayoutConstants;
import com.fr.design.designer.IntervalConstants;
import com.fr.design.dialog.BasicPane;
import com.fr.design.fun.TextFieldAdapterProvider;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.form.ui.TextEditor;
import com.fr.form.ui.reg.NoneReg;
import com.fr.form.ui.reg.RegExp;
import com.fr.log.FineLoggerFactory;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.awt.*;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
/**
* Created by kerry on 2017/9/4.
@ -23,7 +27,7 @@ import java.awt.*;
public class RegFieldPane extends RegPane {
protected RegErrorMsgPane regErrorMsgPane;
public RegFieldPane(){
public RegFieldPane() {
this(ALL_REG_TYPE);
}
@ -39,8 +43,8 @@ public class RegFieldPane extends RegPane {
@Override
public void regChangeAction() {
RegExp regExp = (RegExp)getRegComboBox().getSelectedItem();
if(regExp instanceof NoneReg){
RegExp regExp = (RegExp) getRegComboBox().getSelectedItem();
if (regExp instanceof NoneReg) {
regErrorMsgPane.setVisible(false);
return;
}
@ -67,33 +71,35 @@ public class RegFieldPane extends RegPane {
}
private static class RegErrorMsgPane extends BasicPane {
private UITextField regErrorMsgField;
private ErrorMsgTextFieldAdapter errorMsgTextFieldAdapter;
public RegErrorMsgPane() {
initRegErrorMsgField();
setStyle();
}
private void setStyle() {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
this.setBorder(BorderFactory.createEmptyBorder(IntervalConstants.INTERVAL_L6, IntervalConstants.INTERVAL_L5, 0, 0));
initRegErrorMsgField();
UILabel tipLabel = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Widget_Error_Tip"));
tipLabel.setPreferredSize(new Dimension(60, 20));
JPanel panel = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{new Component[]{tipLabel, regErrorMsgField}}, TableLayoutHelper.FILL_LASTCOLUMN, 10, LayoutConstants.VGAP_MEDIUM);
JPanel panel = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{new Component[]{tipLabel, errorMsgTextFieldAdapter.getErrorMsgTextField()}}, TableLayoutHelper.FILL_LASTCOLUMN, 10, LayoutConstants.VGAP_MEDIUM);
this.add(panel);
}
private void initRegErrorMsgField() {
regErrorMsgField = new UITextField();
regErrorMsgField.getDocument().addDocumentListener(new DocumentListener() {
public void changedUpdate(DocumentEvent e) {
regErrorMsgField.setToolTipText(regErrorMsgField.getText());
}
public void insertUpdate(DocumentEvent e) {
regErrorMsgField.setToolTipText(regErrorMsgField.getText());
}
TextFieldAdapterProvider provider = ExtraDesignClassManager.getInstance().getSingle(TextFieldAdapterProvider.XML_TAG);
if (provider == null) {
errorMsgTextFieldAdapter = new UITextFieldAdapter();
return;
}
try {
errorMsgTextFieldAdapter = provider.createTextFieldAdapter();
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
errorMsgTextFieldAdapter = new UITextFieldAdapter();
public void removeUpdate(DocumentEvent e) {
regErrorMsgField.setToolTipText(regErrorMsgField.getText());
}
});
}
}
@Override
@ -102,11 +108,11 @@ public class RegFieldPane extends RegPane {
}
public void populate(TextEditor textEditor) {
regErrorMsgField.setText(textEditor.getRegErrorMessage());
errorMsgTextFieldAdapter.setText(textEditor.getRegErrorMessage());
}
public void update(TextEditor textEditor) {
textEditor.setRegErrorMessage(regErrorMsgField.getText());
textEditor.setRegErrorMessage(errorMsgTextFieldAdapter.getText());
}
}

6
designer-base/src/main/java/com/fr/design/gui/ispinner/UISpinner.java

@ -73,6 +73,12 @@ public class UISpinner extends JPanel implements UIObserver, GlobalNameObserver
textField.setValue(defaultValue);
}
public UISpinner(double minValue, double maxValue, double dierta, double defaultValue, boolean fillNegativeNumber) {
init(minValue, maxValue, dierta);
textField.setValue(defaultValue);
textField.canFillNegativeNumber(fillNegativeNumber);
}
protected void init(double minValue, double maxValue, double dierta) {
this.minValue = minValue;
this.maxValue = maxValue;

85
designer-base/src/main/java/com/fr/design/gui/style/AlignmentPane.java

@ -17,6 +17,7 @@ import com.fr.design.gui.ibutton.UIButtonGroup;
import com.fr.design.gui.icombobox.UIComboBox;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.ispinner.UISpinner;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
@ -56,11 +57,11 @@ public class AlignmentPane extends AbstractBasicStylePane implements GlobalNameO
private static final int GAP = 23;
private static final int VERGAP = 3;
private static final Dimension SPINNER_DIMENSION = new Dimension(75, 20);
private static final String[] TEXT = {com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Wrap_Text"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Single_Line"),
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_StyleAlignment_Single_Line(Adjust_Font)"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_StyleAlignment_Multi_Line(Adjust_Font)")};
private static final String[] TEXT = {Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Wrap_Text"), Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Single_Line"),
Toolkit.i18nText("Fine-Design_Basic_StyleAlignment_Single_Line(Adjust_Font)"), Toolkit.i18nText("Fine-Design_Basic_StyleAlignment_Multi_Line(Adjust_Font)")};
private static final String[] LAYOUT = {com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Layout_Default"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Layout_Image_Titled"),
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Layout_Image_Extend"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Layout_Image_Adjust")};
private static final String[] LAYOUT = {Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Layout_Default"), Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Layout_Image_Titled"),
Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Layout_Image_Extend"), Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Layout_Image_Adjust")};
private JPanel hPaneContainer;
private JPanel vPaneContainer;
@ -103,8 +104,8 @@ public class AlignmentPane extends AbstractBasicStylePane implements GlobalNameO
{IOUtils.readIcon("/com/fr/design/images/m_format/cellstyle/defaultAlignment.png"), IOUtils.readIcon("/com/fr/design/images/m_format/cellstyle/defaultAlignment_white.png")}};
Integer[] hAlignment = new Integer[]{Constants.LEFT, Constants.CENTER, Constants.RIGHT, Integer.valueOf(Constants.DISTRIBUTED), Constants.NULL};
hAlignmentPane = new UIButtonGroup<>(hAlignmentIconArray, hAlignment);
hAlignmentPane.setAllToolTips(new String[]{com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Tooltips_Left"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Tooltips_Center"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Tooltips_Right"),
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Tooltips_Distributed"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Tooltips_DEFAULT")});
hAlignmentPane.setAllToolTips(new String[]{Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Tooltips_Left"), Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Tooltips_Center"), Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Tooltips_Right"),
Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Tooltips_Distributed"), Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Tooltips_DEFAULT")});
hPaneContainer = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
vPaneContainer = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
@ -113,7 +114,7 @@ public class AlignmentPane extends AbstractBasicStylePane implements GlobalNameO
{IOUtils.readIcon("/com/fr/design/images/m_format/cellstyle/v_down_normal.png"), IOUtils.readIcon("/com/fr/design/images/m_format/cellstyle/v_down_normal_white.png")}};
Integer[] vAlignment = new Integer[]{Constants.TOP, Constants.CENTER, Constants.BOTTOM};
vAlignmentPane = new UIButtonGroup<>(vAlignmentIconArray, vAlignment);
vAlignmentPane.setAllToolTips(new String[]{com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Tooltips_Top"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Tooltips_Center"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Tooltips_Bottom")});
vAlignmentPane.setAllToolTips(new String[]{Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Tooltips_Top"), Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Tooltips_Center"), Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Tooltips_Bottom")});
initOtherComponent();
initAllNames();
@ -175,7 +176,7 @@ public class AlignmentPane extends AbstractBasicStylePane implements GlobalNameO
private void initTextRotationCombox() {
ArrayList<String> selectOption = new ArrayList<>();
selectOption.add(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Custom_Angle"));
selectOption.add(Toolkit.i18nText("Fine-Design_Basic_Custom_Angle"));
VerticalTextProcessor processor = ExtraClassManager.getInstance().getSingle(VerticalTextProcessor.XML_TAG, DefaultVerticalTextProcessor.class);
selectOption.addAll(Arrays.asList(processor.getComboxOption()));
@ -183,25 +184,25 @@ public class AlignmentPane extends AbstractBasicStylePane implements GlobalNameO
}
private void initAllNames() {
hAlignmentPane.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Pane_Horizontal"));
vAlignmentPane.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Pane_Vertical"));
imageLayoutComboBox.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Image_Layout"));
textComboBox.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Text_Style"));
textRotationComboBox.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_StyleAlignment_Text_Rotation"));
rotationPane.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_StyleAlignment_Text_Rotation"));
leftIndentSpinner.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Left_Indent"));
rightIndentSpinner.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Right_Indent"));
spaceBeforeSpinner.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Spacing_Before"));
spaceAfterSpinner.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Spacing_After"));
lineSpaceSpinner.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Line_Spacing"));
hAlignmentPane.setGlobalName(Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Pane_Horizontal"));
vAlignmentPane.setGlobalName(Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Pane_Vertical"));
imageLayoutComboBox.setGlobalName(Toolkit.i18nText("Fine-Design_Basic_Image_Layout"));
textComboBox.setGlobalName(Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Text_Style"));
textRotationComboBox.setGlobalName(Toolkit.i18nText("Fine-Design_Basic_StyleAlignment_Text_Rotation"));
rotationPane.setGlobalName(Toolkit.i18nText("Fine-Design_Basic_StyleAlignment_Text_Rotation"));
leftIndentSpinner.setGlobalName(Toolkit.i18nText("Fine-Design_Basic_Style_Left_Indent"));
rightIndentSpinner.setGlobalName(Toolkit.i18nText("Fine-Design_Basic_Style_Right_Indent"));
spaceBeforeSpinner.setGlobalName(Toolkit.i18nText("Fine-Design_Basic_Style_Spacing_Before"));
spaceAfterSpinner.setGlobalName(Toolkit.i18nText("Fine-Design_Basic_Style_Spacing_After"));
lineSpaceSpinner.setGlobalName(Toolkit.i18nText("Fine-Design_Basic_Style_Line_Spacing"));
}
private JPanel createPane() {
JPanel jp1 = new JPanel(new BorderLayout());
basicPane = new JPanel();
seniorPane = new JPanel();
basicPane = new UIExpandablePane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Basic"), 290, 24, basicPane());
seniorPane = new UIExpandablePane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Advanced"), 290, 24, seniorPane());
basicPane = new UIExpandablePane(Toolkit.i18nText("Fine-Design_Report_Basic"), 290, 24, basicPane());
seniorPane = new UIExpandablePane(Toolkit.i18nText("Fine-Design_Basic_Advanced"), 290, 24, seniorPane());
jp1.add(basicPane, BorderLayout.NORTH);
jp1.add(seniorPane, BorderLayout.CENTER);
@ -212,13 +213,13 @@ public class AlignmentPane extends AbstractBasicStylePane implements GlobalNameO
private JPanel basicPane() {
double f = TableLayout.FILL;
double p = TableLayout.PREFERRED;
UILabel horizontalLabel = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Pane_Horizontal") + " ", SwingConstants.LEFT);
UILabel horizontalLabel = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Pane_Horizontal") + " ", SwingConstants.LEFT);
UIComponentUtils.setLineWrap(horizontalLabel);
Component[][] components = new Component[][]{
new Component[]{null, null},
new Component[]{horizontalLabel, hPaneContainer},
new Component[]{null, null},
new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Pane_Vertical") + " ", SwingConstants.RIGHT), vPaneContainer},
new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Pane_Vertical") + " ", SwingConstants.RIGHT), vPaneContainer},
new Component[]{null, null}
};
double[] rowSize = {p, p, p, p, p, p};
@ -233,11 +234,11 @@ public class AlignmentPane extends AbstractBasicStylePane implements GlobalNameO
double p = TableLayout.PREFERRED;
Component[][] components = new Component[][]{
new Component[]{null, null},
new Component[]{new UILabel((com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Image_Layout")) + " ", SwingConstants.LEFT), imageLayoutComboBox},
new Component[]{new UILabel((Toolkit.i18nText("Fine-Design_Basic_Image_Layout")) + " ", SwingConstants.LEFT), imageLayoutComboBox},
new Component[]{null, null},
new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Text_Style") + " ", SwingConstants.LEFT), textComboBox},
new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Text_Style") + " ", SwingConstants.LEFT), textComboBox},
new Component[]{null, null},
new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_StyleAlignment_Text_Rotation") + " ", SwingConstants.LEFT), textRotationComboBox},
new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Basic_StyleAlignment_Text_Rotation") + " ", SwingConstants.LEFT), textRotationComboBox},
new Component[]{null, rotationBarCC},
new Component[]{null, null},
};
@ -261,23 +262,23 @@ public class AlignmentPane extends AbstractBasicStylePane implements GlobalNameO
lineSpaceSpinner.setPreferredSize(SPINNER_DIMENSION);
JPanel indentationPane = new JPanel(new BorderLayout());
indentationPane.add(new UILabel((com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Style_Indentation")), SwingConstants.LEFT));
indentationPane.add(new UILabel((Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Style_Indentation")), SwingConstants.LEFT));
indentationPane.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, GAP));
JPanel partSpacingPane = new JPanel(new BorderLayout());
partSpacingPane.add(new UILabel((com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Style_Part_Spacing")), SwingConstants.LEFT));
partSpacingPane.add(new UILabel((Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Style_Part_Spacing")), SwingConstants.LEFT));
partSpacingPane.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, GAP));
JPanel spacingPane = new JPanel(new BorderLayout());
spacingPane.add(new UILabel((com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Style_Spacing")), SwingConstants.LEFT));
spacingPane.add(new UILabel((Toolkit.i18nText("Fine-Design_Basic_Style_Line_Spacing")), SwingConstants.LEFT));
spacingPane.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, GAP));
Component[][] components = new Component[][]{
new Component[]{null, null, null},
new Component[]{indentationPane, creatSpinnerPane(leftIndentSpinner), creatSpinnerPane(rightIndentSpinner)},
new Component[]{null, new UILabel((com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Left")), SwingConstants.CENTER), new UILabel((com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Right")), SwingConstants.CENTER)},
new Component[]{null, new UILabel((Toolkit.i18nText("Fine-Design_Report_Left")), SwingConstants.CENTER), new UILabel((Toolkit.i18nText("Fine-Design_Basic_Right")), SwingConstants.CENTER)},
new Component[]{null, null, null},
new Component[]{null, null, null},
new Component[]{partSpacingPane, creatSpinnerPane(spaceBeforeSpinner), creatSpinnerPane(spaceAfterSpinner)},
new Component[]{null, new UILabel((com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Front")), SwingConstants.CENTER), new UILabel((com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Behind")), SwingConstants.CENTER)},
new Component[]{null, new UILabel((Toolkit.i18nText("Fine-Design_Basic_Front")), SwingConstants.CENTER), new UILabel((Toolkit.i18nText("Fine-Design_Basic_Behind")), SwingConstants.CENTER)},
new Component[]{null, null, null},
new Component[]{null, null, null},
new Component[]{spacingPane, creatSpinnerPane(lineSpaceSpinner), null},
@ -300,7 +301,7 @@ public class AlignmentPane extends AbstractBasicStylePane implements GlobalNameO
* @return 标题
*/
public String title4PopupWindow() {
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Style_Alignment");
return Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Style_Alignment");
}
/**
@ -363,18 +364,18 @@ public class AlignmentPane extends AbstractBasicStylePane implements GlobalNameO
return null;
}
if (ComparatorUtils.equals(globalNameListener.getGlobalName(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Pane_Horizontal"))) {
if (ComparatorUtils.equals(globalNameListener.getGlobalName(), Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Pane_Horizontal"))) {
Integer h = this.hAlignmentPane.getSelectedItem();
style = style.deriveHorizontalAlignment(h == null ? -1 : h);
}
if (ComparatorUtils.equals(globalNameListener.getGlobalName(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Pane_Vertical"))) {
if (ComparatorUtils.equals(globalNameListener.getGlobalName(), Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Pane_Vertical"))) {
Integer vAlign = this.vAlignmentPane.getSelectedItem();
if (vAlign != null) {
style = style.deriveVerticalAlignment(vAlign);
}
}
if (ComparatorUtils.equals(globalNameListener.getGlobalName(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Text_Style"))) {
if (ComparatorUtils.equals(globalNameListener.getGlobalName(), Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Text_Style"))) {
if (ComparatorUtils.equals(this.textComboBox.getSelectedItem(), TEXT[0])) {
style = style.deriveTextStyle(Style.TEXTSTYLE_WRAPTEXT);
} else if (ComparatorUtils.equals(this.textComboBox.getSelectedItem(), TEXT[1])) {
@ -394,7 +395,7 @@ public class AlignmentPane extends AbstractBasicStylePane implements GlobalNameO
private Style updateImageLayout(Style style) {
if (ComparatorUtils.equals(globalNameListener.getGlobalName(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Image_Layout"))) {
if (ComparatorUtils.equals(globalNameListener.getGlobalName(), Toolkit.i18nText("Fine-Design_Basic_Image_Layout"))) {
if (ComparatorUtils.equals(this.imageLayoutComboBox.getSelectedItem(), LAYOUT[1])) {
style = style.deriveImageLayout(Constants.IMAGE_TILED);
} else if (ComparatorUtils.equals(this.imageLayoutComboBox.getSelectedItem(), LAYOUT[2])) {
@ -410,7 +411,7 @@ public class AlignmentPane extends AbstractBasicStylePane implements GlobalNameO
private Style updateTextRotation(Style style) {
if (ComparatorUtils.equals(globalNameListener.getGlobalName(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_StyleAlignment_Text_Rotation"))) {
if (ComparatorUtils.equals(globalNameListener.getGlobalName(), Toolkit.i18nText("Fine-Design_Basic_StyleAlignment_Text_Rotation"))) {
if (this.textRotationComboBox.getSelectedIndex() != 0) {
style = style.deriveVerticalText(Style.VERTICALTEXT);
style = style.deriveRotation(0);
@ -424,21 +425,21 @@ public class AlignmentPane extends AbstractBasicStylePane implements GlobalNameO
}
private Style updateOther(Style style) {
if (ComparatorUtils.equals(globalNameListener.getGlobalName(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Left_Indent"))) {
if (ComparatorUtils.equals(globalNameListener.getGlobalName(), Toolkit.i18nText("Fine-Design_Basic_Style_Left_Indent"))) {
style = style.derivePaddingLeft(indentationUnitProcessor.paddingUnitGainFromSpinner((int) (this.leftIndentSpinner.getValue())));
}
if (ComparatorUtils.equals(globalNameListener.getGlobalName(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Right_Indent"))) {
if (ComparatorUtils.equals(globalNameListener.getGlobalName(), Toolkit.i18nText("Fine-Design_Basic_Style_Right_Indent"))) {
style = style.derivePaddingRight(indentationUnitProcessor.paddingUnitGainFromSpinner((int) (this.rightIndentSpinner.getValue())));
}
//间距
if (ComparatorUtils.equals(globalNameListener.getGlobalName(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Spacing_Before"))) {
if (ComparatorUtils.equals(globalNameListener.getGlobalName(), Toolkit.i18nText("Fine-Design_Basic_Style_Spacing_Before"))) {
style = style.deriveSpacingBefore((int) (this.spaceBeforeSpinner.getValue()));
}
if (ComparatorUtils.equals(globalNameListener.getGlobalName(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Spacing_After"))) {
if (ComparatorUtils.equals(globalNameListener.getGlobalName(), Toolkit.i18nText("Fine-Design_Basic_Style_Spacing_After"))) {
style = style.deriveSpacingAfter((int) (this.spaceAfterSpinner.getValue()));
}
if (ComparatorUtils.equals(globalNameListener.getGlobalName(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Line_Spacing"))) {
if (ComparatorUtils.equals(globalNameListener.getGlobalName(), Toolkit.i18nText("Fine-Design_Basic_Style_Line_Spacing"))) {
style = style.deriveLineSpacing((int) (this.lineSpaceSpinner.getValue()));
}
return style;

86
designer-base/src/main/java/com/fr/design/gui/style/TextFontTippedPane.java

@ -0,0 +1,86 @@
package com.fr.design.gui.style;
import com.fr.base.Style;
import com.fr.design.constants.LayoutConstants;
import com.fr.design.designer.IntervalConstants;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.mainframe.theme.edit.ui.LabelUtils;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
/**
* @author Starryi
* @version 1.0
* Created by Starryi on 2021/9/29
*/
public class TextFontTippedPane extends AbstractBasicStylePane {
private FRFontPane fontPane;
public TextFontTippedPane(boolean showFormatTip) {
this.initializePane(showFormatTip);
}
private void initializePane(boolean showFormatTip) {
setLayout(new BorderLayout());
setBorder(BorderFactory.createEmptyBorder(IntervalConstants.INTERVAL_L1, 0, 0, 0));
fontPane = new FRFontPane();
this.add(createLabeledPane(Toolkit.i18nText("Fine-Design_Form_FR_Font"), fontPane), BorderLayout.NORTH);
if (showFormatTip) {
JPanel formatTipPane = createFormatTipPane();
this.add(formatTipPane, BorderLayout.CENTER);
}
}
private JPanel createLabeledPane(String text, JPanel panel) {
double f = TableLayout.FILL;
double p = TableLayout.PREFERRED;
double[] rowSize = { p };
double[] columnSize = {p, f};
UILabel uiLabel = new UILabel(text);
JPanel uiLabelPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
uiLabelPane.add(uiLabel, BorderLayout.NORTH);
return TableLayoutHelper.createGapTableLayoutPane(new Component[][]{
new Component[] { uiLabelPane, panel },
}, rowSize, columnSize, LayoutConstants.VGAP_LARGE, LayoutConstants.VGAP_MEDIUM);
}
private JPanel createFormatTipPane() {
JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane();
container.setBorder(BorderFactory.createEmptyBorder(IntervalConstants.INTERVAL_L1, 0, 0, 0));
JTextArea formatMigratedTip = LabelUtils.createAutoWrapLabel(Toolkit.i18nText("Fine-Design_Report_Format_Style_Migrated_Tip"), new Color(153, 153, 153));
container.add(formatMigratedTip, BorderLayout.NORTH);
return container;
}
@Override
public String title4PopupWindow() {
return Toolkit.i18nText("Fine-Design_Report_Text");
}
@Override
public void populateBean(Style style) {
this.fontPane.populateBean(style);
}
@Override
public Style update(Style style) {
return this.fontPane.update(style);
}
}

483
designer-base/src/main/java/com/fr/design/gui/style/TextFormatPane.java

@ -0,0 +1,483 @@
package com.fr.design.gui.style;
import com.fr.base.CoreDecimalFormat;
import com.fr.base.GraphHelper;
import com.fr.base.Style;
import com.fr.base.TextFormat;
import com.fr.data.core.FormatField;
import com.fr.data.core.FormatField.FormatContents;
import com.fr.design.border.UIRoundedBorder;
import com.fr.design.constants.LayoutConstants;
import com.fr.design.constants.UIConstants;
import com.fr.design.event.GlobalNameListener;
import com.fr.design.event.GlobalNameObserver;
import com.fr.design.event.UIObserverListener;
import com.fr.design.gui.icheckbox.UICheckBox;
import com.fr.design.gui.icombobox.TextFontComboBox;
import com.fr.design.gui.icombobox.UIComboBox;
import com.fr.design.gui.icombobox.UIComboBoxRenderer;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.general.ComparatorUtils;
import com.fr.stable.StringUtils;
import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.math.RoundingMode;
import java.text.Format;
import java.text.SimpleDateFormat;
/**
* @author Starryi
* @version 1.0
* Created by Starryi on 2021/9/29
* 包含格式相关的设置
*/
public class TextFormatPane extends AbstractBasicStylePane implements GlobalNameObserver {
private static final long serialVersionUID = 724330854437726751L;
private static final int LABEL_X = 4;
private static final int LABEL_Y = 18;
private static final int LABEL_DELTA_WIDTH = 8;
private static final int LABEL_HEIGHT = 15; //标签背景的范围
private static final int CURRENCY_FLAG_POINT = 6;
private static final Integer[] TYPES = new Integer[]{
FormatContents.NULL, FormatContents.NUMBER,
FormatContents.CURRENCY, FormatContents.PERCENT,
FormatContents.SCIENTIFIC, FormatContents.DATE,
FormatContents.TIME, FormatContents.TEXT};
private static final Integer[] DATE_TYPES = new Integer[]{FormatContents.NULL, FormatContents.DATE, FormatContents.TIME};
private Format format;
private UIComboBox typeComboBox;
private TextFontComboBox textField;
private UILabel sampleLabel;
private JPanel contentPane;
private JPanel txtCenterPane;
private JPanel centerPane;
private JPanel optionPane;
private UICheckBox roundingBox;
private JPanel formatFontPane;
private boolean isRightFormat;
private boolean isDate = false;
private GlobalNameListener globalNameListener = null;
/**
* Constructor.
*/
public TextFormatPane() {
this.initComponents(TYPES);
}
protected UIComboBox getTypeComboBox() {
return typeComboBox;
}
protected void initComponents(Integer[] types) {
this.setLayout(new BorderLayout(0, 4));
initSampleLabel();
contentPane = new JPanel(new BorderLayout(0, 4)) {
@Override
public Dimension getPreferredSize() {
return new Dimension(super.getPreferredSize().width, 65);
}
};
typeComboBox = new UIComboBox(types);
UIComboBoxRenderer render = createComBoxRender();
typeComboBox.setRenderer(render);
typeComboBox.addItemListener(itemListener);
typeComboBox.setGlobalName("typeComboBox");
contentPane.add(sampleLabel, BorderLayout.NORTH);
txtCenterPane = new JPanel(new BorderLayout());
textField = new TextFontComboBox();
textField.addItemListener(textFieldItemListener);
textField.setEditable(true);
textField.setGlobalName("textField");
txtCenterPane.add(textField, BorderLayout.NORTH);
contentPane.add(txtCenterPane, BorderLayout.CENTER);
centerPane = new JPanel(new CardLayout());
centerPane.add(new JPanel(), "hide");
centerPane.setPreferredSize(new Dimension(0, 0));
centerPane.add(contentPane, "show");
typeComboBox.setPreferredSize(new Dimension(155,20));
JPanel typePane = new JPanel(new BorderLayout());
typePane.add(typeComboBox, BorderLayout.CENTER);
typePane.setBorder(BorderFactory.createEmptyBorder(0, 20, 0, 0));
JPanel option = new JPanel(new BorderLayout());
option.add(new UILabel(Toolkit.i18nText("Fine-Design_Report_Base_Option"), SwingConstants.LEFT), BorderLayout.WEST);
roundingBox = new UICheckBox(Toolkit.i18nText("Fine-Design_Report_Base_Option_Half_Up"));
roundingBox.setBorder(BorderFactory.createEmptyBorder(0, 30, 0, 0));
roundingBox.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
}
});
roundingBox.setGlobalName("roundingBox");
option.add(roundingBox, BorderLayout.CENTER);
optionPane = new JPanel(new CardLayout());
optionPane.add(new JPanel(), "hide");
optionPane.setPreferredSize(new Dimension(0, 0));
optionPane.add(option, "show");
Component[][] components = getComponent(centerPane, typePane);
this.add(createContentPane(components), BorderLayout.CENTER);
}
protected JPanel createContentPane (Component[][] components) {
double f = TableLayout.FILL;
double p = TableLayout.PREFERRED;
double[] rowSize = {p, p, p, p, p};
double[] columnSize = {p, f};
int[][] rowCount = {{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}};
return TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, LayoutConstants.VGAP_LARGE, LayoutConstants.VGAP_MEDIUM);
}
protected Component[][] getComponent (JPanel centerPane, JPanel typePane) {
return new Component[][]{
new Component[]{null, null},
new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Report_Base_Format"), SwingConstants.LEFT), typePane},
new Component[]{centerPane, null},
new Component[]{optionPane, null},
};
}
protected UIComboBoxRenderer createComBoxRender() {
return new UIComboBoxRenderer() {
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (value instanceof Integer) {
label.setText(" " + FormatField.getInstance().getName((Integer) value));
}
return label;
}
};
}
private void initSampleLabel() {
Border interBorder = new UIRoundedBorder(UIConstants.LINE_COLOR, 1, 4);
String title = Toolkit.i18nText("Fine-Design_Report_Base_StyleFormat_Sample");
Border border = BorderFactory.createTitledBorder(interBorder, title, TitledBorder.LEFT, 0, null, UIConstants.LINE_COLOR);
sampleLabel = new UILabel(FormatField.getInstance().getFormatValue()) {
@Override
public void paint(Graphics g) {
super.paint(g);
int width = getWidth();
Color original = g.getColor();
g.setColor(getBackground());
g.fillRect(LABEL_X, LABEL_Y, width - LABEL_DELTA_WIDTH, LABEL_HEIGHT);
g.setColor(UIConstants.LINE_COLOR);
FontMetrics cellFM = g.getFontMetrics();
int textWidth = cellFM.stringWidth(getText());
GraphHelper.drawString(g, getText(), (width - textWidth) / 2, 26);
g.setColor(original);
}
};
sampleLabel.setHorizontalAlignment(UILabel.CENTER);
sampleLabel.setBorder(border);
}
@Override
/**
* 得到合适的大小
*/
public Dimension getPreferredSize() {
if (this.typeComboBox.getSelectedIndex() == FormatContents.NULL) {
return typeComboBox.getPreferredSize();
}
return super.getPreferredSize();
}
/**
* 弹出框标题
*
* @return 标题
*/
public String title4PopupWindow() {
return Toolkit.i18nText("Fine-Design_Report_Text");
}
/**
* Populate
*/
public void populateBean(Format format) {
this.format = format;
if (format == null) {
this.typeComboBox.setSelectedIndex(FormatContents.NULL);
} else {
if (format instanceof CoreDecimalFormat) {
// check all value
String pattern = ((CoreDecimalFormat) format).toPattern();
if (isCurrencyFormatStyle(pattern)) {
setPatternComboBoxAndList(FormatContents.CURRENCY, pattern);
} else if (pattern.indexOf("%") > 0) {
setPatternComboBoxAndList(FormatContents.PERCENT, pattern);
this.roundingBox.setSelected(((CoreDecimalFormat) format).getRoundingMode().equals(RoundingMode.HALF_UP));
} else if (pattern.indexOf("E") > 0) {
setPatternComboBoxAndList(FormatContents.SCIENTIFIC, pattern);
} else {
setPatternComboBoxAndList(FormatContents.NUMBER, pattern);
}
} else if (format instanceof SimpleDateFormat) { // date and time
String pattern = ((SimpleDateFormat) format).toPattern();
if (!isTimeType(pattern)) {
setPatternComboBoxAndList(FormatContents.DATE, pattern);
} else {
setPatternComboBoxAndList(FormatContents.TIME, pattern);
}
} else if (format instanceof TextFormat) { // Text
this.typeComboBox.setSelectedItem(FormatContents.TEXT);
}
}
}
private boolean isCurrencyFormatStyle(String pattern) {
if (pattern.length() == 0) {
return false;
}
if (pattern.charAt(0) == '¤' || pattern.charAt(0) == '$') {
return true;
}
return pattern.length() > CURRENCY_FLAG_POINT && pattern.startsWith("#,##0;");
}
/**
* 判断是否是数组有模式
*
* @param stringArray 字符串数组
* @param pattern 格式
* @return 是否是数组有模式
*/
public static int isArrayContainPattern(String[] stringArray, String pattern) {
for (int i = 0; i < stringArray.length; i++) {
if (ComparatorUtils.equals(stringArray[i], pattern)) {
return i;
}
}
return -1;
}
private void setPatternComboBoxAndList(int formatStyle, String pattern) {
this.typeComboBox.setSelectedItem(formatStyle);
this.textField.setSelectedItem(pattern);
}
private boolean isTimeType(String pattern) {
return pattern.matches(".*[Hhmsa].*");
}
/**
* update
*/
public Format update() {
String patternString = String.valueOf(textField.getSelectedItem());
if (getFormatContents() == FormatContents.TEXT) {
return FormatField.getInstance().getFormat(getFormatContents(), patternString);
}
if (isRightFormat) {
if (StringUtils.isNotEmpty(patternString)) {
RoundingMode roundingMode = roundingBox.isSelected() ? RoundingMode.HALF_UP : RoundingMode.HALF_EVEN;
return FormatField.getInstance().getFormat(getFormatContents(), patternString, roundingMode);
}
}
return null;
}
private int getFormatContents() {
return (Integer) typeComboBox.getSelectedItem();
}
/**
* Refresh preview label.
*/
private void refreshPreviewLabel() {
this.sampleLabel.setText(FormatField.getInstance().getFormatValue());
this.sampleLabel.setForeground(UIManager.getColor("Label.foreground"));
try {
isRightFormat = true;
if (StringUtils.isEmpty(String.valueOf(textField.getSelectedItem()))) {
return;
}
this.sampleLabel.setText(FormatField.getInstance().getFormatValue(getFormatContents(), String.valueOf(textField.getSelectedItem())));
} catch (Exception e) {
this.sampleLabel.setForeground(Color.red);
this.sampleLabel.setText(e.getMessage());
isRightFormat = false;
}
}
private boolean isTextOrNull() {
int contents = getFormatContents();
return contents == FormatContents.TEXT || contents == FormatContents.NULL;
}
/**
* Radio selection listener.
*/
ItemListener itemListener = new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
int contents = getFormatContents();
String[] items = FormatField.getInstance().getFormatArray(contents, false);
CardLayout cardLayout = (CardLayout) centerPane.getLayout();
if (isTextOrNull()) {
centerPane.setPreferredSize(new Dimension(0, 0));
cardLayout.show(centerPane, "hide");
} else {
textField.removeAllItems();
textField.setItemArray(items);
textField.setSelectedIndex(0);
centerPane.setPreferredSize(new Dimension(270, 65));
cardLayout.show(centerPane, "show");
}
CardLayout optionLayout = ((CardLayout) optionPane.getLayout());
if (getFormatContents() == FormatContents.PERCENT) {
optionPane.setPreferredSize(new Dimension(100, 20));
optionLayout.show(optionPane, "show");
} else {
optionPane.setPreferredSize(new Dimension(0, 0));
optionLayout.show(optionPane, "hide");
roundingBox.setSelected(false);
}
}
}
};
ItemListener textFieldItemListener = new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
refreshPreviewLabel();
}
}
};
@Override
/**
* populate
*/
public void populateBean(Style style) {
this.populateBean(style.getFormat());
}
@Override
/**
* update
*/
public Style update(Style style) {
if (ComparatorUtils.equals(globalNameListener.getGlobalName(), "textField")
|| ComparatorUtils.equals(globalNameListener.getGlobalName(), "typeComboBox")
|| ComparatorUtils.equals(globalNameListener.getGlobalName(), "roundingBox")) {
return style.deriveFormat(this.update());
}
return style;
}
/**
* 默认只显示百分比的编辑下拉.
*/
public void justUsePercentFormat() {
typeComboBox.setEnabled(false);
this.typeComboBox.setSelectedItem(FormatContents.PERCENT);
}
public void setForDataSheet() {
Integer[] otherTypes = new Integer[]{FormatContents.NULL, FormatContents.NUMBER, FormatContents.CURRENCY, FormatContents.PERCENT, FormatContents.SCIENTIFIC,};
this.typeComboBox = new UIComboBox(otherTypes);
UIComboBoxRenderer render = new UIComboBoxRenderer() {
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (value instanceof Integer) {
label.setText(" " + FormatField.getInstance().getName((Integer) value));
}
return label;
}
};
typeComboBox.setRenderer(render);
typeComboBox.addItemListener(itemListener);
setTypeComboBoxPane(typeComboBox);
}
protected void setTypeComboBoxPane (UIComboBox typeComboBox) {
this.add(typeComboBox, BorderLayout.NORTH);
}
public void setComboBoxModel(boolean isDate) {
if (this.isDate != isDate) {
this.isDate = isDate;
this.typeComboBox.setSelectedIndex(0);
if (isDate) {
for (int i = 0; i < DATE_TYPES.length; i++) {
this.typeComboBox.addItem(DATE_TYPES[i]);
}
for (int i = 0; i < TYPES.length; i++) {
this.typeComboBox.removeItemAt(1);
}
} else {
for (int i = 0; i < TYPES.length; i++) {
this.typeComboBox.addItem(TYPES[i]);
}
for (int i = 0; i < DATE_TYPES.length; i++) {
this.typeComboBox.removeItemAt(1);
}
}
}
}
@Override
public void registerNameListener(GlobalNameListener listener) {
globalNameListener = listener;
}
public void registerChangeListener(UIObserverListener listener) {
typeComboBox.registerChangeListener(listener);
textField.registerChangeListener(listener);
}
@Override
public boolean shouldResponseNameListener() {
return false;
}
@Override
public void setGlobalName(String name) {
}
}

24
designer-base/src/main/java/com/fr/design/gui/style/TranslucentBorderSpecialPane.java

@ -299,15 +299,16 @@ public class TranslucentBorderSpecialPane extends AbstractBorderPackerPane imple
Background borderImage = style.getBorderImage();
if (borderImage instanceof ImageBackground) {
// 图片类型边框
Image image = ((ImageBackground) borderImage).getImage();
int[] ninePoint = ((ImageBackground) borderImage).getNinePoint();
ImageBackground imageBackground = (ImageBackground) borderImage;
Image image = imageBackground.getImage();
if (image != null) {
this.borderLineCombo.selectBorderImage();
this.imagePreviewPane.setImageWithSuffix(((ImageBackground) borderImage).getImageWithSuffix());
this.tweakNinePointButton.setEnabled(true);
this.borderImageOpacityPane.populateBean(style.getBorderImageOpacity());
if (ninePoint != null && ninePoint.length == 4 && ninePoint[0] > 0 && ninePoint[1] > 0 && ninePoint[2] > 0 && ninePoint[3] > 0) {
int[] ninePoint = ((ImageBackground) borderImage).getNinePoint();
if (ninePoint != null && ninePoint.length == 4 && ninePoint[0] >= 0 && ninePoint[1] >= 0 && ninePoint[2] >= 0 && ninePoint[3] >= 0) {
this.ninePoint = Arrays.copyOf(ninePoint, 4);
} else {
this.ninePoint = new int[4];
@ -487,6 +488,7 @@ public class TranslucentBorderSpecialPane extends AbstractBorderPackerPane imple
private int ninePointBottom = -1;
private static final int MIN_NINE_POINT = 0;
private static final int MIN_GAP_PARALLEL_LINES = 1;
private int imgWidth;
private int imgHeight;
@ -757,8 +759,8 @@ public class TranslucentBorderSpecialPane extends AbstractBorderPackerPane imple
private void onNinePointTopChanged(int value) {
if (value < MIN_NINE_POINT) {
value = MIN_NINE_POINT;
} else if (value >= imgHeight - ninePointBottom) {
value = imgHeight - ninePointBottom - MIN_NINE_POINT;
} else if (value >= imgHeight - ninePointBottom - MIN_GAP_PARALLEL_LINES) {
value = imgHeight - ninePointBottom - MIN_GAP_PARALLEL_LINES;
}
this.ninePointTop = value;
repaint();
@ -767,8 +769,8 @@ public class TranslucentBorderSpecialPane extends AbstractBorderPackerPane imple
private void onNinePointBottomChanged(int value) {
if (value < MIN_NINE_POINT) {
value = MIN_NINE_POINT;
} else if (value >= imgHeight - ninePointTop) {
value = imgHeight - ninePointTop - MIN_NINE_POINT;
} else if (value >= imgHeight - ninePointTop - MIN_GAP_PARALLEL_LINES) {
value = imgHeight - ninePointTop - MIN_GAP_PARALLEL_LINES;
}
this.ninePointBottom = value;
repaint();
@ -777,8 +779,8 @@ public class TranslucentBorderSpecialPane extends AbstractBorderPackerPane imple
private void onNinePointLeftChanged(int value) {
if (value < MIN_NINE_POINT) {
value = MIN_NINE_POINT;
} else if (value >= imgWidth - ninePointRight) {
value = imgWidth - ninePointRight - MIN_NINE_POINT;
} else if (value >= imgWidth - ninePointRight - MIN_GAP_PARALLEL_LINES) {
value = imgWidth - ninePointRight - MIN_GAP_PARALLEL_LINES;
}
this.ninePointLeft = value;
repaint();
@ -787,8 +789,8 @@ public class TranslucentBorderSpecialPane extends AbstractBorderPackerPane imple
private void onNinePointRightChanged(int value) {
if (value < MIN_NINE_POINT) {
value = MIN_NINE_POINT;
} else if (value >= imgWidth - ninePointLeft) {
value = imgWidth - ninePointLeft - MIN_NINE_POINT;
} else if (value >= imgWidth - ninePointLeft - MIN_GAP_PARALLEL_LINES) {
value = imgWidth - ninePointLeft - MIN_GAP_PARALLEL_LINES;
}
this.ninePointRight = value;
repaint();

871
designer-base/src/main/java/com/fr/design/javascript/ExportJavaScriptPane.java

@ -3,6 +3,7 @@ package com.fr.design.javascript;
import com.fr.base.BaseFormula;
import com.fr.base.Parameter;
import com.fr.base.extension.FileExtension;
import com.fr.design.border.UITitledBorder;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.BasicPane;
import com.fr.design.dialog.DialogActionAdapter;
@ -15,6 +16,10 @@ import com.fr.design.gui.icheckbox.UICheckBox;
import com.fr.design.gui.icombobox.UIComboBox;
import com.fr.design.gui.icombobox.UIComboBoxRenderer;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.itableeditorpane.ParameterTableModel;
import com.fr.design.gui.itableeditorpane.UITableEditAction;
import com.fr.design.gui.itableeditorpane.UITableEditorPane;
import com.fr.design.gui.itableeditorpane.UITableModelAdapter;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.gui.itree.filetree.TemplateFileTree;
import com.fr.design.hyperlink.AbstractHyperLinkPane;
@ -23,32 +28,40 @@ import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.scrollruler.ModLineBorder;
import com.fr.file.filetree.IOFileNodeFilter;
import com.fr.general.GeneralUtils;
import com.fr.js.ExportJavaScript;
import com.fr.js.SingleJavaScript;
import com.fr.stable.ParameterProvider;
import com.fr.stable.StringUtils;
import javax.swing.AbstractButton;
import javax.swing.AbstractCellEditor;
import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.TableCellEditor;
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@ -59,21 +72,20 @@ public class ExportJavaScriptPane extends AbstractHyperLinkPane<ExportJavaScript
private ExportRadioGroup templateRadioGroup;
private UIRadioButton currentTemplateRadio;
private UIRadioButton otherTemplateRadio;
private UITextField reportPathTextField;
private UIButton browserButton;
private UIComboBox exportTypeComboBox;
private ExportRadioGroup fileNameRadioGroup;
private UIRadioButton defaultNameRadio;
private UIRadioButton customNameRadio;
private FormulaEditor fileNameFormulaEditor;
private UICheckBox extendParametersCheckBox;
private ReportletParameterViewPane parameterViewPane;
private CardLayout card;
private JPanel templatePanel;
private CurrentTemplatePane currentTemplatePane;
private OtherTemplatePane otherTemplatePane;
private static final double p = TableLayout.PREFERRED;
private static final Map<String, String> EXPORT_TYPES_MAP = new HashMap<>();
private static final String CURRENT_TEMPLATE = "current";
private static final String DEFAULT_FILENAME = "default";
private static final Map<String, String> FILENAME_TYPE_MAP = new HashMap<>();
private static final Map<String, String> PARAMETER_TYPE_MAP = new HashMap<>();
private static final String DEFAULT = "default";
private static final String CUSTOM = "custom";
private static final String CURRENT_TEMPLATE = "cur";
private static final String OTHER_TEMPLATE = "other";
static {
EXPORT_TYPES_MAP.put(ExportJavaScript.EXPORT_PDF, Toolkit.i18nText("Fine-Design_Basic_Export_JS_PDF"));
@ -82,134 +94,601 @@ public class ExportJavaScriptPane extends AbstractHyperLinkPane<ExportJavaScript
EXPORT_TYPES_MAP.put(ExportJavaScript.EXPORT_EXCEL_SHEET, Toolkit.i18nText("Fine-Design_Basic_Export_JS_Excel_Sheet"));
EXPORT_TYPES_MAP.put(ExportJavaScript.EXPORT_WORD, Toolkit.i18nText("Fine-Design_Basic_Export_JS_Word"));
EXPORT_TYPES_MAP.put(ExportJavaScript.EXPORT_IMAGE, Toolkit.i18nText("Fine-Design_Basic_Export_JS_Image"));
FILENAME_TYPE_MAP.put(DEFAULT, Toolkit.i18nText("Fine-Design_Basic_Export_JS_Filename_Default"));
FILENAME_TYPE_MAP.put(CUSTOM, Toolkit.i18nText("Fine-Design_Basic_Export_JS_Custom"));
PARAMETER_TYPE_MAP.put(DEFAULT, Toolkit.i18nText("Fine-Design_Basic_Export_JS_Extend_Parameters"));
PARAMETER_TYPE_MAP.put(CUSTOM, Toolkit.i18nText("Fine-Design_Basic_Export_JS_Custom"));
}
public ExportJavaScriptPane() {
initComponents();
}
// 当前模板
class CurrentTemplatePane extends BasicPane {
private void initComponents() {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
this.setBorder(BorderFactory.createTitledBorder(new ModLineBorder(ModLineBorder.TOP), Toolkit.i18nText("Fine-Design_Basic_Export_JS_Setting")));
private ExportRadioGroup fileNameRadioGroup;
private UIRadioButton defaultNameRadio;
private UIRadioButton customNameRadio;
private FormulaEditor fileNameFormulaEditor;
private UICheckBox extendParametersCheckBox;
private ReportletParameterViewPane parameterViewPane;
//导出模板+导出方式+导出文件名
JPanel northPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
public CurrentTemplatePane() {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
this.setBorder(UITitledBorder.createBorderWithTitle(Toolkit.i18nText("Fine-Design_Basic_Export_JS_Template_Current")));
//导出模板
JPanel chooseTemplatePane = initChooseTemplatePane();
northPane.add(chooseTemplatePane, BorderLayout.NORTH);
JPanel northPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
//导出方式
JPanel exportTypePane = initExportTypePane();
northPane.add(exportTypePane, BorderLayout.CENTER);
//导出方式
JPanel exportTypePane = initExportTypePane();
northPane.add(exportTypePane, BorderLayout.CENTER);
//导出文件名
JPanel fileNamePane = initFileNamePane();
northPane.add(fileNamePane, BorderLayout.SOUTH);
//导出文件名
JPanel fileNamePane = initFileNamePane();
northPane.add(fileNamePane, BorderLayout.SOUTH);
//参数
JPanel centerPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
JPanel paramsPane = initParamsPane();
centerPane.add(paramsPane);
//参数
JPanel centerPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
JPanel paramsPane = initParamsPane();
centerPane.add(paramsPane);
this.add(northPane, BorderLayout.NORTH);
this.add(centerPane, BorderLayout.CENTER);
}
this.add(northPane, BorderLayout.NORTH);
this.add(centerPane, BorderLayout.CENTER);
}
private JPanel initParamsPane() {
UILabel parameterLabel = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Export_JS_Parameters_Setting") + ':');
extendParametersCheckBox = new UICheckBox(Toolkit.i18nText("Fine-Design_Basic_Export_JS_Extend_Parameters"));
extendParametersCheckBox.setSelected(true);
parameterViewPane = new ReportletParameterViewPane(getChartParaType(), getValueEditorPane(), getValueEditorPane());
parameterViewPane.setVisible(false);
addListener(parameterViewPane);
extendParametersCheckBox.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
parameterViewPane.setVisible(e.getStateChange() == ItemEvent.DESELECTED);
}
});
JPanel paramsPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
Component[][] components = new Component[][]{{parameterLabel, extendParametersCheckBox}};
JPanel paramsCheckPane = TableLayoutHelper.createTableLayoutPane(components, new double[]{p}, new double[]{p, p});
paramsCheckPane.setBorder(BorderFactory.createEmptyBorder(0, 2, 5, 2));
JPanel dynamicPaneWrapper = FRGUIPaneFactory.createBorderLayout_S_Pane();
dynamicPaneWrapper.add(parameterViewPane);
paramsPane.add(paramsCheckPane, BorderLayout.NORTH);
paramsPane.add(dynamicPaneWrapper, BorderLayout.CENTER);
return paramsPane;
}
private JPanel initParamsPane() {
extendParametersCheckBox = new UICheckBox(Toolkit.i18nText("Fine-Design_Basic_Hyperlink_Extends_Report_Parameters"));
extendParametersCheckBox.setSelected(true);
parameterViewPane = new ReportletParameterViewPane(getChartParaType(), getValueEditorPane(), getValueEditorPane());
parameterViewPane.setVisible(false);
parameterViewPane.addTableEditorListener(new TableModelListener() {
public void tableChanged(TableModelEvent e) {
List<ParameterProvider> list = parameterViewPane.update();
HashSet<String> tempSet = new HashSet<>();
for (int i = 0; i < list.size(); i++) {
if (StringUtils.isEmpty(list.get(i).getName())) {
continue;
private JPanel initFileNamePane() {
UILabel nameLabel = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Export_JS_Filename") + ":");
fileNameRadioGroup = new ExportRadioGroup();
defaultNameRadio = new UIRadioButton(Toolkit.i18nText("Fine-Design_Basic_Export_JS_Filename_Default"));
defaultNameRadio.setSelected(true);
customNameRadio = new UIRadioButton(Toolkit.i18nText("Fine-Design_Basic_Export_JS_Custom"));
addRadioToGroup(fileNameRadioGroup, defaultNameRadio, customNameRadio);
fileNameFormulaEditor = new FormulaEditor(Toolkit.i18nText("Fine-Design_Report_Parameter_Formula"));
fileNameFormulaEditor.setVisible(false);
fileNameFormulaEditor.setEnabled(false);
UILabel fileNameTipLabel = new UILabel("<html><body style=\"color:rgb(147,147,147)\">" + Toolkit.i18nText("Fine-Design_Basic_Export_JS_Title_Tip_Front") + "\\/:*?\"<>|" + Toolkit.i18nText("Fine-Design_Basic_Export_JS_Title_Tip_Back") + "</html>");
fileNameTipLabel.setVisible(false);
fileNameRadioGroup.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (defaultNameRadio.isSelected()) {
fileNameFormulaEditor.setVisible(false);
fileNameFormulaEditor.setEnabled(false);
fileNameTipLabel.setVisible(false);
} else {
fileNameFormulaEditor.setVisible(true);
fileNameFormulaEditor.setEnabled(true);
fileNameTipLabel.setVisible(true);
}
if (tempSet.contains(list.get(i).toString())) {
list.remove(i);
FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Parameter_Duplicate_Name") + "!");
return;
}
tempSet.add(list.get(i).toString());
}
});
Component[][] components = new Component[][]{{nameLabel, defaultNameRadio, customNameRadio, fileNameFormulaEditor}};
JPanel fileNameRadioPane = TableLayoutHelper.createTableLayoutPane(components, new double[]{p}, new double[]{p, p, p, p});
JPanel fileNameTipPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
fileNameTipPane.add(fileNameTipLabel);
JPanel fileNamePane = FRGUIPaneFactory.createBorderLayout_S_Pane();
fileNamePane.add(fileNameRadioPane, BorderLayout.NORTH);
fileNamePane.add(fileNameTipPane, BorderLayout.CENTER);
fileNameTipPane.setBorder(BorderFactory.createEmptyBorder(5, 2, 5, 2));
fileNamePane.setBorder(BorderFactory.createEmptyBorder(5, 2, 5, 2));
return fileNamePane;
}
@Override
protected String title4PopupWindow() {
return Toolkit.i18nText("Fine-Design_Basic_Export_JS_Setting");
}
}
// 其他模板
class OtherTemplatePane extends BasicPane {
private UITableEditorPane<SingleJavaScript> editorPane;
public OtherTemplatePane() {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
this.setBorder(UITitledBorder.createBorderWithTitle(Toolkit.i18nText("Fine-Design_Basic_Export_JS_Template_Other")));
editorPane = new UITableEditorPane<>(new ExportJSTableModel());
this.add(editorPane, BorderLayout.CENTER);
}
@Override
protected String title4PopupWindow() {
return Toolkit.i18nText("Fine-Design_Basic_Export_JS_Setting");
}
}
class ExportJSTableModel extends UITableModelAdapter<SingleJavaScript> {
private static final long serialVersionUID = -3697206557955735642L;
public ExportJSTableModel() {
super(new String[]{
Toolkit.i18nText("Fine-Design_Basic_Export_JS_Template_File"),
Toolkit.i18nText("Fine-Design_Basic_Export_JS_Type"),
Toolkit.i18nText("Fine-Design_Basic_Export_JS_Filename"),
Toolkit.i18nText("Fine-Design_Basic_Export_JS_Filename_Custom"),
Toolkit.i18nText("Fine-Design_Basic_Export_JS_Parameters_Setting"),
StringUtils.EMPTY});
this.setColumnClass(new Class[]{
ExportTemplateChooser.class,
ExportTypeCombobox.class,
FileNameCombobox.class,
FileNameFormulaEditor.class,
ParameterCombobox.class,
ParameterSettingButton.class
});
this.setDefaultEditor(ExportTemplateChooser.class, new ExportTemplateChooser());
this.setDefaultEditor(ExportTypeCombobox.class, new ExportTypeCombobox());
this.setDefaultEditor(FileNameCombobox.class, new FileNameCombobox());
this.setDefaultEditor(FileNameFormulaEditor.class, new FileNameFormulaEditor());
this.setDefaultEditor(ParameterCombobox.class, new ParameterCombobox());
this.setDefaultEditor(ParameterSettingButton.class, new ParameterSettingButton());
this.createTable().getColumnModel().getColumn(2).setMaxWidth(60);
this.createTable().getColumnModel().getColumn(4).setMaxWidth(60);
this.createTable().getColumnModel().getColumn(5).setMaxWidth(40);
}
@Override
public UITableEditAction[] createAction() {
return new UITableEditAction[] {new AddJSAction(), new DeleteAction()};
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
SingleJavaScript js = this.getList().get(rowIndex);
switch (columnIndex) {
case 0:
return js.getTemplatePath();
case 1:
return EXPORT_TYPES_MAP.get(js.getExportType());
case 2:
return js.isDefaultFileName() ? Toolkit.i18nText("Fine-Design_Basic_Export_JS_Filename_Default") : Toolkit.i18nText("Fine-Design_Basic_Export_JS_Custom");
case 3:
return js.getFileName();
case 4:
return js.isExtendParameters() ? Toolkit.i18nText("Fine-Design_Basic_Export_JS_Extend_Parameters") : Toolkit.i18nText("Fine-Design_Basic_Export_JS_Custom");
case 5:
return js.getParameters();
}
});
extendParametersCheckBox.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
parameterViewPane.setVisible(e.getStateChange() == ItemEvent.DESELECTED);
return null;
}
@Override
public boolean isCellEditable(int row, int col) {
if(col == 3) {
// 命名详情
return this.getList().get(row) != null && !this.getList().get(row).isDefaultFileName();
}
if (col == 5) {
// 参数设置按钮
return this.getList().get(row) != null && !this.getList().get(row).isExtendParameters();
}
return true;
}
private class AddJSAction extends AddTableRowAction {
public AddJSAction() {
}
});
JPanel paramsPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
paramsPane.setBorder(BorderFactory.createTitledBorder(new ModLineBorder(ModLineBorder.TOP), Toolkit.i18nText("Fine-Design_Basic_Parameters")));
paramsPane.add(extendParametersCheckBox, BorderLayout.NORTH);
JPanel dynamicPaneWrapper = FRGUIPaneFactory.createBorderLayout_S_Pane();
dynamicPaneWrapper.add(parameterViewPane);
paramsPane.add(dynamicPaneWrapper, BorderLayout.CENTER);
return paramsPane;
}
private JPanel initFileNamePane() {
UILabel nameLabel = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Export_JS_Filename") + ":");
fileNameRadioGroup = new ExportRadioGroup();
defaultNameRadio = new UIRadioButton(Toolkit.i18nText("Fine-Design_Basic_Export_JS_Filename_Default"));
defaultNameRadio.setSelected(true);
customNameRadio = new UIRadioButton(Toolkit.i18nText("Fine-Design_Basic_Export_JS_Filename_Custom"));
addRadioToGroup(fileNameRadioGroup, defaultNameRadio, customNameRadio);
fileNameFormulaEditor = new FormulaEditor(Toolkit.i18nText("Fine-Design_Report_Parameter_Formula"));
fileNameFormulaEditor.setEnabled(false);
fileNameRadioGroup.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (defaultNameRadio.isSelected()) {
fileNameFormulaEditor.setEnabled(false);
super.actionPerformed(e);
if (otherTemplatePane.editorPane.getTableModel().getList().size() <= 50) {
addJS();
} else {
fileNameFormulaEditor.setEnabled(true);
FineJOptionPane.showMessageDialog(otherTemplatePane, Toolkit.i18nText("Fine-Design_Basic_Export_JS_Batch_Export_Limit"));
}
}
});
Component[][] components = new Component[][]{{nameLabel, defaultNameRadio, customNameRadio, fileNameFormulaEditor}};
JPanel fileNameRadioPane = TableLayoutHelper.createTableLayoutPane(components, new double[]{p}, new double[]{p, p, p, p});
JPanel fileNameTipPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
UILabel fileNameTipLabel = new UILabel("<html><body style=\"color:red\">" + Toolkit.i18nText("Fine-Design_Basic_Export_JS_Title_Tip_Front") + "\\/:*?\"<>|" + Toolkit.i18nText("Fine-Design_Basic_Export_JS_Title_Tip_Back") + "</html>");
fileNameTipPane.add(fileNameTipLabel);
JPanel fileNamePane = FRGUIPaneFactory.createBorderLayout_S_Pane();
fileNamePane.add(fileNameRadioPane, BorderLayout.NORTH);
fileNamePane.add(fileNameTipPane, BorderLayout.CENTER);
fileNameTipPane.setBorder(BorderFactory.createEmptyBorder(5,2,5,2));
fileNamePane.setBorder(BorderFactory.createEmptyBorder(5,2,5,2));
return fileNamePane;
}
}
private JPanel initExportTypePane() {
UILabel typeLabel = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Export_JS_Type") + ":");
exportTypeComboBox = new UIComboBox(new DefaultComboBoxModel<String>());
DefaultComboBoxModel<String> comboBoxModel = (DefaultComboBoxModel<String>) exportTypeComboBox.getModel();
String[] allExportTypes = new String[]{ExportJavaScript.EXPORT_PDF, ExportJavaScript.EXPORT_EXCEL_PAGE, ExportJavaScript.EXPORT_EXCEL_SIMPLE, ExportJavaScript.EXPORT_EXCEL_SHEET, ExportJavaScript.EXPORT_WORD, ExportJavaScript.EXPORT_IMAGE};
for (int i = 0; i < allExportTypes.length; i++) {
comboBoxModel.addElement(allExportTypes[i]);
private void addJS() {
SingleJavaScript js = new SingleJavaScript();
addRow(js);
fireTableDataChanged();
table.getSelectionModel().setSelectionInterval(table.getRowCount() - 1, table.getRowCount() - 1);
}
this.exportTypeComboBox.setRenderer(new UIComboBoxRenderer() {
// 导出文件选择
class ExportTemplateChooser extends AbstractCellEditor implements TableCellEditor {
private static final long serialVersionUID = -9112506131272704717L;
private JPanel reportletNamePane;
private UITextField reportPathTextField;
private UIButton browserButton;
public ExportTemplateChooser() {
reportletNamePane = FRGUIPaneFactory.createBorderLayout_S_Pane();
// 路径输入框
reportPathTextField = new UITextField(7);
reportPathTextField.setEnabled(false);
reportletNamePane.add(reportPathTextField, BorderLayout.WEST);
// 选择路径按钮
browserButton = new UIButton("...");
browserButton.setVisible(true);
reportletNamePane.add(browserButton, BorderLayout.EAST);
browserButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent evt) {
final ReportletPane reportletPane = new ReportletPane();
reportletPane.setSelectedReportletPath(reportPathTextField.getText());
BasicDialog reportletDialog = reportletPane.showWindow(SwingUtilities.getWindowAncestor(ExportJavaScriptPane.this));
reportletDialog.addDialogActionListener(new DialogActionAdapter() {
@Override
public void doOk() {
reportPathTextField.setText(reportletPane.getSelectedReportletPath());
}
});
reportletDialog.setVisible(true);
}
});
this.addCellEditorListener(new CellEditorListener() {
@Override
public void editingCanceled(ChangeEvent e) {
}
@Override
public void editingStopped(ChangeEvent e) {
if (table.getSelectedRow() == -1){
return;
}
SingleJavaScript js = getList().get(table.getSelectedRow());
String value = StringUtils.trimToNull(reportPathTextField.getText());
js.setTemplatePath(value);
js.setCurrentTemplate(false);
fireTableDataChanged();
}
});
}
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (value instanceof String) {
this.setText(EXPORT_TYPES_MAP.get(value));
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
reportPathTextField.setText((String) value);
return reportletNamePane;
}
@Override
public Object getCellEditorValue() {
return reportPathTextField.getText();
}
}
// 导出方式下拉框
class ExportTypeCombobox extends AbstractCellEditor implements TableCellEditor {
private static final long serialVersionUID = -6564079764032351372L;
public ExportTypeCombobox() {
exportTypeComboBox = getComboBoxWithModel(new String[]{ExportJavaScript.EXPORT_PDF, ExportJavaScript.EXPORT_EXCEL_PAGE, ExportJavaScript.EXPORT_EXCEL_SIMPLE, ExportJavaScript.EXPORT_EXCEL_SHEET, ExportJavaScript.EXPORT_WORD, ExportJavaScript.EXPORT_IMAGE}
, EXPORT_TYPES_MAP);
this.addCellEditorListener(new CellEditorListener() {
@Override
public void editingCanceled(ChangeEvent e) {
}
@Override
public void editingStopped(ChangeEvent e) {
if (table.getSelectedRow() == -1){
return;
}
SingleJavaScript js = getList().get(table.getSelectedRow());
Object ob = exportTypeComboBox.getSelectedItem();
if (ob != null) {
String value = ob.toString();
js.setExportType(value);
}
fireTableDataChanged();
}
});
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
exportTypeComboBox.setSelectedItem(value);
return exportTypeComboBox;
}
@Override
public Object getCellEditorValue() {
Object ob = exportTypeComboBox.getSelectedItem();
if (ob != null) {
return ob.toString();
}
return this;
return ExportJavaScript.EXPORT_PDF;
}
});
}
// 命名方式下拉框
class FileNameCombobox extends AbstractCellEditor implements TableCellEditor {
private static final long serialVersionUID = 1829005772744444269L;
private UIComboBox fileNameComboBox;
public FileNameCombobox() {
fileNameComboBox = getComboBoxWithModel(new String[]{DEFAULT, CUSTOM}, FILENAME_TYPE_MAP);
this.addCellEditorListener(new CellEditorListener() {
@Override
public void editingCanceled(ChangeEvent e) {
}
@Override
public void editingStopped(ChangeEvent e) {
if (table.getSelectedRow() == -1){
return;
}
SingleJavaScript js = getList().get(table.getSelectedRow());
Object ob = fileNameComboBox.getSelectedItem();
if (ob != null) {
String value = ob.toString();
js.setDefaultFileName(StringUtils.equals(value, DEFAULT));
}
fireTableDataChanged();
}
});
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
fileNameComboBox.setSelectedItem(value);
return fileNameComboBox;
}
@Override
public Object getCellEditorValue() {
return fileNameComboBox.getSelectedItem().toString();
}
}
// 命名方式公式框
class FileNameFormulaEditor extends AbstractCellEditor implements TableCellEditor {
private static final long serialVersionUID = 7120075192535645493L;
private FormulaEditor fileNameFormulaEditor;
public FileNameFormulaEditor() {
fileNameFormulaEditor = new FormulaEditor(Toolkit.i18nText("Fine-Design_Report_Parameter_Formula"));
this.addCellEditorListener(new CellEditorListener() {
@Override
public void editingCanceled(ChangeEvent e) {
}
@Override
public void editingStopped(ChangeEvent e) {
if (table.getSelectedRow() == -1){
return;
}
SingleJavaScript js = getList().get(table.getSelectedRow());
String value = fileNameFormulaEditor.getUITextField().getText();
js.setFileName(value);
fireTableDataChanged();
}
});
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
fileNameFormulaEditor.setValue(BaseFormula.createFormulaBuilder().build());
return fileNameFormulaEditor;
}
@Override
public Object getCellEditorValue() {
return fileNameFormulaEditor.getUITextField().getText();
}
public FormulaEditor getFileNameEditor() {
return fileNameFormulaEditor;
}
}
//参数设置下拉框
class ParameterCombobox extends AbstractCellEditor implements TableCellEditor {
private static final long serialVersionUID = 2630964402770993584L;
private UIComboBox parameterSetting;
public ParameterCombobox() {
parameterSetting = getComboBoxWithModel(new String[]{DEFAULT, CUSTOM}, PARAMETER_TYPE_MAP);
this.addCellEditorListener(new CellEditorListener() {
@Override
public void editingCanceled(ChangeEvent e) {
}
@Override
public void editingStopped(ChangeEvent e) {
if (table.getSelectedRow() == -1){
return;
}
SingleJavaScript js = getList().get(table.getSelectedRow());
Object ob = parameterSetting.getSelectedItem();
if (ob != null) {
String value = ob.toString();
js.setExtendParameters(StringUtils.equals(value, DEFAULT));
}
fireTableDataChanged();
}
});
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
parameterSetting.setSelectedItem(value);
return parameterSetting;
}
@Override
public Object getCellEditorValue() {
return parameterSetting.getSelectedItem().toString();
}
}
// 参数设置按钮
class ParameterSettingButton extends AbstractCellEditor implements TableCellEditor {
private static final long serialVersionUID = 4021592871993049137L;
private UIButton paraButton;
private ParameterSettingPane paraSettingPane;
ParameterProvider[] parameterArr;
public ParameterSettingButton() {
paraSettingPane = new ParameterSettingPane();
paraButton = new UIButton();
paraButton.setBackground(Color.GRAY);
paraButton.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
BasicDialog dialog = paraSettingPane.showWindow(SwingUtilities.getWindowAncestor(ExportJavaScriptPane.this));
dialog.addDialogActionListener(new DialogActionAdapter() {
@Override
public void doOk() {
List<ParameterProvider> parameterList = paraSettingPane.getParameterList();
parameterArr = parameterList.toArray(new Parameter[parameterList.size()]);
}
});
dialog.setVisible(true);
}
});
this.addCellEditorListener(new CellEditorListener() {
@Override
public void editingCanceled(ChangeEvent e) {
}
@Override
public void editingStopped(ChangeEvent e) {
if (table.getSelectedRow() == -1){
return;
}
SingleJavaScript js = getList().get(table.getSelectedRow());
js.setParameters(parameterArr);
fireTableDataChanged();
}
});
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
paraSettingPane.refresh(new ArrayList<>(Arrays.asList((ParameterProvider[]) value)));
return paraButton;
}
@Override
public Object getCellEditorValue() {
return paraSettingPane.getParameterList();
}
}
// 参数设置弹出框
class ParameterSettingPane extends BasicPane {
private ReportletParameterViewPane parameterViewPane;
public ParameterSettingPane() {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
parameterViewPane = new ReportletParameterViewPane(ParameterTableModel.NO_CHART_USE, getValueEditorPane(), getValueEditorPane());
addListener(parameterViewPane);
this.add(parameterViewPane);
}
@Override
protected String title4PopupWindow() {
return Toolkit.i18nText("Fine-Design_Basic_Export_JS_Parameters_Setting");
}
public List<ParameterProvider> getParameterList() {
return parameterViewPane.update();
}
public void refresh(List list) {
parameterViewPane.update(list);
}
}
}
public ExportJavaScriptPane() {
initComponents();
}
private void initComponents() {
JPanel totalPanel = FRGUIPaneFactory.createBorderLayout_S_Pane();
totalPanel.setBorder(UITitledBorder.createBorderWithTitle(Toolkit.i18nText("Fine-Design_Basic_Export_JS_Setting")));
// 导出模板
JPanel northPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
JPanel chooseTemplatePane = initChooseTemplatePane();
northPane.add(chooseTemplatePane, BorderLayout.NORTH);
// 默认当前模板
currentTemplatePane = new CurrentTemplatePane();
otherTemplatePane = new OtherTemplatePane();
templatePanel = FRGUIPaneFactory.createCardLayout_S_Pane();
card = new CardLayout();
templatePanel.setLayout(card);
templatePanel.add(CURRENT_TEMPLATE, currentTemplatePane);
templatePanel.add(OTHER_TEMPLATE, otherTemplatePane);
totalPanel.add(northPane, BorderLayout.NORTH);
totalPanel.add(templatePanel, BorderLayout.CENTER);
this.setLayout(FRGUIPaneFactory.createBorderLayout());
this.add(totalPanel);
}
private JPanel initExportTypePane() {
UILabel typeLabel = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Export_JS_Type") + ":");
exportTypeComboBox = getComboBoxWithModel(new String[]{ExportJavaScript.EXPORT_PDF, ExportJavaScript.EXPORT_EXCEL_PAGE, ExportJavaScript.EXPORT_EXCEL_SIMPLE, ExportJavaScript.EXPORT_EXCEL_SHEET, ExportJavaScript.EXPORT_WORD, ExportJavaScript.EXPORT_IMAGE}
, EXPORT_TYPES_MAP);
Component[][] components = new Component[][]{{typeLabel, exportTypeComboBox}};
JPanel exportTypePane = TableLayoutHelper.createTableLayoutPane(components, new double[]{p}, new double[]{p, p});
exportTypePane.setBorder(BorderFactory.createEmptyBorder(5,2,5,2));
exportTypePane.setBorder(BorderFactory.createEmptyBorder(5, 2, 5, 2));
return exportTypePane;
}
@ -220,51 +699,28 @@ public class ExportJavaScriptPane extends AbstractHyperLinkPane<ExportJavaScript
currentTemplateRadio.setSelected(true);
otherTemplateRadio = new UIRadioButton(Toolkit.i18nText("Fine-Design_Basic_Export_JS_Template_Other"));
addRadioToGroup(templateRadioGroup, currentTemplateRadio, otherTemplateRadio);
templateRadioGroup.addActionListener(new ActionListener() {
currentTemplateRadio.addItemListener(new ItemListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (currentTemplateRadio.isSelected()) {
browserButton.setEnabled(false);
} else {
browserButton.setEnabled(true);
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
card.show(templatePanel, CURRENT_TEMPLATE);
}
}
});
Component[][] components = new Component[][]{{templateLabel, currentTemplateRadio, otherTemplateRadio}};
JPanel reportletRadioPane = TableLayoutHelper.createTableLayoutPane(components, new double[]{p}, new double[]{p, p, p});
JPanel reportletNamePane = FRGUIPaneFactory.createBorderLayout_S_Pane();
// 路径输入框
reportPathTextField = new UITextField(20);
reportPathTextField.setEnabled(false);
reportletNamePane.add(reportPathTextField, BorderLayout.CENTER);
// 选择路径按钮
browserButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Select"));
browserButton.setPreferredSize(new Dimension(browserButton.getPreferredSize().width, 20));
browserButton.setEnabled(false);
reportletNamePane.add(browserButton, BorderLayout.EAST);
browserButton.addActionListener(new ActionListener() {
otherTemplateRadio.addItemListener(new ItemListener() {
@Override
public void actionPerformed(ActionEvent evt) {
final ReportletPane reportletPane = new ReportletPane();
reportletPane.setSelectedReportletPath(reportPathTextField.getText());
BasicDialog reportletDialog = reportletPane.showWindow(SwingUtilities.getWindowAncestor(ExportJavaScriptPane.this));
reportletDialog.addDialogActionListener(new DialogActionAdapter() {
@Override
public void doOk() {
reportPathTextField.setText(reportletPane.getSelectedReportletPath());
}
});
reportletDialog.setVisible(true);
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
card.show(templatePanel, OTHER_TEMPLATE);
}
}
});
Component[][] components = new Component[][]{{templateLabel, currentTemplateRadio, otherTemplateRadio}};
JPanel reportletRadioPane = TableLayoutHelper.createTableLayoutPane(components, new double[]{p}, new double[]{p, p, p});
JPanel chooseTemplatePane = FRGUIPaneFactory.createBorderLayout_S_Pane();
JPanel chooseTemplatePane = FRGUIPaneFactory.createLeftFlowZeroGapBorderPane();
chooseTemplatePane.add(reportletRadioPane, BorderLayout.NORTH);
chooseTemplatePane.add(reportletNamePane, BorderLayout.CENTER);
chooseTemplatePane.setBorder(BorderFactory.createEmptyBorder(0,2,5,2));
chooseTemplatePane.setBorder(BorderFactory.createEmptyBorder(0, 7, 5, 2));
return chooseTemplatePane;
}
@ -276,27 +732,26 @@ public class ExportJavaScriptPane extends AbstractHyperLinkPane<ExportJavaScript
}
this.templateRadioGroup.selectIndexButton(ob.isCurrentTemplate() ? 0 : 1);
if (ob.isCurrentTemplate()) {
this.browserButton.setEnabled(false);
} else {
this.browserButton.setEnabled(true);
this.reportPathTextField.setText(ob.getTemplatePath());
}
this.exportTypeComboBox.setSelectedItem(ob.getExportType());
this.fileNameRadioGroup.selectIndexButton(ob.isDefaultFileName() ? 0 : 1);
if (ob.isDefaultFileName()) {
this.fileNameFormulaEditor.setEnabled(false);
} else {
this.fileNameFormulaEditor.setEnabled(true);
this.fileNameFormulaEditor.setValue(BaseFormula.createFormulaBuilder().build(ob.getFileName()));
}
if (ob.isExtendParameters()) {
this.extendParametersCheckBox.setSelected(true);
SingleJavaScript js = ob.getJavaScript();
exportTypeComboBox.setSelectedItem(js.getExportType());
currentTemplatePane.fileNameRadioGroup.selectIndexButton(js.isDefaultFileName() ? 0 : 1);
if (!js.isDefaultFileName()) {
currentTemplatePane.fileNameFormulaEditor.setEnabled(true);
currentTemplatePane.fileNameFormulaEditor.setVisible(true);
currentTemplatePane.fileNameFormulaEditor.setValue(BaseFormula.createFormulaBuilder().build(js.getFileName()));
}
if (js.isExtendParameters()) {
currentTemplatePane.extendParametersCheckBox.setSelected(true);
} else {
currentTemplatePane.extendParametersCheckBox.setSelected(false);
List<ParameterProvider> parameterList = this.parameterViewPane.update();
parameterList.clear();
ParameterProvider[] parameters = js.getParameters();
this.parameterViewPane.populate(parameters);
}
} else {
this.extendParametersCheckBox.setSelected(false);
List<ParameterProvider> parameterList = this.parameterViewPane.update();
parameterList.clear();
ParameterProvider[] parameters = ob.getParameters();
this.parameterViewPane.populate(parameters);
OtherTemplatePane pane = (OtherTemplatePane) this.templatePanel.getComponent(1);
pane.editorPane.populate(ob.getJsList().toArray(new SingleJavaScript[ob.getJsList().size()]));
}
}
@ -309,32 +764,78 @@ public class ExportJavaScriptPane extends AbstractHyperLinkPane<ExportJavaScript
@Override
public void updateBean(ExportJavaScript exportJavaScript) {
exportJavaScript.setCurrentTemplate(this.currentTemplateRadio.isSelected());
exportJavaScript.setTemplatePath(getTemplatePath());
exportJavaScript.setExportType(GeneralUtils.objectToString(this.exportTypeComboBox.getSelectedItem()));
exportJavaScript.setDefaultFileName(this.defaultNameRadio.isSelected());
exportJavaScript.setFileName(getFileName());
exportJavaScript.setExtendParameters(this.extendParametersCheckBox.isSelected());
if (extendParametersCheckBox.isSelected()) {
exportJavaScript.setParameters(null);
boolean selected = currentTemplateRadio.isSelected();
exportJavaScript.setCurrentTemplate(selected);
if (selected) {
SingleJavaScript js = new SingleJavaScript();
js.setCurrentTemplate(true);
js.setTemplatePath(DEFAULT);
js.setExportType(GeneralUtils.objectToString(exportTypeComboBox.getSelectedItem()));
js.setDefaultFileName(currentTemplatePane.defaultNameRadio.isSelected());
js.setFileName(getFileName());
js.setExtendParameters(currentTemplatePane.extendParametersCheckBox.isSelected());
if (currentTemplatePane.extendParametersCheckBox.isSelected()) {
exportJavaScript.setParameters(null);
} else {
List<ParameterProvider> parameterList = parameterViewPane.update();
if (!parameterList.isEmpty()) {
Parameter[] parameters = new Parameter[parameterList.size()];
parameterList.toArray(parameters);
js.setParameters(parameters);
}
}
exportJavaScript.addJS(js);
} else {
List<ParameterProvider> parameterList = this.parameterViewPane.update();
if (!parameterList.isEmpty()) {
Parameter[] parameters = new Parameter[parameterList.size()];
parameterList.toArray(parameters);
exportJavaScript.setParameters(parameters);
List<SingleJavaScript> javaScripts = otherTemplatePane.editorPane.update();
for (SingleJavaScript js : javaScripts) {
exportJavaScript.addJS(js);
}
}
}
private String getTemplatePath() {
return currentTemplateRadio.isSelected() ? CURRENT_TEMPLATE : reportPathTextField.getText();
private String getFileName() {
return currentTemplatePane.defaultNameRadio.isSelected() ? DEFAULT : currentTemplatePane.fileNameFormulaEditor.getUITextField().getText();
}
private String getFileName() {
return defaultNameRadio.isSelected() ? DEFAULT_FILENAME : fileNameFormulaEditor.getUITextField().getText();
private UIComboBox getComboBoxWithModel(String[] itemTextArr, Map<String, String> itemTextDic) {
UIComboBox comboBox = new UIComboBox(new DefaultComboBoxModel<String>());
DefaultComboBoxModel<String> comboBoxModel = (DefaultComboBoxModel<String>) comboBox.getModel();
for (int i = 0; i < itemTextArr.length; i++) {
comboBoxModel.addElement(itemTextArr[i]);
}
comboBox.setRenderer(new UIComboBoxRenderer() {
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (value instanceof String) {
this.setText(itemTextDic.get(value));
}
return this;
}
});
return comboBox;
}
private void addListener(ReportletParameterViewPane paraPane) {
paraPane.addTableEditorListener(new TableModelListener() {
public void tableChanged(TableModelEvent e) {
List<ParameterProvider> list = paraPane.update();
HashSet<String> tempSet = new HashSet<>();
for (int i = 0; i < list.size(); i++) {
if (StringUtils.isEmpty(list.get(i).getName())) {
continue;
}
if (tempSet.contains(list.get(i).toString())) {
list.remove(i);
FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Design_Basic_Parameter_Duplicate_Name") + "!");
return;
}
tempSet.add(list.get(i).toString());
}
}
});
}
@Override
public boolean accept(Object ob) {

9
designer-base/src/main/java/com/fr/design/login/service/DesignerPassportManager.java

@ -5,6 +5,7 @@ import com.fr.design.login.DesignerLoginType;
import com.fr.design.upm.event.CertificateEvent;
import com.fr.event.EventDispatcher;
import com.fr.json.JSONObject;
import com.fr.stable.StringUtils;
/**
* @author Lanlan
@ -96,6 +97,14 @@ public class DesignerPassportManager {
return uid;
}
/**
* 登出帆软通行证
*/
public void logout() {
saveUserInfo(-1, StringUtils.EMPTY, StringUtils.EMPTY, StringUtils.EMPTY, DesignerLoginType.UNKNOWN, StringUtils.EMPTY);
EventDispatcher.fire(CertificateEvent.LOGOUT, StringUtils.EMPTY);
}
/**
* 保存登录信息
*/

5
designer-base/src/main/java/com/fr/design/mainframe/DesktopCardPane.java

@ -92,7 +92,7 @@ public class DesktopCardPane extends BasicPane implements TargetModifiedListener
} else if (jt.isOpening()) {
showOpenStatus();
} else if (jt.isOpenFailed()) {
showOpenFailedCover();
showOpenFailedCover(jt.getTemplateOpenFailedTip());
} else {
hideCover();
}
@ -121,7 +121,8 @@ public class DesktopCardPane extends BasicPane implements TargetModifiedListener
layeredPane.moveToFront(loadingPane);
}
public void showOpenFailedCover() {
public void showOpenFailedCover(String text) {
failedPane.setFailedTip(text);
layeredPane.moveToFront(failedPane);
}

1
designer-base/src/main/java/com/fr/design/mainframe/EastRegionContainerPane.java

@ -1005,6 +1005,7 @@ public class EastRegionContainerPane extends UIEastResizableContainer {
button.addActionListener(actionListener);
}
button.setToolTipText(title);
button.setName(name);
}
public void processSnapChat() {

88
designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java

@ -19,7 +19,6 @@ import com.fr.design.ExtraDesignClassManager;
import com.fr.design.actions.TableDataSourceAction;
import com.fr.design.actions.edit.RedoAction;
import com.fr.design.actions.edit.UndoAction;
import com.fr.design.actions.file.BatchCompileAction;
import com.fr.design.actions.file.SaveAsTemplateAction;
import com.fr.design.actions.file.SaveTemplateAction;
import com.fr.design.actions.file.WebPreviewUtils;
@ -68,7 +67,12 @@ import com.fr.form.ui.NoneWidget;
import com.fr.form.ui.Widget;
import com.fr.general.ComparatorUtils;
import com.fr.general.IOUtils;
import com.fr.locale.InterProviderFactory;
import com.fr.log.FineLoggerFactory;
import com.fr.nx.app.designer.utils.CptAndCptxCompatibilityUtil;
import com.fr.nx.app.designer.utils.CptCompileUtil;
import com.fr.nx.cptx.entry.metadata.CptxMetadata;
import com.fr.nx.cptx.utils.CptxFileUtils;
import com.fr.plugin.context.PluginContext;
import com.fr.plugin.context.PluginRuntime;
import com.fr.nx.app.designer.toolbar.CompileAction;
@ -130,6 +134,8 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
private JComponent centerPane;
private DesignModelAdapter<T, ?> designModel;
private PreviewProvider previewType;
private String templateOpenFailedTip;
/**
* 统计模板制作耗时
*
@ -951,7 +957,7 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
}
protected boolean export() throws Exception {
return this.getTarget().export(TemplateResourceManager.getResource().saveTemplate(editingFILE));
return this.getTarget().export(TemplateResourceManager.getResource().saveTemplate(getEditingFILE()));
}
@ -969,7 +975,7 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
} else if (DesignerMode.isAuthorityEditing()) {
return new ShortCut[]{new SaveTemplateAction(this), new UndoAction(this), new RedoAction(this)};
} else {
return new ShortCut[]{new SaveTemplateAction(this), new SaveAsTemplateAction(this), new BatchCompileAction(), new UndoAction(this), new RedoAction(this)};
return new ShortCut[]{new SaveTemplateAction(this), new SaveAsTemplateAction(this), new UndoAction(this), new RedoAction(this)};
}
}
@ -1125,35 +1131,49 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
/**
* 判断是否是新版设计器
*
* @param showTipPane 是否需要展示弹窗
* @return 是返回true
*/
public boolean isNewDesigner() {
public boolean isNewDesigner(boolean showTipPane) {
String xmlDesignerVersion = getTarget().getXMLDesignerVersion();
if (isLowerThanHBB(xmlDesignerVersion)) {
String info = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Open-New_Form_Tip");
String moreInfo = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Server_Version_Tip_More_Info");
new InformationWarnPane(info, moreInfo, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tool_Tips")).show();
if (showTipPane) {
new InformationWarnPane(info, moreInfo, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tool_Tips")).show();
}
return true;
}
return false;
}
public boolean isNewDesigner() {
return isNewDesigner(true);
}
/**
* 是否是就版本设计器
*
* @param showTipPane 是否需要展示弹窗
* @return 是就返回true
*/
public boolean isOldDesigner() {
public boolean isOldDesigner(boolean showTipPane) {
String xmlDesignerVersion = getTarget().getXMLDesignerVersion();
if (isHigherThanCurrent(xmlDesignerVersion)) {
String infor = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Template_Version_Not_Match", DesignUtils.parseVersion(xmlDesignerVersion));
String moreInfo = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Server_Version_Tip_More_Info");
new InformationWarnPane(infor, moreInfo, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tool_Tips")).show();
if (showTipPane) {
new InformationWarnPane(infor, moreInfo, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tool_Tips")).show();
}
return true;
}
return false;
}
public boolean isOldDesigner() {
return isOldDesigner(true);
}
/**
*
*/
@ -1406,9 +1426,7 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
* @return 按钮组
*/
public UIButton[] createExtraButtons() {
UIButton[] uiButtons = new UIButton[]{
(UIButton) new CompileAction().createToolBarComponent()
};
UIButton[] uiButtons = new UIButton[0];
Set<DesignerFrameUpButtonProvider> providers = ExtraDesignClassManager.getInstance().getArray(DesignerFrameUpButtonProvider.XML_TAG);
for (DesignerFrameUpButtonProvider provider : providers) {
uiButtons = ArrayUtils.addAll(uiButtons, provider.getUpButtons(getMenuState()));
@ -1434,6 +1452,7 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
};
button.setToolTipText(getTemplateTheme().getName());
button.setText(getTemplateTheme().getName());
button.setName(getTemplateTheme().getName());
button.setAlignmentX(SwingConstants.LEFT);
button.set4ToolbarButton();
button.setEnabled(true);
@ -1460,7 +1479,27 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
public abstract String route();
public String getTemplateName() {
return getEditingFILE().getName();
return getEditingFILE().getName() + compatibilityTip();
}
/**
* 设置新引擎后有不支持的功能时设计器中模板的标题需要加上兼容模式或者不支持分页引擎来提示用户
* */
private String compatibilityTip() {
if (!CptAndCptxCompatibilityUtil.isEngineXEnable(this.getTarget(), getEditingFILE().getPath())){
return StringUtils.EMPTY;
}
String path = this.getEditingFILE().getPath();
CptxMetadata metadata = CptxFileUtils.getMetadata(path);
//是否是兼容模式,兼容模式下,设置了新引擎的cpt和cptx的后缀不同
if (metadata != null && metadata.isForceCpt()) {
if (path.endsWith(".cptx")){
return InterProviderFactory.getProvider().getLocText("Fine-Plugin_Engine_Compatibility_Mode");
} else if (path.endsWith(".cpt")){
return InterProviderFactory.getProvider().getLocText("Fine-Plugin_Engine_Paging_Engine_Not_Work");
}
}
return StringUtils.EMPTY;
}
public String getTemplatePredefinedStyle() {
@ -1529,6 +1568,8 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
@Override
public void run() {
callBackForSave();
//在保存后的回调中执行预编译流程
CptCompileUtil.compile(JTemplate.this);
}
});
@ -1557,7 +1598,7 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
if (editingFILE == null || editingFILE instanceof MemFILE) {
return false;
}
this.getTarget().export(TemplateResourceManager.getResource().saveTemplate(editingFILE));
export();
this.editingFILE = editingFILE;
return true;
} else {
@ -1599,6 +1640,10 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
worker.addSuccessCallback(new Runnable() {
@Override
public void run() {
boolean isChangedFile = !JTemplate.this.saved;
if (isChangedFile){
CptCompileUtil.compile(JTemplate.this);
}
callBackForSave();
// 当前打开的是正在保存的模板才刷新
if (ComparatorUtils.equals(JTemplate.this.template.getTemplateID(),
@ -1608,7 +1653,6 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
DesignerFrameFileDealerPane.getInstance().refresh();
}
});
return worker;
}
@ -1659,6 +1703,14 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
result = result || provider.saveToNewFile(this.editingFILE.getPath(), this);
}
if (!result) {
/*
* 1.在CptCompileUtil::haveChanged改变报表引擎属性
* 2.在这三种情况下1.cptx文件另存为cpt文件 2.cptx另存为cptx文件 3.设置了新引擎的cpt文件另存为cpt文件
* 因为文件的编译目录改变了需要重新预编译因此设置jTemplate的保存状态为false
* */
if (CptAndCptxCompatibilityUtil.needRecompile(oldName, this)){
this.saved = false;
}
result = this.saveRealFile();
// 更换最近打开
DesignerEnvManager.getEnvManager().replaceRecentOpenedFilePath(oldName, this.getPath());
@ -1741,6 +1793,14 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
themeAttrMark.setDark(theme.isDark());
}
public String getTemplateOpenFailedTip() {
return templateOpenFailedTip;
}
public void setTemplateOpenFailedTip(String templateOpenFailedTip) {
this.templateOpenFailedTip = templateOpenFailedTip;
}
@Override
public void setTemplateTheme(TemplateTheme newTheme, TemplateThemeCompatible compatible) {
ThemedTemplate.super.setTemplateTheme(newTheme, compatible);
@ -1748,4 +1808,4 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
templateThemeButton.setText(name);
templateThemeButton.setToolTipText(name);
}
}
}

1
designer-base/src/main/java/com/fr/design/mainframe/NorthRegionContainerPane.java

@ -116,6 +116,7 @@ public class NorthRegionContainerPane extends JPanel {
if (!DesignerEnvManager.getEnvManager().getAlphaFineConfigManager().isEnabled()) {
ad.createAlphaFinePane().setVisible(false);
}
northEastPane.add(ad.createGuideEntryPane());
northEastPane.add(ad.createNotificationCenterPane());
OSSupportCenter.buildAction(new OSBasedAction() {

10
designer-base/src/main/java/com/fr/design/mainframe/OpenFailedPane.java

@ -24,6 +24,7 @@ public class OpenFailedPane extends JPanel {
private UILabel label;
private MessageWithLink link;
private String defaultFailedText;
public OpenFailedPane() {
this.setLayout(new LayoutManager() {
@ -83,11 +84,18 @@ public class OpenFailedPane extends JPanel {
});
}
};
this.defaultFailedText = link.getText();
link.setBackground(Color.WHITE);
this.add(label);
this.add(link);
}
public void setFailedTip(String text) {
if (StringUtils.isEmpty(text)) {
this.link.setText(defaultFailedText);
} else {
this.link.setText(text);
}
}
}

189
designer-base/src/main/java/com/fr/design/mainframe/guide/base/Guide.java

@ -0,0 +1,189 @@
package com.fr.design.mainframe.guide.base;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.guide.collect.GuideCollector;
import com.fr.design.mainframe.guide.scene.GuideScene;
import com.fr.design.mainframe.guide.ui.GuideCompleteDialog;
import com.fr.design.mainframe.guide.ui.GuideManageDialog;
import com.fr.stable.StringUtils;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
public class Guide {
private String id;
private String name;
private String description;
private String completeMessage;
private GuideView guideView;
private GuideLifecycle lifecycle;
private boolean isComplete;
private GuideScene scene;
public Guide() {
this(null, null, null);
}
public Guide(String id, String name, String description) {
this.id = id;
this.name = name;
this.description = description;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setDescription(String description) {
this.description = description;
}
public String getDescription() {
if (StringUtils.isNotEmpty(description)) {
return description;
}
return name;
}
public String getCompleteMessage() {
return completeMessage;
}
public void setCompleteMessage(String completeMessage) {
this.completeMessage = completeMessage;
}
public void setGuideView(GuideView guideView) {
this.guideView = guideView;
}
public GuideView getGuideView() {
return guideView;
}
public void setComplete(boolean complete) {
isComplete = complete;
}
public boolean isComplete() {
return isComplete;
}
public void setScene(GuideScene scene) {
this.scene = scene;
}
public GuideScene getScene() {
return scene;
}
/**
* 开启引导流程
*/
public void go() {
DesignerContext.getDesignerFrame().setExtendedState(JFrame.MAXIMIZED_BOTH);
// 同时只能启动一个引导
if (GuideManager.getInstance().getCurrentGuide() != null) {
return;
}
GuideManager.getInstance().setCurrentGuide(this);
guideView.showLoading();
new SwingWorker<Boolean, Void>() {
@Override
protected Boolean doInBackground() {
try {
if (lifecycle != null && !lifecycle.prepared()) {
return false;
}
return true;
} catch (Exception e) {
e.printStackTrace();
guideView.hideLoading();
terminate();
return false;
}
}
@Override
protected void done() {
try {
if (get()) {
start();
}
} catch (Exception e) {
e.printStackTrace();
guideView.hideLoading();
terminate();
}
}
}.execute();
}
public void start() {
guideView.hideLoading();
if (scene != null) {
guideView.setScene(scene);
guideView.showGuide();
if (lifecycle != null) {
lifecycle.onStart();
}
} else {
complete();
}
}
public void complete() {
if (lifecycle != null) {
lifecycle.onComplete();
}
setComplete(true);
GuideCollector.getInstance().saveInfo();
guideView.dismissGuide();
GuideCompleteDialog.getInstance().showDialog(getCompleteMessage());
end();
}
public void terminate() {
if (lifecycle != null) {
lifecycle.onTerminate();
}
end();
}
public void end() {
guideView.dismissGuide();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
if (lifecycle != null) {
lifecycle.onEnd();
}
GuideManager.getInstance().setCurrentGuide(null);
GuideManageDialog.getInstance().showDialog();
}
});
}
public void registerLifecycle(GuideLifecycle lifecycle) {
this.lifecycle = lifecycle;
}
public void removeGuideLifecycle() {
this.lifecycle = null;
}
}

51
designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideBuilder.java

@ -0,0 +1,51 @@
package com.fr.design.mainframe.guide.base;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.guide.scene.GuideScene;
public class GuideBuilder {
private Guide guide;
public static GuideBuilder newInstance() {
return new GuideBuilder();
}
public GuideBuilder() {
guide = new Guide();
guide.setGuideView(new GuideView(DesignerContext.getDesignerFrame(), guide));
}
public GuideBuilder setID(String id) {
guide.setId(id);
return this;
}
public GuideBuilder setName(String name) {
guide.setName(name);
return this;
}
public GuideBuilder setDescription(String description) {
guide.setDescription(description);
return this;
}
public GuideBuilder setCompleteMessage(String message) {
guide.setCompleteMessage(message);
return this;
}
public GuideBuilder addScene(GuideScene scene) {
guide.setScene(scene);
return this;
}
public GuideBuilder registerLifecycle(GuideLifecycle lifecycle) {
guide.registerLifecycle(lifecycle);
return this;
}
public Guide getGuide() {
return guide;
}
}

55
designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideGroup.java

@ -0,0 +1,55 @@
package com.fr.design.mainframe.guide.base;
import java.util.ArrayList;
import java.util.List;
public class GuideGroup {
private List<Guide> guideList;
private String id;
private String name;
public GuideGroup(String id, String name) {
this.id = id;
this.name = name;
guideList = new ArrayList<>();
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void addGuide(Guide guide) {
guideList.add(guide);
}
public List<Guide> getGuideList() {
return guideList;
}
public List<Guide> getCompleteGuideList() {
List<Guide> complete = new ArrayList<>();
for (Guide guide : getGuideList()) {
if (guide.isComplete()) {
complete.add(guide);
}
}
return complete;
}
public boolean isCompleteAll() {
return getCompleteGuideList().size() == getGuideList().size();
}
public boolean isCompleteSome() {
List<Guide> completeGuides = getCompleteGuideList();
return completeGuides.size() > 0 && completeGuides.size() < getGuideList().size();
}
}

32
designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideLifecycle.java

@ -0,0 +1,32 @@
package com.fr.design.mainframe.guide.base;
public interface GuideLifecycle{
/**
* 准备环境
* @return 返回true引导可继续执行
*/
boolean prepared();
/**
* 开始引导教程
*/
void onStart();
/**
* 完成引导教程
*/
void onComplete();
/**
* 终止引导教程
*/
void onTerminate();
/**
* 结束引导教程
*/
void onEnd();
}

28
designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideLifecycleAdaptor.java

@ -0,0 +1,28 @@
package com.fr.design.mainframe.guide.base;
public abstract class GuideLifecycleAdaptor implements GuideLifecycle{
@Override
public boolean prepared() {
return true;
}
@Override
public void onStart() {
}
@Override
public void onComplete() {
}
@Override
public void onTerminate() {
}
@Override
public void onEnd() {
}
}

113
designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideManager.java

@ -0,0 +1,113 @@
package com.fr.design.mainframe.guide.base;
import com.fr.design.mainframe.guide.collect.GuideCollector;
import com.fr.stable.StringUtils;
import java.util.ArrayList;
import java.util.List;
public class GuideManager {
private static GuideManager guideManager;
private Guide currentGuide;
private List<GuideVersion> guideVersionList;
public static GuideManager getInstance() {
if (guideManager == null) {
guideManager = new GuideManager();
}
return guideManager;
}
public GuideManager() {
guideVersionList = new ArrayList<>();
}
public Guide getCurrentGuide() {
return currentGuide;
}
public void setCurrentGuide(Guide currentGuide) {
this.currentGuide = currentGuide;
}
public void addGuideGroup(String version, GuideGroup guideGroup) {
GuideVersion guideVersion = getGuideVersion(version);
if (guideVersion == null) {
guideVersion = new GuideVersion(version);
guideVersionList.add(guideVersion);
}
guideVersion.addGuideGroup(guideGroup);
}
public void addGuide(String groupId, Guide guide) {
GuideGroup guideGroup = getGuideGroup(groupId);
if (guideGroup != null) {
guideGroup.addGuide(guide);
}
}
public List<GuideVersion> getGuideVersionList() {
return guideVersionList;
}
public List<Guide> getAllGuide() {
List<Guide> guideList = new ArrayList<>();
for (GuideVersion version : guideVersionList) {
for (GuideGroup group : version.getGuideGroupList()) {
for (Guide guide : group.getGuideList()) {
guideList.add(guide);
}
}
}
return guideList;
}
public GuideVersion getGuideVersion(String version) {
for (GuideVersion guideVersion : guideVersionList) {
if (StringUtils.equals(version, guideVersion.getVersion())) {
return guideVersion;
}
}
return null;
}
public GuideGroup getGuideGroup(String groupId) {
for (GuideVersion version : guideVersionList) {
for (GuideGroup group : version.getGuideGroupList()) {
if (StringUtils.equals(groupId, group.getId())) {
return group;
}
}
}
return null;
}
public Guide getGuide(String guideId) {
for (GuideVersion version : guideVersionList) {
for (GuideGroup group : version.getGuideGroupList()) {
for (Guide guide : group.getGuideList()) {
if (StringUtils.equals(guideId, guide.getId())) {
return guide;
}
}
}
}
return null;
}
public void completeAll() {
for (GuideVersion version : guideVersionList) {
for (GuideGroup group : version.getGuideGroupList()) {
for (Guide guide : group.getGuideList()) {
guide.setComplete(true);
}
}
}
GuideCollector.getInstance().saveInfo();
}
public void clearAll() {
guideVersionList.clear();
}
}

29
designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideVersion.java

@ -0,0 +1,29 @@
package com.fr.design.mainframe.guide.base;
import java.util.ArrayList;
import java.util.List;
public class GuideVersion {
private String version;
private List<GuideGroup> guideGroupList;
public GuideVersion(String version) {
guideGroupList = new ArrayList<>();
this.version = version;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public List<GuideGroup> getGuideGroupList() {
return guideGroupList;
}
public void addGuideGroup(GuideGroup guideGroup) {
guideGroupList.add(guideGroup);
}
}

129
designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideView.java

@ -0,0 +1,129 @@
package com.fr.design.mainframe.guide.base;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.guide.scene.AbstractGuideScene;
import com.fr.design.mainframe.guide.scene.GuideScene;
import com.fr.design.mainframe.guide.ui.GuideLoadingGlassPane;
import com.fr.design.utils.gui.GUICoreUtils;
import javax.swing.JDialog;
import javax.swing.SwingUtilities;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Window;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class GuideView extends JDialog {
private static GuideView guideView;
private Guide invoker;
private GuideScene scene;
private Color modalColor;
private float modalOpacity;
private Window window;
public static GuideView getInstance(Guide guide) {
if (guideView == null) {
guideView = new GuideView(DesignerContext.getDesignerFrame(), guide);
}
return guideView;
}
public GuideView(Window window) {
super(window);
this.setUndecorated(true);
this.window = window;
this.modalColor = Color.BLACK;
this.modalOpacity = 0.6f;
this.setPreferredSize(window.getSize());
this.setSize(window.getSize());
this.setLayout(FRGUIPaneFactory.createBorderLayout());
setBg();
this.setGlassPane(new GuideLoadingGlassPane());
DesignerContext.getDesignerFrame().addWindowListener(new WindowAdapter() {
@Override
public void windowDeiconified(WindowEvent e) {
if (isVisible()) {
updateGuideViewLocation();
// window 带透明的dialog在窗口最小化后再打开会不渲染,这边试了下重新设置visible可行
setVisible(false);
setVisible(true);
}
}
});
}
public GuideView(Window window, Guide guide) {
this(window);
this.invoker = guide;
}
public void setModalColor(Color color) {
modalColor = color;
setBg();
}
public void setModalOpacity(float opacity){
modalOpacity = opacity;
setBg();
}
private void setBg() {
Color newColor = new Color(modalColor.getRed(), modalColor.getGreen(), modalColor.getBlue(), (int) (255 * modalOpacity));
this.setBackground(newColor);
}
public void setScene(GuideScene scene) {
if (scene instanceof AbstractGuideScene) {
((AbstractGuideScene) scene).setContainer(this);
}
this.scene = scene;
}
public void showGuide() {
updateGuideViewLocation();
this.setVisible(true);
if (scene != null) {
scene.start();
} else {
GuideManager.getInstance().getCurrentGuide().complete();
}
}
public void dismissGuide() {
this.getLayeredPane().removeAll();
revalidate();
repaint();
setVisible(false);
dispose();
}
@Override
public void paint(Graphics g) {
super.paint(g);
}
public void showLoading() {
updateGuideViewLocation();
this.setVisible(true);
this.getGlassPane().setVisible(true);
}
public void hideLoading() {
this.getGlassPane().setVisible(false);
repaint();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
setVisible(false);
}
});
}
private void updateGuideViewLocation() {
GUICoreUtils.centerWindow(window, this);
this.setSize(getSize());
}
}

155
designer-base/src/main/java/com/fr/design/mainframe/guide/collect/GuideCollector.java

@ -0,0 +1,155 @@
package com.fr.design.mainframe.guide.collect;
import com.fr.base.io.XMLReadHelper;
import com.fr.design.mainframe.guide.base.Guide;
import com.fr.design.mainframe.guide.base.GuideManager;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.ProductConstants;
import com.fr.stable.StableUtils;
import com.fr.stable.xml.XMLPrintWriter;
import com.fr.stable.xml.XMLReadable;
import com.fr.stable.xml.XMLTools;
import com.fr.stable.xml.XMLable;
import com.fr.stable.xml.XMLableReader;
import com.fr.third.javax.xml.stream.XMLStreamException;
import com.fr.third.org.apache.commons.io.FileUtils;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
public class GuideCollector implements XMLable {
private static final String ROOT_XML = "GuideCollector";
private static final String GUIDE_XML = "Guide";
private static final String FILE_NAME = "guide.info";
private static GuideCollector collector;
private boolean showHint;
private List<Guide> cacheGuides;
public static GuideCollector getInstance() {
if (collector == null) {
collector = new GuideCollector();
}
return collector;
}
public GuideCollector() {
cacheGuides = new ArrayList<>();
}
public boolean isShowHint() {
return showHint;
}
public void setShowHint(boolean showHint) {
this.showHint = showHint;
saveInfo();
}
public void load() {
for(Guide cacheGuide : cacheGuides) {
Guide guide = GuideManager.getInstance().getGuide(cacheGuide.getId());
if (guide != null) {
guide.setComplete(cacheGuide.isComplete());
}
}
}
public void saveInfo() {
cacheGuides = GuideManager.getInstance().getAllGuide();
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
XMLTools.writeOutputStreamXML(this, out);
out.flush();
out.close();
String fileContent = new String(out.toByteArray(), StandardCharsets.UTF_8);
FileUtils.writeStringToFile(getInfoFile(), fileContent, StandardCharsets.UTF_8);
} catch (Exception ex) {
FineLoggerFactory.getLogger().error(ex.getMessage());
}
}
private File getInfoFile() {
File file = new File(StableUtils.pathJoin(ProductConstants.getEnvHome(), FILE_NAME));
try {
if (!file.exists()) {
file.createNewFile();
}
} catch (Exception ex) {
FineLoggerFactory.getLogger().error(ex.getMessage(), ex);
}
return file;
}
public void loadFromFile() {
if (!getInfoFile().exists()) {
return;
}
XMLableReader reader = null;
try (InputStream in = new FileInputStream(getInfoFile())) {
reader = XMLReadHelper.createXMLableReader(in, XMLPrintWriter.XML_ENCODER);
if (reader == null) {
return;
}
reader.readXMLObject(this);
} catch (FileNotFoundException e) {
} catch (XMLStreamException | IOException e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
} finally {
try {
if (reader != null) {
reader.close();
}
} catch (XMLStreamException e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
}
@Override
public void readXML(XMLableReader xmLableReader) {
String tagName = xmLableReader.getTagName();
if (tagName.equals(ROOT_XML)) {
showHint = xmLableReader.getAttrAsBoolean("showHint", false);
xmLableReader.readXMLObject(new XMLReadable() {
public void readXML(XMLableReader reader) {
String tagName = reader.getTagName();
if (tagName.equals(GUIDE_XML)) {
Guide guide = new Guide();
guide.setId(reader.getAttrAsString("id", null));
guide.setComplete(reader.getAttrAsBoolean("isComplete", false));
cacheGuides.add(guide);
}
}
});
}
}
@Override
public void writeXML(XMLPrintWriter writer) {
writer.startTAG(ROOT_XML);
writer.attr("showHint", showHint);
for(Guide guide : GuideManager.getInstance().getAllGuide()) {
writer.startTAG(GUIDE_XML);
writer.attr("id", guide.getId());
writer.attr("isComplete", guide.isComplete());
writer.end();
}
writer.end();
}
@Override
public Object clone() throws CloneNotSupportedException {
return null;
}
}

480
designer-base/src/main/java/com/fr/design/mainframe/guide/scene/AbstractGuideScene.java

@ -0,0 +1,480 @@
package com.fr.design.mainframe.guide.scene;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.mainframe.guide.base.GuideManager;
import com.fr.design.mainframe.guide.base.GuideView;
import com.fr.design.mainframe.guide.utils.ScreenImage;
import com.fr.design.mainframe.guide.tip.BubbleTip;
import com.fr.design.mainframe.guide.tip.GuideTip;
import com.fr.stable.StringUtils;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import java.awt.AWTException;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Component;
import java.awt.Composite;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
public abstract class AbstractGuideScene extends JPanel implements GuideScene {
private static final int DEFAULT_ARROW_HEIGHT = 12;
private static final int DEFAULT_ARROW_WIDTH = 18;
private GuideScene nextScene;
private SceneFilter sceneFilter;
private GuideSceneLifecycle lifecycle;
private GuideView container;
private List<Component> targetList;
private List<Component> highlightList;
private Component nextButton;
private List<Point[]> pointsList;
public AbstractGuideScene() {
this.setLayout(null);
this.setOpaque(false);
targetList = new ArrayList<>();
highlightList = new ArrayList<>();
pointsList = new ArrayList<>();
}
/**
* 根据设计器上组件添加高亮区域视图
* JComponent 采用组件绘制方式
* Component 采用屏幕截图方式
* @param component 设计器组件对象
* @return
*/
public boolean addTarget(Component component) {
try {
if (component == null || container == null) {
return false;
}
Point point = SwingUtilities.convertPoint(component,0,0, container.getRootPane());
Rectangle rectangle = new Rectangle(point, component.getSize());
BufferedImage image;
if (component instanceof JComponent) {
JComponent jComponent = (JComponent) component;
image = ScreenImage.createImage(jComponent);
} else if (component instanceof Window) {
image = ScreenImage.createImage(component);
} else {
image = captureImage(component);
}
targetList.add(component);
highlightList.add(getTargetComponentWithImage(image, rectangle));
return true;
} catch (AWTException e) {
e.printStackTrace();
GuideManager.getInstance().getCurrentGuide().terminate();
return false;
}
}
/**
* 根据设计器上选定区域获取高亮视图采用截屏的方式
* @param rectangle 选定区域相对屏幕
* @return
*/
public boolean addTarget(Rectangle rectangle) {
try {
targetList.add(null);
BufferedImage image = captureImage(rectangle);
highlightList.add(getTargetComponentWithImage(image, rectangle));
return true;
} catch (AWTException e) {
e.printStackTrace();
GuideManager.getInstance().getCurrentGuide().terminate();
return false;
}
}
/**
* 根据设计器组件选定其中某个区域添加高亮视图
* @param component 设计器组件
* @param origin 相对组件的区域
* @return
*/
public boolean addTarget(Component component, Rectangle origin) {
try {
if (component == null) {
return false;
}
Point point = SwingUtilities.convertPoint(component,0,0, container.getRootPane());
origin = origin.intersection(new Rectangle(0,0,component.getWidth(), component.getHeight()));
Rectangle rectangle = new Rectangle(point.x + origin.x, point.y + origin.y, origin.width, origin.height);
BufferedImage image;
if (component instanceof JComponent) {
JComponent jComponent = (JComponent) component;
image = ScreenImage.createImage(jComponent, origin);
} else {
image = ScreenImage.createImage(component).getSubimage(origin.x, origin.y, origin.width, origin.height);
}
targetList.add(component);
highlightList.add(getTargetComponentWithImage(image, rectangle));
return true;
} catch (AWTException e) {
e.printStackTrace();
GuideManager.getInstance().getCurrentGuide().terminate();
return false;
}
}
/**
* 添加自定义组件
* @param component 自定义组件
* @param rectangle 相对引导页的区域
* @return
*/
public boolean addCustomTarget(Component component, Rectangle rectangle) {
if (component == null) {
return false;
}
component.setBounds(rectangle);
targetList.add(component);
highlightList.add(component);
return true;
}
public boolean addCustomTarget(Component component, Point location) {
return addCustomTarget(component, new Rectangle(location, component.getPreferredSize()));
}
protected List<Component> getTargetList() {
return targetList;
}
public List<Component> getHighlightList() {
return highlightList;
}
private UILabel getTargetComponentWithImage(BufferedImage image, Rectangle rectangle) {
ImageIcon ic = new ImageIcon(image);
UILabel label = new UILabel(ic);
label.setOpaque(true);
label.setBounds(rectangle);
return label;
}
private BufferedImage captureImage(Rectangle rectangle) throws AWTException {
container.setVisible(false);
BufferedImage image = ScreenImage.createImage(rectangle);
showContainer();
return image;
}
private BufferedImage captureImage(Component component) throws AWTException {
container.setVisible(false);
BufferedImage image = ScreenImage.createImage(component);
showContainer();
return image;
}
private void showContainer() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
container.setVisible(true);
container.toFront();
container.requestFocus();
}
});
}
/**
* 自定义位置添加气泡提示组件
* @param title 提示标题
* @param content 提示内容
* @param direction 气泡窗口位置方向
* @param anchor 气泡窗口箭头坐标
* @param bubbleTailStart 气泡窗口箭头坐标相对于位置方向交叉轴的比例从左到右从上到下
*/
public void addBubbleTip(String title, String content, GuideTip.Direction direction, Point anchor, float bubbleTailStart) {
BubbleTip bt = new BubbleTip(title, content, direction, bubbleTailStart);
bt.setAnchor(anchor);
this.add(bt.getTip());
}
/**
* 以上一个添加的引导目标窗口为基础添加对应的气泡窗
* @param title 提示标题
* @param content 提示内容
* @param direction
* @param anchorStart
* @param bubbleTailStart
*/
public void addBubbleTip(String title, String content, GuideTip.Direction direction, float anchorStart, float bubbleTailStart) {
if (highlightList.size() == 0) {
return;
}
Component lastTarget = highlightList.get(highlightList.size() - 1);
Rectangle bounds = lastTarget.getBounds();
Point anchor = new Point(0,0);
if (direction == GuideTip.Direction.TOP) {
anchor = new Point(bounds.x + (int)(bounds.width * anchorStart), bounds.y);
} else if (direction == GuideTip.Direction.BOTTOM) {
anchor = new Point(bounds.x + (int)(bounds.width * anchorStart), bounds.y + bounds.height);
} else if (direction == GuideTip.Direction.LEFT) {
anchor = new Point(bounds.x, bounds.y + (int)(bounds.height * anchorStart));
} else if (direction == GuideTip.Direction.RIGHT) {
anchor = new Point(bounds.x + bounds.width, bounds.y + (int) (bounds.height * anchorStart));
}
addBubbleTip(title, content, direction, anchor, bubbleTailStart);
}
public void addBubbleTip(String title, String content, GuideTip.Direction direction) {
addBubbleTip(title, content, direction, 0.5f, 0.5f);
}
public void addBubbleTip(String title, GuideTip.Direction direction) {
addBubbleTip(title, StringUtils.EMPTY, direction);
}
public void addTip(GuideTip tip) {
this.add(tip.getTip());
}
public void addLineArrow(Point... points) {
pointsList.add(points);
}
public void setContainer(GuideView container) {
this.container = container;
}
public GuideView getContainer() {
return container;
}
@Override
public GuideScene nextScene(GuideScene scene) {
nextScene = scene;
return nextScene;
}
@Override
public void addSceneFilter(SceneFilter filter) {
sceneFilter = filter;
}
@Override
public void start() {
clear();
if (lifecycle != null && !lifecycle.prepared()) {
return;
}
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
showScene();
}
});
}
@Override
public void showScene() {
if (container != null) {
container.setContentPane(AbstractGuideScene.this);
setBounds(0, 0 , getSceneWidth(), getSceneWidth());
// show target
for (int index = highlightList.size() - 1; index >= 0; index--) {
add(highlightList.get(index));
}
// show next button
if (nextButton != null) {
nextButton.setBounds((getSceneWidth() - 60) / 2, getSceneHeight() - 100, 60, 30);
add(nextButton);
}
container.revalidate();
container.repaint();
}
showContainer();
if (lifecycle != null) {
lifecycle.onShow();
}
}
@Override
public void complete() {
container.getLayeredPane().remove(this);
container.repaint();
if (lifecycle != null && !lifecycle.onComplete()) {
return;
}
if (sceneFilter != null) {
nextScene = sceneFilter.getFilterScene();
}
if (nextScene != null) {
if (nextScene instanceof AbstractGuideScene) {
((AbstractGuideScene) nextScene).setContainer(container);
}
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
nextScene.start();
}
});
} else {
GuideManager.getInstance().getCurrentGuide().complete();
}
}
@Override
public void registerLifecycle(GuideSceneLifecycle lifecycle) {
this.lifecycle = lifecycle;
}
@Override
public void removeLifecycle() {
this.lifecycle = null;
}
public void showNextButton() {
UIButton nextButton = new UIButton("Next");
nextButton.setPreferredSize(new Dimension(60, 30));
nextButton.setOpaque(false);
nextButton.setFont(nextButton.getFont().deriveFont(20));
nextButton.setRoundBorder(true, 8);
nextButton.setForeground(Color.WHITE);
nextButton.setNormalPainted(false);
nextButton.setPressedPainted(false);
nextButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
complete();
}
});
this.nextButton = nextButton;
}
private int getSceneWidth() {
if (container == null) {
return 0;
}
return container.getLayeredPane().getWidth();
}
private int getSceneHeight() {
if (container == null) {
return 0;
}
return container.getLayeredPane().getHeight();
}
private void clear() {
targetList = new ArrayList<>();
highlightList = new ArrayList<>();
this.nextButton = null;
this.removeAll();
invalidate();
repaint();
}
@Override
public void paint(Graphics g) {
super.paint(g);
if (pointsList.isEmpty()) {
return;
}
Graphics2D g2d = (Graphics2D) g;
Composite oldComposite = g2d.getComposite();
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
g2d.setColor(Color.WHITE);
for (Point[] points : pointsList) {
if (points.length <= 1) {
continue;
}
Point startPoint = points[0];
Point endPoint = startPoint;
for (int index = 1; index < points.length; index++) {
startPoint = endPoint;
endPoint = points[index];
g2d.drawLine(startPoint.x, startPoint.y, endPoint.x, endPoint.y);
}
drawArrow(g2d, startPoint, endPoint);
}
g2d.setComposite(oldComposite);
}
/**
* 根据最后两点坐标计算出三角箭头的三个点坐标绘制箭头
* 这里实现以终点坐标为坐标轴圆点计算
* @param start 起始点坐标
* @param end 重点坐标
*/
private void drawArrow(Graphics2D g2d, Point start, Point end) {
try{
double dealtPointX = start.x - end.x;
double dealtPointY = -(start.y - end.y);
double pointDistance = calDistance(dealtPointX, dealtPointY);
double triangleHeight = Math.min(DEFAULT_ARROW_HEIGHT, pointDistance);
double triangleWidth = triangleHeight * (DEFAULT_ARROW_WIDTH / 2) / DEFAULT_ARROW_WIDTH;
if (triangleHeight < 1 || triangleWidth < 1 || pointDistance < 1) {
return;
}
double pointAngle;
double abs = 1;
if (dealtPointX == 0) {
pointAngle = Math.PI / 2;
} else {
pointAngle = Math.atan(dealtPointY / dealtPointX);
}
if (dealtPointY < 0) {
pointAngle += Math.PI;
abs = -1;
}
double deltaAngle = Math.atan(triangleWidth / triangleHeight);
double triangleDistance = calDistance(triangleWidth, triangleHeight);
Point p1 =calPoint(end, triangleDistance, pointAngle - deltaAngle, abs);
Point p2 = calPoint(end, triangleDistance, pointAngle + deltaAngle, abs);
int xPoints[] = {end.x, p1.x, p2.x};
int yPoints[] = {end.y, p1.y, p2.y};
g2d.fillPolygon(xPoints, yPoints, 3);
} catch (Exception e) {
e.printStackTrace();
GuideManager.getInstance().getCurrentGuide().terminate();
}
}
private double calDistance(double x, double y) {
return Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
}
private Point calPoint(Point relativePoint, double distance, double angle, double abs) {
int x = (int)(relativePoint.x + abs * distance * Math.cos(angle));
int y = (int)(relativePoint.y - abs * distance * Math.sin(angle));
return new Point(x, y);
}
}

123
designer-base/src/main/java/com/fr/design/mainframe/guide/scene/ClickScene.java

@ -0,0 +1,123 @@
package com.fr.design.mainframe.guide.scene;
import com.fr.design.mainframe.guide.base.GuideManager;
import javax.swing.AbstractButton;
import javax.swing.ButtonModel;
import javax.swing.SwingUtilities;
import java.awt.Component;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class ClickScene extends AbstractGuideScene{
public enum ClickType {
LEFT, LEFT_DOUBLE, RIGHT
}
public void addClickTarget(Component component, ClickType clickType) {
addClickTarget(component, clickType, false);
}
public void addClickTarget(Component component, ClickType clickType, boolean isDispatch) {
if (super.addTarget(component)) {
addTargetClickListener(clickType, isDispatch);
}
}
public void addClickTarget(Rectangle rectangle, ClickType clickType) {
if (super.addTarget(rectangle)) {
addTargetClickListener(clickType,false);
}
}
public void addClickTarget(Component component, Rectangle rectangle, ClickType clickType) {
if (super.addTarget(component, rectangle)) {
addTargetClickListener(clickType, false);
}
}
public void addCustomClickTarget(Component component, Rectangle rectangle, ClickType clickType) {
if (super.addCustomTarget(component, rectangle)) {
addTargetClickListener(clickType, false);
}
}
public void addCustomClickTarget(Component component, Point location, ClickType clickType) {
if (super.addCustomTarget(component, location)) {
addTargetClickListener(clickType, false);
}
}
private void addTargetClickListener(ClickType clickType, boolean isDispatch) {
Component highlight = getHighlightList().get(getHighlightList().size() - 1);
Component target = getTargetList().get(getTargetList().size() - 1);
highlight.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON1) {
if ((e.getClickCount() == 1 && clickType == ClickType.LEFT) || (e.getClickCount() == 2 && clickType == ClickType.LEFT_DOUBLE)) {
if (isDispatch) {
redispatchMouseEvent(e, target);
}
complete();
}
} else if (e.getButton() == MouseEvent.BUTTON3 && clickType == ClickType.RIGHT) {
if (isDispatch) {
redispatchMouseEvent(e, target);
}
complete();
}
}
@Override
public void mousePressed(MouseEvent e) {
if (isDispatch) {
if (target instanceof AbstractButton) {
AbstractButton b = (AbstractButton) target;
b.setFocusable(false);
}
redispatchMouseEvent(e, target);
}
}
@Override
public void mouseReleased(MouseEvent e) {
if (isDispatch) {
redispatchMouseEvent(e, target);
}
}
@Override
public void mouseEntered(MouseEvent e) {
if (isDispatch) {
redispatchMouseEvent(e, target);
}
}
@Override
public void mouseExited(MouseEvent e) {
if (isDispatch) {
redispatchMouseEvent(e, target);
}
}
});
}
private void redispatchMouseEvent(MouseEvent e, Component component) {
component.dispatchEvent(new MouseEvent(component, e.getID(), e
.getWhen(), e.getModifiers(), e.getX(),
e.getY(), e.getClickCount(), e.isPopupTrigger()));
}
@Override
public void showScene() {
// 交互类的 scene 如果没有高亮内容块载,需要及时终止Guide,否则就没法去掉模态框影响到设计器主功能的使用了
if (this.getComponentCount() == 0) {
GuideManager.getInstance().getCurrentGuide().terminate();
} else {
super.showScene();
}
}
}

37
designer-base/src/main/java/com/fr/design/mainframe/guide/scene/DisplayScene.java

@ -0,0 +1,37 @@
package com.fr.design.mainframe.guide.scene;
import java.util.Timer;
import java.util.TimerTask;
public class DisplayScene extends AbstractGuideScene {
private long delay;
private static final long DEFAULT_DELAY = 1000;
private static Timer displayTimer = new Timer();
public DisplayScene() {
this(DEFAULT_DELAY);
}
public DisplayScene(long delay) {
super();
this.delay = delay;
}
public void setDelay(long delay) {
this.delay = delay;
}
@Override
public void showScene() {
super.showScene();
// 实例化Timer类
displayTimer.schedule(new TimerTask() {
@Override
public void run() {
complete();
displayTimer.purge();
}
}, delay);
}
}

64
designer-base/src/main/java/com/fr/design/mainframe/guide/scene/DragScene.java

@ -0,0 +1,64 @@
package com.fr.design.mainframe.guide.scene;
import com.fr.design.mainframe.guide.scene.drag.DragAndDropDragGestureListener;
import java.awt.Component;
import java.awt.Rectangle;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragSourceDropEvent;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDropEvent;
public class DragScene extends AbstractGuideScene{
public enum DragType{
NONE, FROM, TO
}
public void addDragTarget(Component component, DragType type) {
if (super.addTarget(component)) {
addDragTargetListener(type);
}
}
public void addDragTarget(Rectangle rectangle, DragType type) {
if (super.addTarget(rectangle)) {
addDragTargetListener(type);
}
}
public void addDragTarget(Component component, Rectangle rectangle, DragType type) {
if (super.addTarget(component, rectangle)) {
addDragTargetListener(type);
}
}
public void addCustomDragTarget(Component component, Rectangle rectangle, DragType type) {
if (super.addCustomTarget(component, rectangle)) {
addDragTargetListener(type);
}
}
private void addDragTargetListener(DragType dragType) {
Component target = getHighlightList().get(getHighlightList().size() - 1);
if (dragType == DragType.FROM) {
new DragAndDropDragGestureListener(target, DnDConstants.ACTION_COPY_OR_MOVE){
@Override
public void dragDropEnd(DragSourceDropEvent dsde) {
if (dsde.getDropSuccess()) {
complete();
}
}
};
} else if (dragType == DragType.TO) {
target.setDropTarget(new DropSceneTarget());
}
}
private class DropSceneTarget extends DropTarget {
@Override
public synchronized void drop(DropTargetDropEvent dtde) {
dtde.dropComplete(true);
}
}
}

18
designer-base/src/main/java/com/fr/design/mainframe/guide/scene/GuideScene.java

@ -0,0 +1,18 @@
package com.fr.design.mainframe.guide.scene;
public interface GuideScene {
GuideScene nextScene(GuideScene scene);
void addSceneFilter(SceneFilter filter);
void start();
void showScene();
void complete();
void registerLifecycle(GuideSceneLifecycle lifecycle);
void removeLifecycle();
}

21
designer-base/src/main/java/com/fr/design/mainframe/guide/scene/GuideSceneLifecycle.java

@ -0,0 +1,21 @@
package com.fr.design.mainframe.guide.scene;
public interface GuideSceneLifecycle {
/**
* 引导场景准备工作
* scene 添加 target 应该在这个阶段处理
* @return 返回true自动执行scene, 返回false需要手动触发
*/
boolean prepared();
/**
* scene 显示后
*/
void onShow();
/**
* scene 交互完成后处理
* @return 返回true自动进入下一个scene返回false需要手动触发
*/
boolean onComplete();
}

18
designer-base/src/main/java/com/fr/design/mainframe/guide/scene/GuideSceneLifecycleAdaptor.java

@ -0,0 +1,18 @@
package com.fr.design.mainframe.guide.scene;
public abstract class GuideSceneLifecycleAdaptor implements GuideSceneLifecycle {
@Override
public boolean prepared() {
return true;
}
@Override
public void onShow() {
}
@Override
public boolean onComplete() {
return true;
}
}

5
designer-base/src/main/java/com/fr/design/mainframe/guide/scene/SceneFilter.java

@ -0,0 +1,5 @@
package com.fr.design.mainframe.guide.scene;
public interface SceneFilter {
GuideScene getFilterScene();
}

60
designer-base/src/main/java/com/fr/design/mainframe/guide/scene/drag/DragAndDropDragGestureListener.java

@ -0,0 +1,60 @@
package com.fr.design.mainframe.guide.scene.drag;
import com.fr.general.ComparatorUtils;
import org.jetbrains.annotations.NotNull;
import java.awt.Component;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragSource;
import java.awt.dnd.DragSourceAdapter;
public class DragAndDropDragGestureListener extends DragSourceAdapter implements DragGestureListener {
private Component component;
public DragAndDropDragGestureListener(Component component, int actions) {
this.component = component;
DragSource source = new DragSource();
source.createDefaultDragGestureRecognizer(component, actions, this);
}
public void dragGestureRecognized(DragGestureEvent dge) {
if (component != null) {
try {
DragAndDropTransferable dragAndDropTransferable = new DragAndDropTransferable(component);
dge.startDrag(DragSource.DefaultCopyDrop, dragAndDropTransferable, this);
} catch (Exception e) {
e.printStackTrace();
}
}
}
private static class DragAndDropTransferable implements Transferable {
private Component component;
public DragAndDropTransferable(Component component) {
this.component = component;
}
DataFlavor[] flavors = {new DataFlavor(Component.class, "Component")};
public DataFlavor[] getTransferDataFlavors() {
return flavors;
}
public boolean isDataFlavorSupported(DataFlavor flavor) {
for (DataFlavor df : flavors) {
if (ComparatorUtils.equals(df, flavor)) {
return true;
}
}
return false;
}
@NotNull
public Object getTransferData(DataFlavor df) {
return component;
}
}
}

97
designer-base/src/main/java/com/fr/design/mainframe/guide/tip/BubbleTip.java

@ -0,0 +1,97 @@
package com.fr.design.mainframe.guide.tip;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.DesignerFrame;
import com.fr.design.mainframe.guide.base.Guide;
import com.fr.design.mainframe.guide.base.GuideManager;
import com.fr.design.mainframe.guide.ui.bubble.Bubble;
import com.fr.design.mainframe.guide.ui.bubble.BubbleWithClose;
import javax.swing.JComponent;
import javax.swing.JOptionPane;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class BubbleTip implements GuideTip {
private BubbleWithClose bubbleBox;
private Point anchor;
/**
*
* @param title 标题
* @param content 内容
* @param direction 气泡提示相对anchor的方向这里方向会和气泡组件箭头方向相反
* @param tailStart 气泡尾巴相对当前边垂直方向偏移位置比例值在0-1范围
*/
public BubbleTip(String title, String content, Direction direction, float tailStart) {
bubbleBox = new BubbleWithClose(title, content, getBubbleBoxTailDirection(direction), tailStart);
bubbleBox.addCloseActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Guide currentGuide = GuideManager.getInstance().getCurrentGuide();
if (currentGuide != null) {
int returnVal = FineJOptionPane.showConfirmDialog(
currentGuide.getGuideView(),
Toolkit.i18nText("Fine-Design_Guide_Option_Warning_Terminal"),
Toolkit.i18nText("Fine-Design_Basic_Confirm"),
JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE);
if (returnVal == JOptionPane.YES_OPTION) {
currentGuide.terminate();
}
}
}
});
}
@Override
public JComponent getTip() {
if(anchor == null) {
return new BubbleWithClose(bubbleBox.getTitle(), bubbleBox.getContent(), Bubble.TailDirection.TOP, 0);
} else {
setBubbleBoxBound();
return bubbleBox;
}
}
/**
* 设置锚点坐标
* 这里可以指定气泡组件箭头坐标的箭头坐标
* @param anchor
*/
public void setAnchor(Point anchor) {
this.anchor = anchor;
}
private void setBubbleBoxBound() {
int bubbleW = bubbleBox.getPreferredSize().width;
int bubbleH = bubbleBox.getPreferredSize().height;
if (bubbleBox.isTailHorizontal()) {
int x = bubbleBox.isTailLeft() ? anchor.x : anchor.x - bubbleW;
int y = anchor.y - (int) (bubbleH * bubbleBox.getTailStart());
bubbleBox.setBounds(x, y, bubbleW, bubbleH);
} else if (bubbleBox.isTailVertical()) {
int x = anchor.x - (int) (bubbleW * bubbleBox.getTailStart());
int y = bubbleBox.isTailTop() ? anchor.y : anchor.y - bubbleH;
bubbleBox.setBounds(x, y, bubbleW, bubbleH);
}
}
private Bubble.TailDirection getBubbleBoxTailDirection(Direction direction) {
switch (direction) {
case TOP:
return Bubble.TailDirection.BOTTOM;
case BOTTOM:
return Bubble.TailDirection.TOP;
case LEFT:
return Bubble.TailDirection.RIGHT;
case RIGHT:
default:
return Bubble.TailDirection.LEFT;
}
}
}

14
designer-base/src/main/java/com/fr/design/mainframe/guide/tip/GuideTip.java

@ -0,0 +1,14 @@
package com.fr.design.mainframe.guide.tip;
import javax.swing.JComponent;
import java.awt.Point;
public interface GuideTip {
enum Direction {
TOP, BOTTOM, LEFT, RIGHT
}
JComponent getTip();
void setAnchor(Point anchor);
}

74
designer-base/src/main/java/com/fr/design/mainframe/guide/ui/BubbleHint.java

@ -0,0 +1,74 @@
package com.fr.design.mainframe.guide.ui;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.VerticalFlowLayout;
import com.fr.design.mainframe.guide.ui.bubble.Bubble;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionListener;
public class BubbleHint extends Bubble {
private UIButton confirmButton;
public BubbleHint() {
super(TailDirection.TOP, 0.9f);
initComponent();
}
private void initComponent() {
this.setLayout(new BorderLayout());
this.setBorder(BorderFactory.createEmptyBorder(10 + Bubble.TAIL_HEIGHT, 15, 10, 15));
this.setPreferredSize(new Dimension(220, 140));
JPanel contentPane = FRGUIPaneFactory.createVerticalFlowLayout_Pane(false, VerticalFlowLayout.CENTER, 0, 0);
contentPane.setOpaque(false);
UILabel title = new UILabel(Toolkit.i18nText("Fine-Design_Guide_Tips_Title"));
title.setFont(title.getFont().deriveFont(16.0f));
title.setForeground(new Color(62, 155, 249));
title.setPreferredSize(new Dimension(190, 30));
title.setHorizontalAlignment(SwingConstants.CENTER);
title.setBorder(BorderFactory.createEmptyBorder(0,0,5,0));
UILabel content1 = new UILabel(Toolkit.i18nText("Fine-Design_Guide_Tips_Content1"));
content1.setPreferredSize(new Dimension(190,20));
content1.setHorizontalAlignment(SwingConstants.CENTER);
UILabel content2 = new UILabel(Toolkit.i18nText("Fine-Design_Guide_Tips_Content2"));
content2.setPreferredSize(new Dimension(190,20));
content2.setHorizontalAlignment(SwingConstants.CENTER);
JPanel buttonContainer= FRGUIPaneFactory.createCenterFlowZeroGapBorderPane();
buttonContainer.setBorder(BorderFactory.createEmptyBorder(20, 0, 0, 0));
buttonContainer.setPreferredSize(new Dimension(190,40));
buttonContainer.setOpaque(false);
confirmButton = new UIButton(Toolkit.i18nText("Fine-Design_Guide_Tips_Know"));
confirmButton.setPreferredSize(new Dimension(78, 24));
buttonContainer.add(confirmButton);
contentPane.add(title);
contentPane.add(content1);
contentPane.add(content2);
contentPane.add(buttonContainer);
this.add(contentPane, BorderLayout.CENTER);
}
public void addConfirmAction(ActionListener listener) {
confirmButton.addActionListener(listener);
}
public void removeConfirmAction(ActionListener listener) {
confirmButton.removeActionListener(listener);
}
}

78
designer-base/src/main/java/com/fr/design/mainframe/guide/ui/ExpandPane.java

@ -0,0 +1,78 @@
package com.fr.design.mainframe.guide.ui;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.VerticalFlowLayout;
import com.fr.general.IOUtils;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class ExpandPane extends JPanel {
private static final Icon downIcon = IOUtils.readIcon("/com/fr/design/mainframe/guide/arrow_down.png");
private static final Icon rightIcon = IOUtils.readIcon("/com/fr/design/mainframe/guide/arrow_right.png");
private String title;
private boolean expand;
private UILabel arrow;
private JPanel headerPane;
private JPanel contentPane;
public ExpandPane(String title, JPanel contentPane) {
this.title = title;
this.expand = true;
this.contentPane = contentPane;
initComponent();
}
private void initComponent() {
VerticalFlowLayout layout = new VerticalFlowLayout(VerticalFlowLayout.TOP, 10, 5);
layout.setAlignLeft(true);
this.setLayout(layout);
JPanel headerPane = createHeader();
this.add(headerPane);
this.add(contentPane);
headerPane.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
setExpand(!expand);
}
});
}
private JPanel createHeader() {
headerPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
headerPane.setPreferredSize(new Dimension(200, 24));
UILabel headerTitle = new UILabel(this.title);
headerTitle.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0));
arrow = new UILabel(downIcon);
arrow.setOpaque(false);
arrow.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
headerPane.add(headerTitle, BorderLayout.CENTER);
headerPane.add(arrow, BorderLayout.WEST);
return headerPane;
}
@Override
public void setPreferredSize(Dimension preferredSize) {
super.setPreferredSize(preferredSize);
headerPane.setPreferredSize(new Dimension(preferredSize.width, headerPane.getPreferredSize().height));
contentPane.setPreferredSize(new Dimension(preferredSize.width, contentPane.getPreferredSize().height));
}
public void setExpand(boolean isExpand) {
this.expand = isExpand;
arrow.setIcon(isExpand ? downIcon : rightIcon);
contentPane.setVisible(isExpand);
}
public boolean isExpand() {
return expand;
}
}

134
designer-base/src/main/java/com/fr/design/mainframe/guide/ui/GuideCompleteDialog.java

@ -0,0 +1,134 @@
package com.fr.design.mainframe.guide.ui;
import com.fr.design.gui.frpane.UITextPane;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ibutton.UIButtonUI;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.utils.gui.GUIPaintUtils;
import com.fr.general.IOUtils;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class GuideCompleteDialog extends JDialog {
private static final int DIALOG_WIDTH = 340;
private static final int DIALOG_HEIGHT = 367;
private static final Icon SUCCESS_ICON = IOUtils.readIcon("/com/fr/design/mainframe/guide/success.png");
private static final int ICON_HEIGHT = 182;
private static final Color FONT_COLOR = new Color(51, 51, 52);
private static final Color BUTTON_BG_COLOR = new Color(65, 155,249);
private static GuideCompleteDialog dialog;
public static GuideCompleteDialog getInstance() {
if (dialog == null) {
dialog = new GuideCompleteDialog(DesignerContext.getDesignerFrame());
}
return dialog;
}
private UITextPane textArea;
public GuideCompleteDialog(Window window) {
super(window);
setSize(DIALOG_WIDTH, DIALOG_HEIGHT);
setUndecorated(true);
setModal(true);
setLocationRelativeTo(window);
this.setContentPane(getContentPane());
}
@Override
public Container getContentPane() {
JPanel contentPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
UILabel completeImage = new UILabel(SUCCESS_ICON);
completeImage.setPreferredSize(new Dimension(DIALOG_WIDTH, ICON_HEIGHT));
JPanel container = new JPanel(new BorderLayout(0, 10));
container.setBorder(BorderFactory.createEmptyBorder(15, 52, 25, 52));
UILabel title = new UILabel(Toolkit.i18nText("Fine-Design_Guide_Complete_Confirm"));
title.setFont(title.getFont().deriveFont(22.0f));
title.setPreferredSize(new Dimension(190, 30));
title.setHorizontalAlignment(SwingConstants.CENTER);
title.setForeground(FONT_COLOR);
textArea = new UITextPane();
textArea.setEnabled(false);
textArea.setOpaque(false);
textArea.setFont(textArea.getFont().deriveFont(18.0f));
textArea.setPreferredSize(new Dimension(236, 52));
textArea.setBorder(null);
textArea.setDisabledTextColor(FONT_COLOR);
StyledDocument doc = textArea.getStyledDocument();
SimpleAttributeSet center = new SimpleAttributeSet();
StyleConstants.setAlignment(center, StyleConstants.ALIGN_CENTER);
doc.setParagraphAttributes(0, doc.getLength(), center, false);
JPanel buttonContainer= FRGUIPaneFactory.createCenterFlowZeroGapBorderPane();
buttonContainer.setPreferredSize(new Dimension(190,38));
buttonContainer.setOpaque(false);
UIButton button = new UIButton(Toolkit.i18nText("Fine-Design_Guide_Complete_End")){
@Override
public Dimension getPreferredSize() {
return new Dimension(122, 38);
}
};
button.setUI(confirmButtonUI);
button.setRoundBorder(true);
button.setForeground(Color.WHITE);
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
setVisible(false);
dispose();
}
});
buttonContainer.add(button);
container.add(title, BorderLayout.NORTH);
container.add(textArea, BorderLayout.CENTER);
container.add(buttonContainer,BorderLayout.SOUTH);
contentPane.add(completeImage, BorderLayout.NORTH);
contentPane.add(container, BorderLayout.CENTER);
return contentPane;
}
public void showDialog(String str) {
textArea.setText(str);
repaint();
this.setVisible(true);
}
private UIButtonUI confirmButtonUI = new UIButtonUI() {
protected void doExtraPainting(UIButton b, Graphics2D g2d, int w, int h, String selectedRoles) {
if (isPressed(b) && b.isPressedPainted()) {
GUIPaintUtils.fillPressed(g2d, 0, 0, w, h, b.isRoundBorder(), b.getRectDirection(), b.isDoneAuthorityEdited(selectedRoles), BUTTON_BG_COLOR);
} else if (isRollOver(b)) {
GUIPaintUtils.fillRollOver(g2d, 0, 0, w, h, b.isRoundBorder(), b.getRectDirection(), b.isDoneAuthorityEdited(selectedRoles), b.isPressedPainted(), BUTTON_BG_COLOR);
} else if (b.isNormalPainted()) {
GUIPaintUtils.fillNormal(g2d, 0, 0, w, h, b.isRoundBorder(), b.getRectDirection(), b.isDoneAuthorityEdited(selectedRoles), b.isPressedPainted(), BUTTON_BG_COLOR);
}
}
};
}

53
designer-base/src/main/java/com/fr/design/mainframe/guide/ui/GuideLoadingGlassPane.java

@ -0,0 +1,53 @@
package com.fr.design.mainframe.guide.ui;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
public class GuideLoadingGlassPane extends JPanel {
private static final String loadingImagePath = "/com/fr/design/mainframe/guide/loading.gif";
private static GuideLoadingGlassPane loadingPane;
public static GuideLoadingGlassPane getInstance() {
if (loadingPane == null) {
loadingPane = new GuideLoadingGlassPane();
}
return loadingPane;
}
public GuideLoadingGlassPane() {
this.setLayout(new GridBagLayout());
this.setOpaque(false);
initComponent();
}
public void initComponent() {
JPanel loadingView = FRGUIPaneFactory.createBorderLayout_S_Pane();
loadingView.setOpaque(false);
loadingView.setPreferredSize(new Dimension(130, 120));
JPanel imageContainer = FRGUIPaneFactory.createCenterFlowInnerContainer_S_Pane();
imageContainer.setOpaque(false);
ImagePanel imagePanel = new ImagePanel(loadingImagePath);
imagePanel.setOpaque(false);
imagePanel.setPreferredSize(new Dimension(84, 84));
imageContainer.add(imagePanel);
UILabel hintLabel = new UILabel(Toolkit.i18nText("Fine-Design_Guide_Loading_Wait"));
hintLabel.setHorizontalAlignment(SwingConstants.CENTER);
hintLabel.setForeground(Color.WHITE);
loadingView.add(imageContainer, BorderLayout.NORTH);
loadingView.add(hintLabel, BorderLayout.SOUTH);
this.add(loadingView, new GridBagConstraints());
}
}

233
designer-base/src/main/java/com/fr/design/mainframe/guide/ui/GuideManageDialog.java

@ -0,0 +1,233 @@
package com.fr.design.mainframe.guide.ui;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.icontainer.UIScrollPane;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.VerticalFlowLayout;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.guide.base.Guide;
import com.fr.design.mainframe.guide.base.GuideGroup;
import com.fr.design.mainframe.guide.base.GuideManager;
import com.fr.design.mainframe.guide.base.GuideVersion;
import com.fr.design.mainframe.guide.collect.GuideCollector;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.general.IOUtils;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.border.Border;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class GuideManageDialog extends JDialog {
private static final int DEFAULT_HEIGHT = 400;
private static final int DEFAULT_WIDTH = 600;
private static final Icon GROUP_COMPLETE_NONE = IOUtils.readIcon("/com/fr/design/mainframe/guide/complete_none.png");
private static final Icon GROUP_COMPLETE_SOME = IOUtils.readIcon("/com/fr/design/mainframe/guide/complete_some.png");
private static final Icon GROUP_COMPLETE_ALL = IOUtils.readIcon("/com/fr/design/mainframe/guide/complete_all.png");
private static final Color BORDER_COLOR = new Color(224, 224, 225);
private static final Color UNCOMPLETE_FONT_COLOR = new Color(51, 51, 52);
private static final Color COMPLETE_FONT_COLOR = new Color(51,51,52,128);
private static GuideManageDialog dialog;
private JPanel scrollContent;
public static GuideManageDialog getInstance() {
if (dialog == null) {
dialog = new GuideManageDialog(DesignerContext.getDesignerFrame());
}
return dialog;
}
public GuideManageDialog(Window parent) {
super(parent);
GuideCollector.getInstance().load();
initComponent();
}
private void initComponent() {
this.setTitle(Toolkit.i18nText("Fine-Design_Guide_Manager_Dialog_Title"));
setResizable(false);
setModal(true);
setLayout(FRGUIPaneFactory.createBorderLayout());
setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
GUICoreUtils.centerWindow(this);
JPanel contentPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
contentPane.add(createContentPanel(), BorderLayout.CENTER);
contentPane.add(createActionsPane(), BorderLayout.SOUTH);
setContentPane(contentPane);
}
private UIScrollPane createContentPanel() {
scrollContent = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, VerticalFlowLayout.TOP, 0, 5);
UIScrollPane scrollPane = new UIScrollPane(scrollContent);
return scrollPane;
}
private JPanel createGuideVersionPane(GuideVersion guideVersion) {
JPanel expandContent = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, VerticalFlowLayout.TOP, 0, 5);
for (GuideGroup guideGroup : guideVersion.getGuideGroupList()) {
JPanel guideGroupCard = createGuideGroupCard(guideGroup);
expandContent.add(guideGroupCard);
}
ExpandPane expandPane = new ExpandPane(Toolkit.i18nText("Fine-Design_Guide_Manager_Dialog_Version_Title", guideVersion.getVersion()), expandContent);
return expandPane;
}
private JPanel createGuideGroupCard(GuideGroup guideGroup) {
JPanel card = FRGUIPaneFactory.createBorderLayout_S_Pane();
card.setBorder(BorderFactory.createLineBorder(BORDER_COLOR));
card.setBackground(Color.WHITE);
JPanel cardContainer = FRGUIPaneFactory.createBorderLayout_S_Pane();
cardContainer.setOpaque(false);
cardContainer.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 10));
card.add(cardContainer, BorderLayout.CENTER);
cardContainer.add(createGroupTitlePane(guideGroup), BorderLayout.NORTH);
cardContainer.add(createGroupContentPane(guideGroup), BorderLayout.CENTER);
return card;
}
private JPanel createGroupTitlePane(GuideGroup guideGroup) {
JPanel titleContainer = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, VerticalFlowLayout.CENTER, 0, 0);
titleContainer.setBorder(getBottomBorder());
titleContainer.setOpaque(false);
titleContainer.setPreferredSize(new Dimension(500, 40));
JPanel titlePane = FRGUIPaneFactory.createBoxFlowInnerContainer_S_Pane(0, 8,0 );
titlePane.setOpaque(false);
UILabel iconLabel = new UILabel(getGroupStateIcon(guideGroup));
iconLabel.setPreferredSize(new Dimension(16, 16));
iconLabel.setOpaque(false);
UILabel titleLabel = new UILabel(guideGroup.getName());
titleLabel.setPreferredSize(new Dimension(200, 16));
titleLabel.setForeground(new Color(65, 155, 249));
titleLabel.setOpaque(false);
titlePane.add(iconLabel);
titlePane.add(titleLabel);
titleContainer.add(titlePane);
return titleContainer;
}
private JPanel createGroupContentPane(GuideGroup guideGroup) {
JPanel groupContainer = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, VerticalFlowLayout.TOP, 0, 0);
groupContainer.setBorder(BorderFactory.createEmptyBorder(0,10,0,0));
groupContainer.setOpaque(false);
for (int index = 0; index < guideGroup.getGuideList().size(); index++) {
JPanel guidePane = createGuidePane(guideGroup.getGuideList().get(index), index);
if (index != guideGroup.getGuideList().size() - 1) {
guidePane.setBorder(getBottomBorder());
}
groupContainer.add(guidePane);
}
return groupContainer;
}
private JPanel createGuidePane(Guide guide, int index) {
JPanel guidePaneContainer = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, VerticalFlowLayout.CENTER, 0, 0);
guidePaneContainer.setPreferredSize(new Dimension(540, 40));
guidePaneContainer.setOpaque(false);
JPanel guidePane = FRGUIPaneFactory.createBoxFlowInnerContainer_S_Pane(0, 50,0 );
guidePane.setOpaque(false);
UILabel title = new UILabel((index + 1) + "、" + guide.getDescription());
title.setPreferredSize(new Dimension(440, 20));
title.setForeground(guide.isComplete() ? COMPLETE_FONT_COLOR : UNCOMPLETE_FONT_COLOR);
title.setOpaque(false);
UIButton button = new UIButton(guide.isComplete() ? Toolkit.i18nText("Fine-Design_Guide_Manager_Dialog_Retry") : Toolkit.i18nText("Fine-Design_Guide_Manager_Dialog_Show"));
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
setVisible(false);
guide.go();
}
});
button.setPreferredSize(new Dimension(48, 20));
guidePane.add(title);
guidePane.add(button);
guidePaneContainer.add(guidePane);
return guidePaneContainer;
}
private Border getBottomBorder() {
return BorderFactory.createMatteBorder(
0,0,1, 0, BORDER_COLOR
);
}
public void showDialog() {
resetScrollContent();
this.setVisible(true);
}
private Icon getGroupStateIcon(GuideGroup guideGroup) {
if (guideGroup.isCompleteAll()) {
return GROUP_COMPLETE_ALL;
} else if (guideGroup.isCompleteSome()) {
return GROUP_COMPLETE_SOME;
} else {
return GROUP_COMPLETE_NONE;
}
}
private UIButton createCompleteAllButton() {
UIButton button = new UIButton(Toolkit.i18nText(Toolkit.i18nText("Fine-Design_Guide_Manager_Dialog_Complete_All")));
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
GuideManager.getInstance().completeAll();
resetScrollContent();
}
});
return button;
}
private UIButton createCloseButton() {
UIButton button = new UIButton(Toolkit.i18nText(Toolkit.i18nText("Fine-Design_Guide_Manager_Dialog_Close")));
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
setVisible(false);
}
});
return button;
}
private JPanel createActionsPane() {
JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane();
container.setBorder(BorderFactory.createEmptyBorder(7, 10, 7, 10));
container.add(createCompleteAllButton(), BorderLayout.WEST);
container.add(createCloseButton(), BorderLayout.EAST);
return container;
}
private void resetScrollContent() {
scrollContent.removeAll();
for (GuideVersion guideVersion : GuideManager.getInstance().getGuideVersionList()) {
scrollContent.add(createGuideVersionPane(guideVersion));
}
revalidate();
repaint();
}
}

28
designer-base/src/main/java/com/fr/design/mainframe/guide/ui/ImagePanel.java

@ -0,0 +1,28 @@
package com.fr.design.mainframe.guide.ui;
import javax.swing.JPanel;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
/**
* Created by kerry on 2020-10-23
*/
public class ImagePanel extends JPanel {
private Image image;
public ImagePanel(String imagePath) {
image = Toolkit.getDefaultToolkit().createImage(ImagePanel.class
.getResource(imagePath));
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (image != null) {
g.drawImage(image, 0, 0, getWidth(), getHeight(), this);
}
}
}

152
designer-base/src/main/java/com/fr/design/mainframe/guide/ui/bubble/Bubble.java

@ -0,0 +1,152 @@
package com.fr.design.mainframe.guide.ui.bubble;
import javax.swing.JComponent;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
public class Bubble extends JComponent {
public enum TailDirection {
TOP, BOTTOM, LEFT, RIGHT
}
protected static final int TAIL_HEIGHT = 7;
protected static final int TAIL_WIDTH = 14;
protected static final int BUBBLE_WIDTH = 170;
protected static final Color BG_COLOR = new Color(240,240,241);
protected static final int BORDER_RADIUS = 10;
private TailDirection tailDirection;
private float tailStart;
public Bubble() {
this(TailDirection.LEFT, 0.5f);
}
public Bubble(TailDirection tailDirection, float tailStart) {
this.tailDirection = tailDirection;
this.tailStart = tailStart;
this.setOpaque(false);
}
public void setTailDirection(TailDirection tailDirection) {
this.tailDirection = tailDirection;
}
public TailDirection getTailDirection() {
return tailDirection;
}
public void setTailStart(float tailStart) {
this.tailStart = tailStart;
}
public float getTailStart() {
return tailStart;
}
@Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(getDefaultWidth(), getDefaultHeight());
}
protected int getDefaultWidth() {
return (isTailHorizontal() ? TAIL_HEIGHT : 0) + BUBBLE_WIDTH;
}
protected int getDefaultHeight() {
return (isTailVertical() ? TAIL_HEIGHT : 0);
}
@Override
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
Composite oldComposite = g2.getComposite();
paintBubbleBg(g2);
g2.setComposite(oldComposite);
super.paintComponent(g);
}
protected void paintBubbleBg(Graphics2D g2) {
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
paintRectBg(g2);
paintTailBg(g2);
}
protected void paintRectBg(Graphics2D g2) {
g2.setColor(BG_COLOR);
Rectangle bounds = getRectBounds();
g2.fillRoundRect(bounds.x, bounds.y, bounds.width, bounds.height, BORDER_RADIUS, BORDER_RADIUS);
}
protected void paintTailBg(Graphics2D g2) {
int width = getWidth();
int height = getHeight();
if (isTailVertical()) {
int tailX = (int) (width * tailStart);
int startX = Math.max(tailX - TAIL_WIDTH / 2, 0);
int endX = startX + TAIL_WIDTH;
int[] xPoints = {startX, endX, tailX};
int[] yPoints = isTailTop() ? new int[]{TAIL_HEIGHT, TAIL_HEIGHT, 0} : new int[]{height - TAIL_HEIGHT, height - TAIL_HEIGHT, height};
g2.fillPolygon(xPoints, yPoints, 3);
} else if (isTailHorizontal()) {
int tailY = (int) (height * tailStart);
int startY = Math.max(tailY - TAIL_WIDTH / 2, 0);
int endY = startY + TAIL_WIDTH;
int[] xPoints = isTailLeft() ? new int[]{TAIL_HEIGHT, TAIL_HEIGHT, 0} : new int[]{width - TAIL_HEIGHT, width - TAIL_HEIGHT, width};
int[] yPoints = {startY, endY, tailY};
g2.fillPolygon(xPoints, yPoints, 3);
}
}
public Rectangle getRectBounds() {
int width = getWidth();
int height = getHeight();
switch (tailDirection) {
case TOP:
return new Rectangle(0, TAIL_HEIGHT, width, height - TAIL_HEIGHT);
case LEFT:
return new Rectangle(TAIL_HEIGHT, 0, width - TAIL_HEIGHT, height);
case RIGHT:
return new Rectangle(0, 0 , width - TAIL_HEIGHT, height);
case BOTTOM:
return new Rectangle(0, 0, width, height - TAIL_HEIGHT);
default:
return new Rectangle(0,0,0,0);
}
}
public boolean isTailHorizontal() {
return isTailLeft() || isTailRight();
}
public boolean isTailVertical() {
return isTailTop() || isTailBottom();
}
public boolean isTailLeft() {
return tailDirection == TailDirection.LEFT;
}
public boolean isTailRight() {
return tailDirection == TailDirection.RIGHT;
}
public boolean isTailTop() {
return tailDirection == TailDirection.TOP;
}
public boolean isTailBottom() {
return tailDirection == TailDirection.BOTTOM;
}
}

267
designer-base/src/main/java/com/fr/design/mainframe/guide/ui/bubble/BubbleWithClose.java

@ -0,0 +1,267 @@
package com.fr.design.mainframe.guide.ui.bubble;
import com.fr.base.GraphHelper;
import com.fr.design.gui.frpane.UITextPane;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.general.IOUtils;
import com.fr.stable.StringUtils;
import javax.swing.Icon;
import javax.swing.JTextPane;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.awt.Rectangle;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.font.FontRenderContext;
import java.awt.font.LineBreakMeasurer;
import java.awt.font.TextAttribute;
import java.text.AttributedCharacterIterator;
import java.text.AttributedString;
public class BubbleWithClose extends Bubble {
private static final Font FONT = new Font(Font.SANS_SERIF, Font.PLAIN, 14);
private static final Icon ICON = IOUtils.readIcon("/com/fr/design/mainframe/guide/close.png");
private static final int HEADER_HEIGHT = 24;
private static final Color HEADER_COLOR = new Color(245, 245, 246);
private static final Color TITLE_COLOR = new Color(51, 51, 52);
private static final Color CONTENT_COLOR = new Color(51,51,52,128);
private static final Insets DEFAULT_INSET = new Insets(10, 15, 10, 15);
private String title;
private String content;
private UITextPane titleTextArea;
private UITextPane contentTextArea;
private UIButton closeButton;
public BubbleWithClose(String title, String content) {
this(title, content, TailDirection.LEFT, 0.5f);
}
public BubbleWithClose(String title, String content, TailDirection tailDirection, float tailStart) {
super(tailDirection, tailStart);
this.title = title;
this.content = content;
this.initComponent();
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
protected void initComponent() {
this.setLayout(getLayoutManager());
createCloseButton();
createContentPane();
this.addComponentListener(new ComponentAdapter() {
@Override
public void componentShown(ComponentEvent e) {
super.componentShown(e);
}
@Override
public void componentResized(ComponentEvent e) {
Rectangle rectBounds = getRectBounds();
Dimension buttonSize = closeButton.getPreferredSize();
closeButton.setBounds(getWidth() - 10 - buttonSize.width, rectBounds.y + (HEADER_HEIGHT - buttonSize.height) / 2, buttonSize.width, buttonSize.height);
Dimension titleSize = new Dimension(0,0);
Dimension contentSize = new Dimension(0, 0);
if (titleTextArea != null) {
titleSize = calTextSize(titleTextArea, getTextAreaMaxWidth());
int x = rectBounds.x + (rectBounds.width - getHorizontalInsets() - titleSize.width) / 2 + DEFAULT_INSET.left;
int y = rectBounds.y + HEADER_HEIGHT + DEFAULT_INSET.top;
titleTextArea.setBounds(x, y, titleSize.width, titleSize.height);
}
if (contentTextArea != null) {
contentSize = calTextSize(contentTextArea, getTextAreaMaxWidth());
int x = rectBounds.x + (rectBounds.width - getHorizontalInsets() - contentSize.width) / 2 + DEFAULT_INSET.left;
int y = rectBounds.y = HEADER_HEIGHT + DEFAULT_INSET.top + (titleSize.height == 0 ? 0 : titleSize.height + 10);
contentTextArea.setBounds(x,y, contentSize.width, contentSize.height);
}
setSize(getPreferredSize().width, getPreferredSize().height);
repaint();
}
});
}
private void createCloseButton() {
closeButton = new UIButton();
closeButton.setIcon(ICON);
closeButton.set4ToolbarButton();
closeButton.setPreferredSize(new Dimension(12, 12));
closeButton.setRolloverEnabled(false);
closeButton.setPressedPainted(false);
this.add(closeButton);
}
public void addCloseActionListener(ActionListener actionListener) {
closeButton.addActionListener(actionListener);
}
public void removeCloseActionListener(ActionListener actionListener){
closeButton.removeActionListener(actionListener);
}
private void createContentPane() {
createTitleTextArea();
createContentTextArea();
}
private void createTitleTextArea() {
if (StringUtils.isNotEmpty(title)) {
titleTextArea = createTextArea(title, FONT, TITLE_COLOR);
this.add(titleTextArea);
}
}
private void createContentTextArea() {
if (StringUtils.isNotEmpty(content)) {
contentTextArea = createTextArea(content, FONT, CONTENT_COLOR);
this.add(contentTextArea);
}
}
private UITextPane createTextArea(String str, Font font, Color foreground) {
UITextPane textArea= new UITextPane(){
@Override
public Insets getInsets() {
return new Insets(0, 0, 0, 0);
}
};
textArea.setText(str);
textArea.setEnabled(false);
textArea.setDisabledTextColor(foreground);
textArea.setBorder(null);
textArea.setFont(font);
textArea.setOpaque(false);
textArea.setForeground(foreground);
StyledDocument doc = textArea.getStyledDocument();
SimpleAttributeSet center = new SimpleAttributeSet();
StyleConstants.setAlignment(center, StyleConstants.ALIGN_CENTER);
doc.setParagraphAttributes(0, doc.getLength(), center, false);
return textArea;
}
protected int getDefaultHeight() {
Dimension titleSize = calTextSize(titleTextArea, getDefaultTextAreaMaxWidth());
Dimension contentSize = calTextSize(contentTextArea, getDefaultTextAreaMaxWidth());
return (isTailVertical() ? TAIL_HEIGHT : 0) + HEADER_HEIGHT + titleSize.height + (titleSize.height == 0 ? 0 : 5) + contentSize.height + getVerticalInsets();
}
private LayoutManager getLayoutManager() {
return new LayoutManager() {
@Override
public void addLayoutComponent(String name, Component comp) {
}
@Override
public void removeLayoutComponent(Component comp) {
}
@Override
public Dimension preferredLayoutSize(Container parent) {
return parent.getPreferredSize();
}
@Override
public Dimension minimumLayoutSize(Container parent) {
return null;
}
@Override
public void layoutContainer(Container parent) {
}
};
}
@Override
protected void paintBubbleBg(Graphics2D g2) {
super.paintBubbleBg(g2);
paintHeaderBg(g2);
}
private void paintHeaderBg(Graphics2D g2) {
g2.setColor(HEADER_COLOR);
Rectangle bounds = getRectBounds();
g2.fillRoundRect(bounds.x, bounds.y, bounds.width, HEADER_HEIGHT, 10, 10);
}
private int countLines(JTextPane textArea, int max_width) {
AttributedString text = new AttributedString(textArea.getText());
text.addAttribute(TextAttribute.FONT, textArea.getFont());
FontRenderContext frc = textArea.getFontMetrics(textArea.getFont())
.getFontRenderContext();
AttributedCharacterIterator charIt = text.getIterator();
LineBreakMeasurer lineMeasurer = new LineBreakMeasurer(charIt, frc);
lineMeasurer.setPosition(charIt.getBeginIndex());
int lines = 0;
while (lineMeasurer.getPosition() < charIt.getEndIndex()) {
lineMeasurer.nextLayout(max_width);
lines++;
}
return lines;
}
private Dimension calTextSize(JTextPane textArea, int maxWidth) {
if (textArea == null) {
return new Dimension(0, 0);
}
FontMetrics fontMetrics = GraphHelper.getFontMetrics(textArea.getFont());
int line = countLines(textArea, maxWidth);
int width = maxWidth;
if (line == 1) {
width = fontMetrics.stringWidth(textArea.getText());
}
int height = fontMetrics.getHeight() * line;
return new Dimension(width, height);
}
private int getTextAreaMaxWidth() {
return getWidth() - (isTailHorizontal() ? TAIL_HEIGHT : 0) -getHorizontalInsets();
}
private int getDefaultTextAreaMaxWidth() {
return BUBBLE_WIDTH - getHorizontalInsets();
}
private int getHorizontalInsets() {
return DEFAULT_INSET.left + DEFAULT_INSET.right;
}
private int getVerticalInsets() {
return DEFAULT_INSET.top + DEFAULT_INSET.bottom;
}
}

98
designer-base/src/main/java/com/fr/design/mainframe/guide/utils/ScreenImage.java

@ -0,0 +1,98 @@
package com.fr.design.mainframe.guide.utils;
import javax.swing.JComponent;
import javax.swing.SwingUtilities;
import java.awt.AWTException;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.image.BufferedImage;
public class ScreenImage {
public static BufferedImage createImage(JComponent component) {
return ScreenImage.createImage(component, getRegion(component));
}
public static BufferedImage createImage(JComponent component, Rectangle region) {
if (! component.isDisplayable()) {
Dimension d = component.getSize();
if (d.width == 0 || d.height == 0) {
d = component.getPreferredSize();
component.setSize( d );
}
layoutComponent( component );
}
BufferedImage image = new BufferedImage(region.width, region.height, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = image.createGraphics();
if (! component.isOpaque()) {
g2d.setColor( component.getBackground() );
g2d.fillRect(region.x, region.y, region.width, region.height);
}
g2d.translate(-region.x, -region.y);
component.print( g2d );
g2d.dispose();
return image;
}
public static BufferedImage createImage(Component component)
throws AWTException {
Point p = new Point(0, 0);
SwingUtilities.convertPointToScreen(p, component);
Rectangle region = component.getBounds();
region.x = p.x;
region.y = p.y;
return ScreenImage.createImage(region);
}
public static BufferedImage createImageWithModal(JComponent component) {
Rectangle region = getRegion(component);
BufferedImage image = new BufferedImage(region.width, region.height, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = image.createGraphics();
g2d.drawImage(createImage(component), 0, 0, null);
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.6f));
g2d.setColor(Color.BLACK);
g2d.fillRect(0, 0, region.width, region.height);
g2d.dispose();
return image;
}
public static BufferedImage createImage(Rectangle region)
throws AWTException {
BufferedImage image = new Robot().createScreenCapture( region );
return image;
}
private static Rectangle getRegion(Component component) {
Dimension d = component.getSize();
if (d.width == 0 || d.height == 0) {
d = component.getPreferredSize();
component.setSize( d );
}
return new Rectangle(0, 0, d.width, d.height);
}
static void layoutComponent(Component component) {
synchronized (component.getTreeLock()) {
component.doLayout();
if (component instanceof Container) {
for (Component child : ((Container)component).getComponents()) {
layoutComponent(child);
}
}
}
}
}

76
designer-base/src/main/java/com/fr/design/mainframe/theme/FormThemeProfilePane.java

@ -36,46 +36,56 @@ public class FormThemeProfilePane extends TemplateThemeProfilePane<FormTheme> {
}
@Override
protected JPanel createCustomEditorsPane() {
JPanel container = super.createCustomEditorsPane();
formBodyStyleSettingPane = new FormBodyStyleEditPane();
addCustomEditorPane(i18nText("Fine-Design_Predefined_Template_Background"), formBodyStyleSettingPane);
addCustomEditorPane(i18nText("Fine-Design_Predefined_Cell_Style"), createCellStyleSettingPane());
addCustomEditorPane(i18nText("Fine-Design_Predefined_Chart_Style"), createChartStyleSettingPane());
componentStyleSettingPane = new ComponentStyleEditPane();
addCustomEditorPane(i18nText("Fine-Design_Predefined_Component_Style"), componentStyleSettingPane);
return container;
public TemplateThemeEditorPane<FormTheme> createThemeEditorPane() {
return new FormThemeEditorPane(config);
}
@Override
protected JPanel createChartStyleSettingPane() {
JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane();
chartStyleSettingPane = new ChartStyleFormEditPane();
container.add(chartStyleSettingPane);
return container;
public String title4PopupWindow() {
return Toolkit.i18nText("Fine-Design_Basic_Form_Theme_Profile_Dialog_Title");
}
@Override
public void populateBean4CustomEditors(FormTheme theme) {
super.populateBean4CustomEditors(theme);
formBodyStyleSettingPane.populateBean(theme.getBodyStyle());
componentStyleSettingPane.populateBean(theme.getComponentStyle());
}
private static class FormThemeEditorPane extends TemplateThemeEditorPane<FormTheme> {
@Override
public void updateBean(FormTheme theme) {
ThemedFormBodyStyle formBodyStyle = formBodyStyleSettingPane.updateBean();
theme.setBodyStyle(formBodyStyle);
private final FormBodyStyleEditPane formBodyStyleSettingPane;
private final ComponentStyleEditPane componentStyleSettingPane;
ThemedComponentStyle componentStyle = componentStyleSettingPane.updateBean();
theme.setComponentStyle(componentStyle);
}
public FormThemeEditorPane(TemplateThemeConfig<FormTheme> config) {
super(config);
formBodyStyleSettingPane = new FormBodyStyleEditPane();
addCustomEditorPane(i18nText("Fine-Design_Predefined_Template_Background"), formBodyStyleSettingPane);
@Override
public String title4PopupWindow() {
return Toolkit.i18nText("Fine-Design_Basic_Form_Theme_Profile_Dialog_Title");
addCustomEditorPane(i18nText("Fine-Design_Predefined_Cell_Style"), createCellStyleSettingPane());
addCustomEditorPane(i18nText("Fine-Design_Predefined_Chart_Style"), createChartStyleSettingPane());
componentStyleSettingPane = new ComponentStyleEditPane();
addCustomEditorPane(i18nText("Fine-Design_Predefined_Component_Style"), componentStyleSettingPane);
}
@Override
protected JPanel createChartStyleSettingPane() {
JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane();
chartStyleSettingPane = new ChartStyleFormEditPane();
container.add(chartStyleSettingPane);
return container;
}
@Override
protected void populateBean4CustomEditors(FormTheme theme) {
super.populateBean4CustomEditors(theme);
formBodyStyleSettingPane.populateBean(theme.getBodyStyle());
componentStyleSettingPane.populateBean(theme.getComponentStyle());
}
@Override
protected void updateBean4CustomEditors(FormTheme theme) {
super.updateBean4CustomEditors(theme);
ThemedFormBodyStyle formBodyStyle = formBodyStyleSettingPane.updateBean();
theme.setBodyStyle(formBodyStyle);
ThemedComponentStyle componentStyle = componentStyleSettingPane.updateBean();
theme.setComponentStyle(componentStyle);
}
}
}

45
designer-base/src/main/java/com/fr/design/mainframe/theme/ReportThemeProfilePane.java

@ -25,28 +25,37 @@ public class ReportThemeProfilePane extends TemplateThemeProfilePane<ReportTheme
}
@Override
protected JPanel createCustomEditorsPane() {
JPanel container = super.createCustomEditorsPane();
this.reportBodyStyleSettingPane = new ReportBodyStyleEditPane();
addCustomEditorPane(Toolkit.i18nText("Fine-Design_Predefined_Template_Background"), reportBodyStyleSettingPane);
addCustomEditorPane(Toolkit.i18nText("Fine-Design_Predefined_Cell_Style"), createCellStyleSettingPane());
addCustomEditorPane(Toolkit.i18nText("Fine-Design_Predefined_Chart_Style"), createChartStyleSettingPane());
return container;
}
@Override
public void populateBean4CustomEditors(ReportTheme theme) {
super.populateBean4CustomEditors(theme);
reportBodyStyleSettingPane.populateBean(theme.getBodyStyle());
}
@Override
public void updateBean(ReportTheme theme) {
theme.setBodyStyle(this.reportBodyStyleSettingPane.updateBean());
public TemplateThemeEditorPane<ReportTheme> createThemeEditorPane() {
return new ReportThemeEditorPane(config);
}
@Override
public String title4PopupWindow() {
return Toolkit.i18nText("Fine-Design_Basic_Report_Theme_Profile_Dialog_Title");
}
private static class ReportThemeEditorPane extends TemplateThemeEditorPane<ReportTheme> {
private final ReportBodyStyleEditPane reportBodyStyleSettingPane;
public ReportThemeEditorPane(TemplateThemeConfig<ReportTheme> config) {
super(config);
this.reportBodyStyleSettingPane = new ReportBodyStyleEditPane();
addCustomEditorPane(Toolkit.i18nText("Fine-Design_Predefined_Template_Background"), reportBodyStyleSettingPane);
addCustomEditorPane(Toolkit.i18nText("Fine-Design_Predefined_Cell_Style"), createCellStyleSettingPane());
addCustomEditorPane(Toolkit.i18nText("Fine-Design_Predefined_Chart_Style"), createChartStyleSettingPane());
}
@Override
public void populateBean4CustomEditors(ReportTheme theme) {
super.populateBean4CustomEditors(theme);
reportBodyStyleSettingPane.populateBean(theme.getBodyStyle());
}
@Override
public void updateBean4CustomEditors(ReportTheme theme) {
super.updateBean4CustomEditors(theme);
theme.setBodyStyle(this.reportBodyStyleSettingPane.updateBean());
}
}
}

1
designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeBlock.java

@ -64,6 +64,7 @@ public class TemplateThemeBlock<T extends TemplateTheme> extends JPanel {
TemplateThemeConfig<T> config,
TemplateThemeProfilePane<T> profilePane) {
this.name = name;
this.setName(name);
this.displayTheme4NewTemplateMarker = displayTheme4NewTemplateMarker;
this.config = config;
this.profilePane = profilePane;

297
designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeEditorPane.java

@ -0,0 +1,297 @@
package com.fr.design.mainframe.theme;
import com.fr.base.theme.FineColorFlushUtils;
import com.fr.base.theme.FineColorManager;
import com.fr.base.theme.TemplateTheme;
import com.fr.base.theme.TemplateThemeConfig;
import com.fr.base.theme.settings.ThemedCellStyleList;
import com.fr.base.theme.settings.ThemedColorScheme;
import com.fr.design.designer.IntervalConstants;
import com.fr.design.gui.frpane.AbstractAttrNoScrollPane;
import com.fr.design.gui.frpane.AttributeChangeListener;
import com.fr.design.gui.frpane.UITabbedPane;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.mainframe.theme.edit.CellStyleListEditPane;
import com.fr.design.mainframe.theme.edit.ChartStyleEditPane;
import com.fr.design.mainframe.theme.edit.ui.ColorListExtendedPane;
import com.fr.design.mainframe.theme.edit.ui.ColorListPane;
import com.fr.design.mainframe.theme.edit.ui.LabelUtils;
import com.fr.design.mainframe.theme.ui.AutoCheckTextField;
import com.fr.design.mainframe.theme.ui.AutoCheckThemeNameTextField;
import com.fr.design.mainframe.theme.ui.BorderUtils;
import com.fr.stable.StringUtils;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.util.List;
/**
* @author Starryi
* @version 1.0
* Created by Starryi on 2021/8/13
*/
public abstract class TemplateThemeEditorPane<T extends TemplateTheme> extends JPanel {
public static final int LEFT_TITLE_PANE_HEIGHT = 539;
public static final int RIGHT_PANE_WIDTH = 362;
public static final int RIGHT_PANE_HEIGHT = LEFT_TITLE_PANE_HEIGHT;
protected AutoCheckThemeNameTextField<T> nameTextField;
private UILabel nameErrorLabel;
protected ColorListPane colorListPane;
protected CellStyleListEditPane cellStyleSettingPane;
protected ChartStyleEditPane chartStyleSettingPane;
protected boolean isPopulating = false;
protected UITabbedPane uiTabbedPane;
private final TemplateThemeConfig<T> config;
private boolean refreshingThemedColor = false;
private T theme;
private AttributeChangeListener changeListener;
private AutoCheckTextField.CheckListener themeNameCheckListener;
public TemplateThemeEditorPane(TemplateThemeConfig<T> config) {
super();
this.config = config;
theme = config.createNewTheme();
initializePane();
}
private void initializePane() {
setLayout(new BorderLayout(0, 0));
setPreferredSize(new Dimension(RIGHT_PANE_WIDTH, RIGHT_PANE_HEIGHT));
JPanel nameEditPane = createNameEditPane();
add(nameEditPane, BorderLayout.NORTH);
JPanel settingPane = new JPanel(new BorderLayout(0, IntervalConstants.INTERVAL_L1));
settingPane.add(createColorSchemeEditPane(), BorderLayout.NORTH);
settingPane.add(createCustomEditorsPane(), BorderLayout.CENTER);
add(settingPane, BorderLayout.CENTER);
}
private JPanel createNameEditPane() {
nameErrorLabel = LabelUtils.createLabel(StringUtils.EMPTY, Color.RED);
nameErrorLabel.setVisible(false);
nameTextField = new AutoCheckThemeNameTextField<>();
nameTextField.setThemeConfig(config);
nameTextField.setEditable(false);
nameTextField.setEnabled(false);
nameTextField.setPreferredSize(new Dimension(165, 20));
nameTextField.setNameCheckListener(new AutoCheckTextField.CheckListener() {
@Override
public void onChecked(String error, boolean valid) {
nameErrorLabel.setVisible(StringUtils.isNotEmpty(error));
nameErrorLabel.setText(error);
themeNameCheckListener.onChecked(error, valid);
}
});
double p = TableLayout.PREFERRED;
JPanel container = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{
new Component[] { LabelUtils.createLabel(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Name")), nameTextField },
new Component[] { null, nameErrorLabel },
}, new double[] { 20, 20}, new double[] { p, 165}, IntervalConstants.INTERVAL_L1, IntervalConstants.INTERVAL_W0);
container.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0));
return container;
}
private JPanel createColorSchemeEditPane() {
colorListPane = new ColorListPane();
double p = TableLayout.PREFERRED;
double[] rowSize = new double[]{p, p, p};
double[] columnSize = {p, p};
JPanel colorListContainerPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
colorListContainerPane.add(colorListPane, BorderLayout.WEST);
UILabel tipLabel = LabelUtils.createLabel(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Color_Scheme_Edit_Tip"), new Color(153, 153, 153));
JPanel content = TableLayoutHelper.createGapTableLayoutPane(new JComponent[][]{
{LabelUtils.createLabel(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Color_Scheme_Edit_Label")), colorListContainerPane},
{null, tipLabel},
},
rowSize, columnSize, 18, 7);
content.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
JPanel borderContainer = new JPanel(new BorderLayout());
borderContainer.setBorder(BorderUtils.createTitleBorder(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Color_Scheme_Title")));
borderContainer.add(content);
JPanel container = new JPanel(new BorderLayout());
container.add(borderContainer, BorderLayout.CENTER);
colorListPane.addColorChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
if (refreshingThemedColor) {
return;
}
List<Color> colors = colorListPane.update();
refreshingThemedColor = true;
onColorSchemeChanged(colors);
refreshingThemedColor = false;
fireAttributeChange();
}
});
return container;
}
private void onColorSchemeChanged(List<Color> colors) {
FineColorManager.FineColorReplaceByColorScheme replaceByColorScheme = new FineColorManager.FineColorReplaceByColorScheme(colors);
T theme = updateBean();
FineColorFlushUtils.replaceCacheObject(theme, replaceByColorScheme);
FineColorManager.traverse(theme, replaceByColorScheme);
populateBean4CustomEditors(theme);
//图表渐变色
chartStyleSettingPane.populateGradientBar(colors);
this.repaint();
}
protected JPanel createCustomEditorsPane() {
JPanel container = new JPanel(new BorderLayout());
container.setBorder(BorderUtils.createTitleBorder(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Custom_Settings_Title")));
uiTabbedPane = new UITabbedPane();
uiTabbedPane.setBorder(BorderFactory.createEmptyBorder(10, 5, 10, 1));
container.add(uiTabbedPane, BorderLayout.CENTER);
return container;
}
public void addCustomEditorPane(String title, final Component component) {
AbstractAttrNoScrollPane settingPane = new NoBorderAbstractAttrNoScrollPane() {
@Override
protected JPanel createContentPane() {
JPanel contentPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
contentPane.add(component, BorderLayout.CENTER);
return contentPane;
}
};
settingPane.addAttributeChangeListener(new AttributeChangeListener() {
@Override
public void attributeChange() {
fireAttributeChange();
}
});
uiTabbedPane.addTab(title, settingPane);
}
protected JPanel createCellStyleSettingPane() {
JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane();
cellStyleSettingPane = new CellStyleListEditPane();
cellStyleSettingPane.registerAttrChangeListener(new AttributeChangeListener() {
@Override
public void attributeChange() {
fireAttributeChange();
}
});
container.add(cellStyleSettingPane);
return container;
}
protected JPanel createChartStyleSettingPane() {
JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane();
chartStyleSettingPane = new ChartStyleEditPane();
container.add(chartStyleSettingPane);
return container;
}
public void populateBean(T theme) {
this.theme = theme;
isPopulating = true;
String name = theme.getName();
setThemeNameEditable(StringUtils.isEmpty(name));
nameTextField.setText(name);
colorListPane.populate(theme.getColorScheme().getColors());
populateBean4CustomEditors(theme);
isPopulating = false;
}
protected void populateBean4CustomEditors(T theme) {
cellStyleSettingPane.populateBean(theme.getCellStyleList());
chartStyleSettingPane.populateBean(theme.getChartStyle());
}
public T updateBean() {
if (theme == null) {
theme = config.createNewTheme();
}
theme.setName(this.nameTextField.getText());
ThemedColorScheme colorScheme = theme.getColorScheme();
colorScheme.setColors(this.colorListPane.update());
theme.setColorScheme(colorScheme);
updateBean4CustomEditors(theme);
return theme;
}
protected void updateBean4CustomEditors(T theme) {
ThemedCellStyleList cellStyleConfig = this.cellStyleSettingPane.updateBean();
theme.setCellStyleList(cellStyleConfig);
theme.setChartStyle(this.chartStyleSettingPane.updateBean());
}
public void setThemeNameEditable(boolean editable) {
nameTextField.setEditable(editable);
nameTextField.setEnabled(editable);
}
public boolean checkNameValid() {
return nameTextField.checkValid();
}
public List<Color> getCurrentColorScheme() {
return colorListPane.update();
}
private void fireAttributeChange() {
if (!isPopulating && !refreshingThemedColor && changeListener != null) {
changeListener.attributeChange();
}
}
public void addAttributeChangeListener(AttributeChangeListener changeListener) {
this.changeListener = changeListener;
}
public void addThemeNameCheckListener(AutoCheckTextField.CheckListener checkListener) {
this.themeNameCheckListener = checkListener;
}
private static abstract class NoBorderAbstractAttrNoScrollPane extends AbstractAttrNoScrollPane {
@Override
protected void initContentPane() {
super.initContentPane();
if (leftContentPane != null) {
// 修正 AbstractAttrNoScrollPane 的默认行为
leftContentPane.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
}
}
}
}

30
designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeManagePane.java → designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeGridControlPane.java

@ -51,34 +51,34 @@ import static com.fr.design.i18n.Toolkit.i18nText;
* @version 1.0
* Created by Starryi on 2021/8/13
*/
public class TemplateThemeManagePane<T extends TemplateTheme> extends BasicPane {
public static final int CONTENT_WIDTH = TemplateThemeListPane.CONTENT_WIDTH + 10;
public static final int CONTENT_HEIGHT = TemplateThemeListPane.CONTENT_HEIGHT + 37;
public class TemplateThemeGridControlPane<T extends TemplateTheme> extends BasicPane {
public static final int CONTENT_WIDTH = TemplateThemeGridPane.CONTENT_WIDTH + 10;
public static final int CONTENT_HEIGHT = TemplateThemeGridPane.CONTENT_HEIGHT + 37;
private final RemoveThemeAction removeAction;
private final UIButton setTheme4NewTemplateButton;
private final TemplateThemeConfig<T> config;
private final TemplateThemeListPane<T> themeListPane;
private final TemplateThemeGridPane<T> themeListPane;
private final TemplateThemeProfilePane<T> profilePane;
private final AsyncThemeFetcher<T> asyncThemeFetcher;
public static TemplateThemeManagePane<FormTheme> createFormThemesManagerPane() {
public static TemplateThemeGridControlPane<FormTheme> createFormThemesManagerPane() {
FormThemeConfig config = FormThemeConfig.getInstance();
FormThemeProfilePane editPane = new FormThemeProfilePane(config);
return new TemplateThemeManagePane<>(config, editPane);
return new TemplateThemeGridControlPane<>(config, editPane);
}
public static TemplateThemeManagePane<ReportTheme> createReportThemesManagerPane() {
public static TemplateThemeGridControlPane<ReportTheme> createReportThemesManagerPane() {
ReportThemeConfig config = ReportThemeConfig.getInstance();
ReportThemeProfilePane editPane = new ReportThemeProfilePane(config);
return new TemplateThemeManagePane<>(config, editPane);
return new TemplateThemeGridControlPane<>(config, editPane);
}
public TemplateThemeManagePane(TemplateThemeConfig<T> config, TemplateThemeProfilePane<T> profilePane) {
public TemplateThemeGridControlPane(TemplateThemeConfig<T> config, TemplateThemeProfilePane<T> profilePane) {
this.config = config;
this.profilePane = profilePane;
this.themeListPane = new TemplateThemeListPane<>(true, config, profilePane);
this.themeListPane = new TemplateThemeGridPane<>(true, config, profilePane);
this.removeAction = new RemoveThemeAction(false);
this.setTheme4NewTemplateButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Pane_Default_Setting"));
this.asyncThemeFetcher = new AsyncThemeFetcher<>(1, config);
@ -179,7 +179,7 @@ public class TemplateThemeManagePane<T extends TemplateTheme> extends BasicPane
@Override
public void afterRollback() {
super.afterRollback();
FineJOptionPane.showMessageDialog(SwingUtilities.getWindowAncestor(TemplateThemeManagePane.this),
FineJOptionPane.showMessageDialog(SwingUtilities.getWindowAncestor(TemplateThemeGridControlPane.this),
i18nText("Fine-Design_Basic_Template_Theme_Operation_Failed_Tip"),
i18nText("Fine-Design_Basic_Alert"),
JOptionPane.WARNING_MESSAGE);
@ -225,11 +225,11 @@ public class TemplateThemeManagePane<T extends TemplateTheme> extends BasicPane
@Override
public void actionPerformed(ActionEvent e) {
T theme = TemplateThemeManagePane.this.themeListPane.getSelectedTheme();
T theme = TemplateThemeGridControlPane.this.themeListPane.getSelectedTheme();
if (theme == null) {
return;
}
int result = FineJOptionPane.showConfirmDialog(SwingUtilities.getWindowAncestor(TemplateThemeManagePane.this),
int result = FineJOptionPane.showConfirmDialog(SwingUtilities.getWindowAncestor(TemplateThemeGridControlPane.this),
Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Pane_Delete_Tip", theme.getName()),
Toolkit.i18nText("Fine-Design_Basic_Delete"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
if (result == JOptionPane.YES_OPTION) {
@ -237,7 +237,7 @@ public class TemplateThemeManagePane<T extends TemplateTheme> extends BasicPane
@Override
public void afterRollback() {
super.afterRollback();
FineJOptionPane.showMessageDialog(SwingUtilities.getWindowAncestor(TemplateThemeManagePane.this),
FineJOptionPane.showMessageDialog(SwingUtilities.getWindowAncestor(TemplateThemeGridControlPane.this),
i18nText("Fine-Design_Basic_Template_Theme_Operation_Failed_Tip"),
i18nText("Fine-Design_Basic_Alert"),
JOptionPane.WARNING_MESSAGE);
@ -269,7 +269,7 @@ public class TemplateThemeManagePane<T extends TemplateTheme> extends BasicPane
}
private void createNewTheme(T prototypeTheme) {
Window parent = SwingUtilities.getWindowAncestor(TemplateThemeManagePane.this);
Window parent = SwingUtilities.getWindowAncestor(TemplateThemeGridControlPane.this);
TemplateThemeProfileDialog<T> profileDialog = new TemplateThemeProfileDialog<>(parent, profilePane);
try {
T theme = (T) prototypeTheme.clone();

341
designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeGridPagesPane.java

@ -0,0 +1,341 @@
package com.fr.design.mainframe.theme;
import com.fr.base.ScreenResolution;
import com.fr.base.theme.FormTheme;
import com.fr.base.theme.FormThemeConfig;
import com.fr.base.theme.ReportTheme;
import com.fr.base.theme.ReportThemeConfig;
import com.fr.base.theme.TemplateTheme;
import com.fr.base.theme.TemplateThemeConfig;
import com.fr.design.ExtraDesignClassManager;
import com.fr.design.dialog.BasicPane;
import com.fr.design.event.ChangeEvent;
import com.fr.design.event.ChangeListener;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.gui.frpane.UITabbedPane;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.mainframe.theme.dialog.TemplateThemeDialog;
import com.fr.design.mainframe.theme.provider.ThemeManageActionProvider;
import com.fr.design.mainframe.theme.ui.BreadcrumbBar;
import com.fr.stable.ArrayUtils;
import com.fr.stable.unit.FU;
import com.fr.workspace.WorkContext;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.border.CompoundBorder;
import javax.swing.border.LineBorder;
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Stroke;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
/**
* @author Starryi
* @version 1.0
* Created by Starryi on 2021/10/9
*/
public class TemplateThemeGridPagesPane extends JPanel {
public static final String COMPLETE_BUTTON = "theme_button_complete";
private BreadcrumbBar breadcrumbBar;
private JPanel contentPane;
private CardLayout cardLayout;
private TemplateThemeGridPagePane themeUsingPane;
private TemplateThemeGridPagePane themeManagingPane;
private PageChangeListener pageChangeListener;
private TemplateThemeGridPagePane currentTemplateThemeGridPagePane;
public TemplateThemeGridPagesPane() {
initializePane();
}
private void initializePane() {
setLayout(new BorderLayout());
setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 10));
breadcrumbBar = new BreadcrumbBar();
breadcrumbBar.setBorder(BorderFactory.createEmptyBorder(0, 0, 10, 0));
add(breadcrumbBar, BorderLayout.NORTH);
contentPane = new JPanel();
contentPane.setBorder(new CompoundBorder(
new TopLineBorder(new Color(0xE0E0E1), 1),
BorderFactory.createEmptyBorder(10, 0, 0, 0)));
cardLayout = new CardLayout();
contentPane.setLayout(cardLayout);
add(contentPane, BorderLayout.CENTER);
themeUsingPane = new TemplateThemeUsingPane();
contentPane.add(themeUsingPane, themeUsingPane.getTitle());
themeManagingPane = new TemplateThemeManagingPane();
contentPane.add(themeManagingPane, themeManagingPane.getTitle());
showThemeUsingPane();
}
public void showThemeUsingPane() {
if (currentTemplateThemeGridPagePane != themeUsingPane) {
cardLayout.show(contentPane, themeUsingPane.getTitle());
currentTemplateThemeGridPagePane = themeUsingPane;
if (pageChangeListener != null) {
pageChangeListener.onPageChangeListener();
}
breadcrumbBar.clear();
breadcrumbBar.addCrumb(themeUsingPane.getTitle(), new BreadcrumbBar.BreadcrumbBackListener() {
@Override
public void onBreadcrumbBack(String text) {
cardLayout.show(contentPane, themeUsingPane.getTitle());
currentTemplateThemeGridPagePane = themeUsingPane;
if (pageChangeListener != null) {
pageChangeListener.onPageChangeListener();
}
}
});
}
}
public void showThemeManagingPane() {
if (currentTemplateThemeGridPagePane != themeManagingPane) {
cardLayout.show(contentPane, themeManagingPane.getTitle());
currentTemplateThemeGridPagePane = themeManagingPane;
if (pageChangeListener != null) {
pageChangeListener.onPageChangeListener();
}
breadcrumbBar.addCrumb(themeManagingPane.getTitle(), null);
}
}
public UIButton[] createLeftButtons() {
UIButton[] buttons = new UIButton[] {};
if (currentTemplateThemeGridPagePane != themeManagingPane && WorkContext.getCurrent().isRoot()) {
buttons = ArrayUtils.addAll(buttons, createOpenThemeManagerButton());
}
return buttons;
}
public UIButton[] createRightButtons() {
UIButton[] buttons = new UIButton[] {};
buttons = ArrayUtils.addAll(buttons, createExtraButtons());
buttons = ArrayUtils.addAll(buttons, createCompleteButton());
return buttons;
}
private UIButton createOpenThemeManagerButton() {
UIButton button = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Dialog_Title"));
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
showThemeManagingPane();
}
});
return button;
}
private UIButton[] createExtraButtons() {
List<UIButton> uiButtonList = new ArrayList<>();
Set<ThemeManageActionProvider> providers = ExtraDesignClassManager.getInstance().getArray(ThemeManageActionProvider.MARK_STRING);
for (ThemeManageActionProvider provider : providers) {
uiButtonList.add(provider.createButton(new ThemeManageActionProvider.ThemeManageActionContext() {
@Override
public TemplateThemeDialog getDialog() {
Container container = getRootPane().getParent();
if (container instanceof TemplateThemeDialog) {
return (TemplateThemeDialog) container;
}
return null;
}
@Override
public TemplateThemeConfig<? extends TemplateTheme> getConfig() {
return currentTemplateThemeGridPagePane.getConfig();
}
}));
}
return uiButtonList.toArray(new UIButton[]{});
}
private UIButton createCompleteButton() {
UIButton button = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Dialog_Complete"));
button.setName(COMPLETE_BUTTON);
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Container container = getRootPane().getParent();
if (container instanceof TemplateThemeDialog) {
((TemplateThemeDialog) container).exit();
}
}
});
return button;
}
public void exit() {
themeUsingPane.exit();
themeManagingPane.exit();
}
public void setPageChangeListener(PageChangeListener changeListener) {
this.pageChangeListener = changeListener;
}
public interface PageChangeListener {
void onPageChangeListener();
}
public static class TopLineBorder extends LineBorder {
private final FU fu;
private TopLineBorder(Color color, int thickness) {
super(color, thickness);
fu = FU.getInstance(thickness);
}
@Override
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
Graphics2D g2d = (Graphics2D)g;
Color oldColor = g2d.getColor();
Stroke oldStroke = g2d.getStroke();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(getLineColor());
int thickness = Math.max(1, fu.toPixI(ScreenResolution.getScreenResolution()));
g2d.setStroke(new BasicStroke(thickness));
g2d.drawLine(0, 0, width, thickness);
g2d.setStroke(oldStroke);
g2d.setColor(oldColor);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
}
}
public abstract static class TemplateThemeGridPagePane extends BasicPane {
public abstract TemplateThemeConfig<? extends TemplateTheme> getConfig();
public void exit() { }
}
public static class TemplateThemeUsingPane extends TemplateThemeGridPagePane {
private final JTemplate<?,?> template;
public final TemplateThemeGridPane<? extends TemplateTheme> themeListPane;
public TemplateThemeUsingPane() {
super();
setLayout(new BorderLayout());
setBorder(new CompoundBorder(
BorderFactory.createLineBorder(new Color(0xE0E0E1)),
BorderFactory.createEmptyBorder(0, 10, 0, 10)));
template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
TemplateThemeConfig<? extends TemplateTheme> config = template.getUsingTemplateThemeConfig();
themeListPane = new TemplateThemeGridPane<>(false, config, null);
themeListPane.startListenThemeConfig();
themeListPane.setSelectedChangeListener(new ChangeListener() {
@Override
public void fireChanged(ChangeEvent event) {
TemplateTheme theme = themeListPane.getSelectedTheme();
if (theme != null) {
template.setTemplateTheme(theme);
themeListPane.repaint();
}
}
});
add(themeListPane, BorderLayout.CENTER);
}
@Override
public TemplateThemeConfig<? extends TemplateTheme> getConfig() {
return template.getUsingTemplateThemeConfig();
}
@Override
public void exit() {
themeListPane.stopListenThemeConfig();
themeListPane.stopAsyncFetchTheme();
}
@Override
protected String title4PopupWindow() {
return Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Using_Dialog_Title");
}
}
public static class TemplateThemeManagingPane extends TemplateThemeGridPagePane {
public static final int CONTENT_WIDTH = TemplateThemeGridControlPane.CONTENT_WIDTH + 4;
public static final int CONTENT_HEIGHT = TemplateThemeGridControlPane.CONTENT_HEIGHT + 10;
private final UITabbedPane tabbedPane;
private final TemplateThemeGridControlPane<FormTheme> formThemesManagerPane;
private final TemplateThemeGridControlPane<ReportTheme> reportThemesManagerPane;
public TemplateThemeManagingPane() {
setLayout(FRGUIPaneFactory.createBorderLayout());
setPreferredSize(new Dimension(CONTENT_WIDTH, CONTENT_HEIGHT));
tabbedPane = new UITabbedPane();
add(tabbedPane, BorderLayout.CENTER);
formThemesManagerPane = TemplateThemeGridControlPane.createFormThemesManagerPane();
formThemesManagerPane.startListenThemeConfig();
reportThemesManagerPane = TemplateThemeGridControlPane.createReportThemesManagerPane();
reportThemesManagerPane.startListenThemeConfig();
tabbedPane.addTab(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Dialog_Form_Tab"), formThemesManagerPane);
tabbedPane.addTab(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Dialog_Report_Tab"), reportThemesManagerPane);
tabbedPane.setSelectedIndex(0);
JTemplate<?,?> template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
TemplateThemeConfig<? extends TemplateTheme> config = template.getUsingTemplateThemeConfig();
if (config == reportThemesManagerPane.getConfig()) {
tabbedPane.setSelectedIndex(1);
}
}
@Override
public TemplateThemeConfig<? extends TemplateTheme> getConfig() {
if (tabbedPane.getSelectedIndex() == 0) {
return FormThemeConfig.getInstance();
} else {
return ReportThemeConfig.getInstance();
}
}
@Override
public void exit() {
formThemesManagerPane.stopListenThemeConfig();
formThemesManagerPane.stopAsyncFetchTheme();
reportThemesManagerPane.stopListenThemeConfig();
reportThemesManagerPane.stopAsyncFetchTheme();
}
@Override
protected String title4PopupWindow() {
return Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Dialog_Title");
}
}
}

18
designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeListPane.java → designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeGridPane.java

@ -2,7 +2,6 @@ package com.fr.design.mainframe.theme;
import com.fr.base.theme.TemplateTheme;
import com.fr.base.theme.TemplateThemeConfig;
import com.fr.base.theme.settings.ThemeThumbnail;
import com.fr.design.designer.IntervalConstants;
import com.fr.design.dialog.BasicPane;
import com.fr.design.event.ChangeEvent;
@ -13,6 +12,7 @@ import com.fr.stable.StringUtils;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.ScrollPaneConstants;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
@ -27,12 +27,12 @@ import java.util.Map;
* @version 1.0
* Created by Starryi on 2021/8/13
*/
public class TemplateThemeListPane<T extends TemplateTheme> extends BasicPane {
public class TemplateThemeGridPane<T extends TemplateTheme> extends BasicPane {
public static final int BLOCK_COUNT_ROW_LINE = 3;
public static final int BLOCK_GAP = IntervalConstants.INTERVAL_L1;
public static final int CONTENT_WIDTH = TemplateThemeBlock.CONTENT_WIDTH * BLOCK_COUNT_ROW_LINE + BLOCK_GAP * (BLOCK_COUNT_ROW_LINE - 1) + 10;
public static final int BLOCK_ROWS_PER_PAGE = 3;
public static final int CONTENT_HEIGHT = TemplateThemeBlock.CONTENT_HEIGHT * BLOCK_ROWS_PER_PAGE + BLOCK_GAP * (BLOCK_ROWS_PER_PAGE + 1);
public static final int CONTENT_HEIGHT = Math.min(527, TemplateThemeBlock.CONTENT_HEIGHT * BLOCK_ROWS_PER_PAGE + BLOCK_GAP * (BLOCK_ROWS_PER_PAGE + 1));
public static final int ASYNC_FETCH_THEME_THREAD_COUNT = 10;
private final AsyncThemeFetcher<T> asyncThemeFetcher;
@ -51,7 +51,7 @@ public class TemplateThemeListPane<T extends TemplateTheme> extends BasicPane {
private ChangeListener changeListener;
public TemplateThemeListPane(boolean displayTheme4NewTemplateMarker, TemplateThemeConfig<T> config, TemplateThemeProfilePane<T> profilePane) {
public TemplateThemeGridPane(boolean displayTheme4NewTemplateMarker, TemplateThemeConfig<T> config, TemplateThemeProfilePane<T> profilePane) {
this.displayTheme4NewTemplateMarker = displayTheme4NewTemplateMarker;
this.config = config;
this.profilePane = profilePane;
@ -64,14 +64,14 @@ public class TemplateThemeListPane<T extends TemplateTheme> extends BasicPane {
setLayout(FRGUIPaneFactory.createBorderLayout());
setPreferredSize(new Dimension(CONTENT_WIDTH, CONTENT_HEIGHT));
contentListPane.setBorder(BorderFactory.createEmptyBorder(BLOCK_GAP, 0, BLOCK_GAP, 0));
contentListPane.setBorder(BorderFactory.createEmptyBorder(BLOCK_GAP, 0, BLOCK_GAP, 10));
contentListPane.setLayout(new GridLayout(0, BLOCK_COUNT_ROW_LINE, BLOCK_GAP, BLOCK_GAP));
fillContentListPane();
JPanel wrapper = FRGUIPaneFactory.createBorderLayout_S_Pane();
wrapper.add(contentListPane, BorderLayout.NORTH);
UIScrollPane scrollPane = new UIScrollPane(wrapper);
UIScrollPane scrollPane = new UIScrollPane(contentListPane);
scrollPane.setPreferredSize(new Dimension(CONTENT_WIDTH, CONTENT_HEIGHT));
scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
scrollPane.setBorder(BorderFactory.createEmptyBorder());
add(scrollPane, BorderLayout.CENTER);

8
designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemePreviewPane.java

@ -48,9 +48,6 @@ public abstract class TemplateThemePreviewPane<T extends TemplateTheme> extends
int height = getHeight();
try {
// 使用TYPE_INT_RGB和new Color(255, 255, 255, 1)设置有透明背景buffer image,
// 使得创建出来的透明像素是(255, 255, 255, 1),而不是(0, 0, 0, 0)
// 这样不支持透明通道缩略图的旧设计器打开新设计器创建的模版时,就不会创建出拥有黑色背景的缩略图
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = image.createGraphics();
// 创建一个支持透明背景的buffer image
@ -58,8 +55,6 @@ public abstract class TemplateThemePreviewPane<T extends TemplateTheme> extends
g2d.dispose();
g2d = image.createGraphics();
g2d.fillRect(0, 0, width, height);
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.clipRect(0, 0, width, height);
@ -80,6 +75,9 @@ public abstract class TemplateThemePreviewPane<T extends TemplateTheme> extends
@Override
public void paintComponent(Graphics g) {
g.clearRect(0, 0, PREVIEW_WIDTH, PREVIEW_HEIGHT);
// 添加个默认白色,否则因为上面的clearRect导致无背景时会出现黑色
g.setColor(Color.WHITE);
g.fillRect(0, 0, PREVIEW_WIDTH, PREVIEW_HEIGHT);
paintBackground((Graphics2D) g);
}

518
designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeProfilePane.java

@ -1,58 +1,39 @@
package com.fr.design.mainframe.theme;
import com.fr.base.theme.FineColorFlushUtils;
import com.fr.base.theme.FineColorManager;
import com.fr.base.theme.TemplateTheme;
import com.fr.base.theme.TemplateThemeConfig;
import com.fr.base.theme.settings.ThemeThumbnail;
import com.fr.base.theme.settings.ThemedCellStyleList;
import com.fr.base.theme.settings.ThemedColorScheme;
import com.fr.design.designer.IntervalConstants;
import com.fr.design.dialog.BasicPane;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.gui.frpane.AbstractAttrNoScrollPane;
import com.fr.design.gui.frpane.AttributeChangeListener;
import com.fr.design.gui.frpane.UITabbedPane;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.mainframe.theme.dialog.TemplateThemeProfileDialog;
import com.fr.design.mainframe.theme.edit.CellStyleListEditPane;
import com.fr.design.mainframe.theme.edit.ChartStyleEditPane;
import com.fr.design.mainframe.theme.edit.ui.ColorListExtendedPane;
import com.fr.design.mainframe.theme.edit.ui.ColorListPane;
import com.fr.design.mainframe.theme.edit.ui.LabelUtils;
import com.fr.design.mainframe.theme.ui.AutoCheckTextField;
import com.fr.design.mainframe.theme.ui.AutoCheckThemeNameTextField;
import com.fr.design.mainframe.theme.ui.BorderUtils;
import com.fr.design.mainframe.toast.DesignerToastMsgUtil;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.general.Inter;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.StringUtils;
import com.fr.transaction.CallBackAdaptor;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.List;
import static com.fr.design.i18n.Toolkit.i18nText;
@ -61,71 +42,35 @@ import static com.fr.design.i18n.Toolkit.i18nText;
* @version 1.0
* Created by Starryi on 2021/8/13
*/
public abstract class TemplateThemeProfilePane<T extends TemplateTheme> extends AbstractAttrNoScrollPane {
public abstract class TemplateThemeProfilePane<T extends TemplateTheme> extends BasicPane {
public static final int TITLE_BORDER_FONT = 12;
public static final int LEFT_TITLE_PANE_WIDTH = 627;
public static final int LEFT_TITLE_PANE_HEIGHT = 539;
public static final int PREVIEW_PANE_WIDTH = LEFT_TITLE_PANE_WIDTH - 10;
public static final int PREVIEW_PANE_HEIGHT = LEFT_TITLE_PANE_HEIGHT - TITLE_BORDER_FONT - 16;
public static final int RIGHT_PANE_WIDTH = 362;
public static final int RIGHT_PANE_HEIGHT = LEFT_TITLE_PANE_HEIGHT;
public static final int COLOR_SCHEME_TITLE_PANE_WIDTH = 298;
public static final int COLOR_SCHEME_TITLE_PANE_HEIGHT = 174 + TITLE_BORDER_FONT / 2;
protected TemplateThemePreviewPane<T> themePreviewPane;
protected UITextField nameTextField;
private UILabel nameErrorLabel;
protected ColorListPane colorListPane;
private ColorListExtendedPane colorListExtendedPane;
protected CellStyleListEditPane cellStyleSettingPane;
protected ChartStyleEditPane chartStyleSettingPane;
protected TemplateThemeEditorPane<T> themeEditorPane;
protected boolean isPopulating = false;
protected UITabbedPane uiTabbedPane;
protected boolean isMutable = false;
private final TemplateThemeConfig<T> config;
protected final TemplateThemeConfig<T> config;
private UIButton saveButton = new UIButton();
private UIButton saveAsButton = new UIButton();
private boolean refreshingThemedColor = false;
private boolean currentIsNewTheme;
private T theme;
public TemplateThemeProfilePane(TemplateThemeConfig<T> config) {
super();
this.config = config;
theme = config.createNewTheme();
}
@Override
protected JPanel createContentPane() {
JPanel container = new JPanel(new BorderLayout(5, 0));
container.add(createLeftPane(), BorderLayout.CENTER);
container.add(createRightPane(), BorderLayout.EAST);
addAttributeChangeListener(new AttributeChangeListener() {
@Override
public void attributeChange() {
if (!isPopulating && !refreshingThemedColor) {
valueChangeAction();
}
}
});
return container;
}
@Override
protected void initContentPane() {
super.initContentPane();
if (leftContentPane != null) {
// 修正 AbstractAttrNoScrollPane 的默认行为
leftContentPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 6));
}
initializePane();
}
public void valueChangeAction() {
themePreviewPane.refresh(updateBean());
private void initializePane() {
setLayout(new BorderLayout(5, 0));
setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 6));
add(createLeftPane(), BorderLayout.CENTER);
add(createRightPane(), BorderLayout.EAST);
}
@Override
@ -149,220 +94,55 @@ public abstract class TemplateThemeProfilePane<T extends TemplateTheme> extends
return titleContainer;
}
private JPanel createRightPane() {
JPanel container = new JPanel(new BorderLayout(0, 0));
container.setPreferredSize(new Dimension(RIGHT_PANE_WIDTH, RIGHT_PANE_HEIGHT));
JPanel nameEditPane = createNameEditPane();
container.add(nameEditPane, BorderLayout.NORTH);
JPanel settingPane = new JPanel(new BorderLayout(0, IntervalConstants.INTERVAL_L1));
container.add(settingPane, BorderLayout.CENTER);
settingPane.add(createColorSchemeEditPane(), BorderLayout.NORTH);
settingPane.add(createCustomEditorsPane(), BorderLayout.CENTER);
uiTabbedPane.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
valueChangeAction();
}
});
return container;
}
private JPanel createNameEditPane() {
nameErrorLabel = LabelUtils.createLabel(StringUtils.EMPTY, Color.RED);
nameErrorLabel.setVisible(false);
nameTextField = new UITextField();
nameTextField.setEnabled(false);
nameTextField.setPreferredSize(new Dimension(165, 20));
nameTextField.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void insertUpdate(DocumentEvent e) {
if (isEnabled()) {
checkThemeCanBeSavedAndUpdateUI(currentIsNewTheme, false, currentIsNewTheme, true, nameTextField, nameErrorLabel, saveButton);
}
}
@Override
public void removeUpdate(DocumentEvent e) {
if (isEnabled()) {
checkThemeCanBeSavedAndUpdateUI(currentIsNewTheme, false, currentIsNewTheme, true, nameTextField, nameErrorLabel, saveButton);
}
}
@Override
public void changedUpdate(DocumentEvent e) {
}
});
nameTextField.addFocusListener(new FocusAdapter() {
@Override
public void focusGained(FocusEvent e) {
if (isEnabled()) {
checkThemeCanBeSavedAndUpdateUI(currentIsNewTheme, false, currentIsNewTheme, true, nameTextField, nameErrorLabel, saveButton);
}
}
themeEditorPane = createThemeEditorPane();
themeEditorPane.addAttributeChangeListener(new AttributeChangeListener() {
@Override
public void focusLost(FocusEvent e) {
if (isEnabled()) {
checkThemeCanBeSavedAndUpdateUI(currentIsNewTheme, true, currentIsNewTheme, true, nameTextField, nameErrorLabel, saveButton);
public void attributeChange() {
if (isPopulating) {
return;
}
themePreviewPane.refresh(updateBean());
saveButton.setEnabled(themeEditorPane.checkNameValid() && isMutable);
}
});
double p = TableLayout.PREFERRED;
JPanel container = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{
new Component[] { LabelUtils.createLabel(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Name")), nameTextField },
new Component[] { null, nameErrorLabel },
}, new double[] { 20, 20}, new double[] { p, 165}, IntervalConstants.INTERVAL_L1, IntervalConstants.INTERVAL_W0);
container.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0));
return container;
}
private JPanel createColorSchemeEditPane() {
colorListPane = new ColorListPane();
colorListExtendedPane = new ColorListExtendedPane();
JPanel extendedContainer = FRGUIPaneFactory.createBorderLayout_S_Pane();
colorListExtendedPane.setBackground(null);
colorListExtendedPane.setOpaque(false);
extendedContainer.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
extendedContainer.setBackground(Color.WHITE);
extendedContainer.add(colorListExtendedPane);
double p = TableLayout.PREFERRED;
double[] rowSize = new double[]{p, p, p};
double[] columnSize = {p, p};
JPanel colorListContainerPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
colorListContainerPane.add(colorListPane, BorderLayout.WEST);
JPanel previewLabelPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
previewLabelPane.add(LabelUtils.createLabel(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Color_Scheme_Preview_Label")), BorderLayout.NORTH);
UILabel tipLabel = LabelUtils.createLabel(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Color_Scheme_Edit_Tip"), new Color(153, 153, 153));
tipLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 5, 0));
JPanel content = TableLayoutHelper.createGapTableLayoutPane(new JComponent[][]{
{LabelUtils.createLabel(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Color_Scheme_Edit_Label")), colorListContainerPane},
{null, tipLabel},
{previewLabelPane, extendedContainer},
},
rowSize, columnSize, 18, 7);
content.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
JPanel borderContainer = new JPanel(new BorderLayout());
borderContainer.setPreferredSize(new Dimension(COLOR_SCHEME_TITLE_PANE_WIDTH, COLOR_SCHEME_TITLE_PANE_HEIGHT));
borderContainer.setBorder(BorderUtils.createTitleBorder(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Color_Scheme_Title")));
borderContainer.add(content);
JPanel container = new JPanel(new BorderLayout());
container.add(borderContainer, BorderLayout.WEST);
colorListPane.addColorChangeListener(new ChangeListener() {
themeEditorPane.addThemeNameCheckListener(new AutoCheckTextField.CheckListener() {
@Override
public void stateChanged(ChangeEvent e) {
if (refreshingThemedColor) {
public void onChecked(String error, boolean valid) {
if (isPopulating) {
return;
}
List<Color> colors = colorListPane.update();
refreshingThemedColor = true;
onColorSchemeChanged(colors);
refreshingThemedColor = false;
saveButton.setEnabled(valid && isMutable);
}
});
return container;
return themeEditorPane;
}
protected JPanel createCustomEditorsPane() {
JPanel container = new JPanel(new BorderLayout());
container.setBorder(BorderUtils.createTitleBorder(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Custom_Settings_Title")));
uiTabbedPane = new UITabbedPane();
uiTabbedPane.setBorder(BorderFactory.createEmptyBorder(10, 5, 10, 1));
container.add(uiTabbedPane, BorderLayout.NORTH);
public abstract TemplateThemePreviewPane<T> createThemePreviewPane();
public abstract TemplateThemeEditorPane<T> createThemeEditorPane();
return container;
}
public void addCustomEditorPane(String title, JComponent component) {
component.setPreferredSize(new Dimension(317, 239));
uiTabbedPane.addTab(title, component);
}
protected JPanel createCellStyleSettingPane() {
JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane();
cellStyleSettingPane = new CellStyleListEditPane();
cellStyleSettingPane.registerAttrChangeListener(new AttributeChangeListener() {
@Override
public void attributeChange() {
valueChangeAction();
}
});
container.add(cellStyleSettingPane);
return container;
}
protected JPanel createChartStyleSettingPane() {
JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane();
chartStyleSettingPane = new ChartStyleEditPane();
container.add(chartStyleSettingPane);
return container;
}
public void populateBean(T theme) {
isPopulating = true;
public abstract TemplateThemePreviewPane<T> createThemePreviewPane();
isMutable = theme.isMutable();
public void onColorSchemeChanged(List<Color> colors) {
colorListExtendedPane.populate(colors);
FineColorManager.FineColorReplaceByColorScheme replaceByColorScheme = new FineColorManager.FineColorReplaceByColorScheme(colors);
T theme = updateBean();
FineColorFlushUtils.replaceCacheObject(theme, replaceByColorScheme);
FineColorManager.traverse(theme, replaceByColorScheme);
populateBean4CustomEditors(theme);
//图表渐变色
chartStyleSettingPane.populateGradientBar(colors);
themeEditorPane.populateBean(theme);
themePreviewPane.refresh(theme);
this.repaint();
}
public void populateBean(T theme) {
this.theme = theme;
isPopulating = true;
String name = theme.getName();
currentIsNewTheme = config.cachedFetch(name) == null;
nameTextField.setText(name);
nameTextField.setEnabled(StringUtils.isEmpty(name));
if (saveButton != null) {
saveButton.setEnabled(theme.isMutable() && !currentIsNewTheme);
saveButton.setEnabled(isMutable);
}
if (saveAsButton != null) {
saveAsButton.setEnabled(!currentIsNewTheme);
saveAsButton.setEnabled(StringUtils.isNotEmpty(name));
}
colorListPane.populate(theme.getColorScheme().getColors());
colorListExtendedPane.populate(colorListPane.update());
populateBean4CustomEditors(theme);
themePreviewPane.refresh(theme);
isPopulating = false;
}
protected void populateBean4CustomEditors(T theme) {
cellStyleSettingPane.populateBean(theme.getCellStyleList());
chartStyleSettingPane.populateBean(theme.getChartStyle());
}
public T updateBean() {
if (theme == null) {
theme = config.createNewTheme();
}
theme.setName(this.nameTextField.getText());
T theme = themeEditorPane.updateBean();
Image thumbnailImage = themePreviewPane.createThumbnailImage();
if (thumbnailImage != null) {
@ -371,24 +151,55 @@ public abstract class TemplateThemeProfilePane<T extends TemplateTheme> extends
theme.setThumbnail(thumbnail);
}
ThemedCellStyleList cellStyleConfig = this.cellStyleSettingPane.updateBean();
theme.setCellStyleList(cellStyleConfig);
ThemedColorScheme colorScheme = theme.getColorScheme();
colorScheme.setColors(this.colorListPane.update());
theme.setColorScheme(colorScheme);
theme.setChartStyle(this.chartStyleSettingPane.updateBean());
updateBean(theme);
return theme;
}
public List<Color> getCurrentColorScheme() {
return colorListPane.update();
public TemplateThemeEditorPane<T> getThemeEditorPane() {
return themeEditorPane;
}
public void save(CallBackAdaptor callBack) {
T theme;
try {
theme = (T) updateBean().clone();
} catch (CloneNotSupportedException ex) {
FineLoggerFactory.getLogger().error(ex.getMessage(), ex);
return;
}
save(theme, callBack);
}
public void save(String name, CallBackAdaptor callBack) {
T theme = null;
try {
theme = (T) updateBean().clone();
} catch (CloneNotSupportedException ex) {
FineLoggerFactory.getLogger().error(ex.getMessage(), ex);
return;
}
theme.setName(name);
save(theme, callBack);
}
private void save(T theme, CallBackAdaptor callBack) {
theme.setRemovable(true);
theme.setMutable(true);
config.addTheme(theme, true, new CallBackAdaptor() {
@Override
public void afterCommit() {
super.afterCommit();
themeEditorPane.setThemeNameEditable(false);
callBack.afterCommit();
}
protected abstract void updateBean(T theme);
@Override
public void afterRollback() {
super.afterRollback();
FineJOptionPane.showMessageDialog(SwingUtilities.getWindowAncestor(TemplateThemeProfilePane.this),
i18nText("Fine-Design_Basic_Template_Theme_Operation_Failed_Tip"),
i18nText("Fine-Design_Basic_Alert"),
JOptionPane.WARNING_MESSAGE);
}
});
}
public UIButton createSaveButton() {
saveButton = new UIButton();
@ -397,29 +208,15 @@ public abstract class TemplateThemeProfilePane<T extends TemplateTheme> extends
saveButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
T theme = updateBean();
boolean canBeSaved = checkThemeCanBeSavedAndUpdateUI(currentIsNewTheme, true, currentIsNewTheme, true, nameTextField, nameErrorLabel, saveButton);
if (canBeSaved && theme != null) {
theme.setName(nameTextField.getText());
config.addTheme(theme, true, new CallBackAdaptor() {
@Override
public void afterCommit() {
super.afterCommit();
currentIsNewTheme = false;
nameTextField.setEnabled(false);
saveAsButton.setEnabled(true);
}
@Override
public void afterRollback() {
super.afterRollback();
FineJOptionPane.showMessageDialog(SwingUtilities.getWindowAncestor(TemplateThemeProfilePane.this),
i18nText("Fine-Design_Basic_Template_Theme_Operation_Failed_Tip"),
i18nText("Fine-Design_Basic_Alert"),
JOptionPane.WARNING_MESSAGE);
}
});
}
save(new CallBackAdaptor() {
@Override
public void afterCommit() {
super.afterCommit();
saveButton.setEnabled(false);
saveAsButton.setEnabled(true);
DesignerToastMsgUtil.toastPrompt(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_Save_Successfully"));
}
});
}
});
return saveButton;
@ -440,7 +237,7 @@ public abstract class TemplateThemeProfilePane<T extends TemplateTheme> extends
private class SaveAsDialog extends JDialog {
private final TemplateThemeProfileDialog<T> parent;
private UITextField nameTextField;
private AutoCheckThemeNameTextField<T> nameTextField;
private UILabel nameErrorLabel;
private UIButton confirmButton;
@ -466,6 +263,18 @@ public abstract class TemplateThemeProfilePane<T extends TemplateTheme> extends
}
private void initializeComponents() {
nameTextField = new AutoCheckThemeNameTextField<>();
nameTextField.setThemeConfig(config);
nameTextField.setPreferredSize(new Dimension(180, 20));
nameTextField.setNameCheckListener(new AutoCheckTextField.CheckListener() {
@Override
public void onChecked(String error, boolean valid) {
nameErrorLabel.setVisible(StringUtils.isNotEmpty(error));
nameErrorLabel.setText(error);
confirmButton.setEnabled(valid);
}
});
nameErrorLabel = LabelUtils.createLabel(StringUtils.EMPTY, Color.RED);
nameErrorLabel.setBorder(BorderFactory.createEmptyBorder(10, 20, 0, 0));
@ -474,47 +283,16 @@ public abstract class TemplateThemeProfilePane<T extends TemplateTheme> extends
confirmButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
saveAsNew(nameTextField.getText());
}
});
nameTextField = new UITextField();
nameTextField.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void insertUpdate(DocumentEvent e) {
if (isEnabled()) {
checkThemeCanBeSavedAndUpdateUI(true, false, true, true, nameTextField, nameErrorLabel, confirmButton);
}
}
@Override
public void removeUpdate(DocumentEvent e) {
if (isEnabled()) {
checkThemeCanBeSavedAndUpdateUI(true, false, true, true, nameTextField, nameErrorLabel, confirmButton);
}
}
@Override
public void changedUpdate(DocumentEvent e) {
}
});
nameTextField.addFocusListener(new FocusAdapter() {
@Override
public void focusGained(FocusEvent e) {
if (isEnabled()) {
checkThemeCanBeSavedAndUpdateUI(true, false, true, true, nameTextField, nameErrorLabel, confirmButton);
}
}
@Override
public void focusLost(FocusEvent e) {
if (isEnabled()) {
checkThemeCanBeSavedAndUpdateUI(true, true, true, true, nameTextField, nameErrorLabel, confirmButton);
}
save(nameTextField.getText(), new CallBackAdaptor() {
@Override
public void afterCommit() {
super.afterCommit();
exit();
parent.exit();
}
});
}
});
nameTextField.setPreferredSize(new Dimension(180, 20));
}
private JPanel createActionsContainer() {
@ -548,82 +326,8 @@ public abstract class TemplateThemeProfilePane<T extends TemplateTheme> extends
return container;
}
private void saveAsNew(String name) {
T newThemeObject = null;
try {
newThemeObject = (T) updateBean().clone();
} catch (CloneNotSupportedException ex) {
FineLoggerFactory.getLogger().error(ex.getMessage(), ex);
return;
}
boolean canBeSaved = checkThemeCanBeSavedAndUpdateUI(true, true, true, true, nameTextField, nameErrorLabel, confirmButton);
if (canBeSaved && newThemeObject != null) {
newThemeObject.setName(name);
newThemeObject.setRemovable(true);
newThemeObject.setMutable(true);
config.addTheme(newThemeObject, true, new CallBackAdaptor() {
@Override
public void afterCommit() {
super.afterCommit();
exit();
parent.exit();
}
@Override
public void afterRollback() {
super.afterRollback();
FineJOptionPane.showMessageDialog(SwingUtilities.getWindowAncestor(TemplateThemeProfilePane.this),
i18nText("Fine-Design_Basic_Template_Theme_Operation_Failed_Tip"),
i18nText("Fine-Design_Basic_Alert"),
JOptionPane.WARNING_MESSAGE);
}
});
}
}
public void exit() {
this.dispose();
}
}
private boolean isThemeNameEmpty(String name) {
return StringUtils.isEmpty(name);
}
private boolean isThemeNameDuplicated(String name) {
return config.cachedFetch(name) != null;
}
private boolean checkThemeCanBeSavedAndUpdateUI(
boolean checkEmpty,
boolean displayEmptyTip,
boolean checkDuplicated,
boolean displayDuplicatedTip,
UITextField textField,
UILabel errorLabel, UIButton... actionButtons) {
String name = textField.getText();
boolean valid = true;
errorLabel.setText(StringUtils.EMPTY);
if (checkEmpty && isThemeNameEmpty(name)) {
valid = false;
if (displayEmptyTip) {
errorLabel.setText(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Empty_Name_Error_Tip"));
}
} else if (checkDuplicated && isThemeNameDuplicated(name)) {
valid = false;
if (displayDuplicatedTip) {
errorLabel.setText(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Duplicated_Name_Error_Tip"));
}
}
errorLabel.setVisible(!valid);
if (actionButtons != null && actionButtons.length > 0) {
for (UIButton button : actionButtons) {
if (button != null) {
button.setEnabled(valid);
}
}
}
return valid;
}
}

64
designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeDialog.java

@ -26,6 +26,9 @@ public abstract class TemplateThemeDialog extends JDialog {
public static final int DIALOG_BOTTOM_ACTION_BUTTON_GAP = 10;
public static final int DIALOG_BOTTOM_ACTION_BUTTON_HEIGHT = 20;
private final JPanel contentContainer;
private final JPanel actionContainer;
public TemplateThemeDialog(Window parent, String title, int contentWidth, int contentHeight) {
super(parent, ModalityType.APPLICATION_MODAL);
@ -44,25 +47,45 @@ public abstract class TemplateThemeDialog extends JDialog {
}
});
GUICoreUtils.centerWindow(this);
contentContainer = FRGUIPaneFactory.createBorderLayout_S_Pane();
actionContainer = FRGUIPaneFactory.createBorderLayout_S_Pane();
contentContainer.add(actionContainer, BorderLayout.SOUTH);
setContentPane(contentContainer);
}
protected final JPanel createDialogContentPane(JPanel contentPane, UIButton[] rightButtons) {
JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane();
container.add(contentPane, BorderLayout.CENTER);
container.add(createActionsContainer(rightButtons), BorderLayout.SOUTH);
return container;
protected void setupContentPane() {
contentContainer.add(createContentPane(), BorderLayout.CENTER, 0);
}
protected final JPanel createDialogContentPane(JPanel contentPane, UIButton[] leftButtons, UIButton[] rightButtons) {
JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane();
container.add(contentPane, BorderLayout.CENTER);
container.add(createActionsContainer(leftButtons, rightButtons), BorderLayout.SOUTH);
return container;
protected JPanel createContentPane() {
return new JPanel();
}
protected UIButton[] createLeftButtons() {
return new UIButton[] {};
}
protected UIButton[] createRightButtons() {
return new UIButton[] {};
}
private JPanel createActionsContainer(UIButton... buttons) {
return this.createActionsContainer(FlowLayout.RIGHT, buttons);
public void setupActionButtons() {
JPanel leftPane = createActionsContainer(FlowLayout.LEFT, createLeftButtons());
JPanel rightPane = createActionsContainer(FlowLayout.RIGHT, createRightButtons());
actionContainer.removeAll();
actionContainer.add(leftPane, BorderLayout.WEST);
actionContainer.add(rightPane, BorderLayout.EAST);
actionContainer.invalidate();
actionContainer.repaint();
}
protected final JPanel createDialogContentPane(JPanel contentPane, UIButton[] rightButtons) {
JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane();
container.add(contentPane, BorderLayout.CENTER);
container.add(createRightActionsContainer(rightButtons), BorderLayout.SOUTH);
return container;
}
private JPanel createActionsContainer(int align, UIButton... buttons) {
@ -84,21 +107,12 @@ public abstract class TemplateThemeDialog extends JDialog {
return container;
}
protected int getPaddingVertical(){
return (DIALOG_BOTTOM_ACTION_BAR_HEIGHT - DIALOG_BOTTOM_ACTION_BUTTON_HEIGHT) / 2;
private JPanel createRightActionsContainer(UIButton... buttons) {
return createActionsContainer(FlowLayout.RIGHT, buttons);
}
private JPanel createActionsContainer(UIButton[] leftButtons, UIButton[] rightButtons) {
JPanel leftPane = createActionsContainer(FlowLayout.LEFT, leftButtons);
JPanel rightPane = createActionsContainer(FlowLayout.RIGHT, rightButtons);
JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane();
container.add(leftPane, BorderLayout.WEST);
container.add(rightPane, BorderLayout.EAST);
return container;
private int getPaddingVertical(){
return (DIALOG_BOTTOM_ACTION_BAR_HEIGHT - DIALOG_BOTTOM_ACTION_BUTTON_HEIGHT) / 2;
}
public void exit() {

58
designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeGridPagesDialog.java

@ -0,0 +1,58 @@
package com.fr.design.mainframe.theme.dialog;
import com.fr.base.theme.TemplateTheme;
import com.fr.base.theme.TemplateThemeConfig;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.theme.TemplateThemeGridPagesPane;
import com.fr.design.mainframe.theme.TemplateThemeGridPane;
import javax.swing.JPanel;
/**
* @author Starryi
* @version 1.0
* Created by Starryi on 2021/8/13
*/
public class TemplateThemeGridPagesDialog extends TemplateThemeDialog implements TemplateThemeGridPagesPane.PageChangeListener {
public static final int CONTENT_WIDTH = TemplateThemeGridPane.CONTENT_WIDTH + 40;
public static final int CONTENT_HEIGHT = TemplateThemeGridPane.CONTENT_HEIGHT + 37;
protected TemplateThemeGridPagesPane overallPane;
public TemplateThemeGridPagesDialog() {
super(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Using_Dialog_Title"), CONTENT_WIDTH, CONTENT_HEIGHT);
setupContentPane();
setupActionButtons();
}
@Override
protected JPanel createContentPane() {
overallPane = new TemplateThemeGridPagesPane();
overallPane.setPageChangeListener(this);
return overallPane;
}
@Override
protected UIButton[] createLeftButtons() {
return overallPane.createLeftButtons();
}
@Override
protected UIButton[] createRightButtons() {
return overallPane.createRightButtons();
}
@Override
public void exit() {
overallPane.exit();
super.exit();
}
@Override
public void onPageChangeListener() {
setupActionButtons();
}
}

107
designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeManageDialog.java

@ -12,8 +12,9 @@ import com.fr.design.gui.frpane.UITabbedPane;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.mainframe.theme.TemplateThemeManagePane;
import com.fr.design.mainframe.theme.TemplateThemeGridControlPane;
import com.fr.design.mainframe.theme.provider.ThemeManageActionProvider;
import javax.swing.BorderFactory;
@ -32,106 +33,10 @@ import java.util.Set;
* @version 1.0
* Created by Starryi on 2021/8/13
*/
public class TemplateThemeManageDialog extends TemplateThemeDialog {
public class TemplateThemeManageDialog extends TemplateThemeGridPagesDialog {
private final TemplateThemeManageDialogContentPane contentPane;
public TemplateThemeManageDialog(Window parent) {
super(parent, Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Dialog_Title"),
TemplateThemeManageDialogContentPane.CONTENT_WIDTH, TemplateThemeManageDialogContentPane.CONTENT_HEIGHT);
contentPane = new TemplateThemeManageDialogContentPane();
setContentPane(createDialogContentPane(contentPane, createActionButtons()));
}
@Override
public void exit(){
contentPane.exit();
super.exit();
}
private UIButton[] createActionButtons() {
List<UIButton> uiButtonList = new ArrayList<>();
Set<ThemeManageActionProvider> providers = ExtraDesignClassManager.getInstance().getArray(ThemeManageActionProvider.MARK_STRING);
for (ThemeManageActionProvider provider : providers) {
uiButtonList.add(provider.createButton(new ThemeManageActionProvider.ThemeManageActionContext() {
@Override
public TemplateThemeDialog getDialog() {
return TemplateThemeManageDialog.this;
}
@Override
public TemplateThemeConfig<? extends TemplateTheme> getConfig() {
return contentPane.getConfig();
}
}));
}
uiButtonList.add(createCompleteButton());
return uiButtonList.toArray(new UIButton[]{});
}
private UIButton createCompleteButton() {
UIButton button = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Dialog_Complete"));
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
exit();
}
});
return button;
}
public static class TemplateThemeManageDialogContentPane extends JPanel {
public static final int CONTENT_WIDTH = TemplateThemeManagePane.CONTENT_WIDTH + 24;
public static final int CONTENT_HEIGHT = TemplateThemeManagePane.CONTENT_HEIGHT + 40;
private final UITabbedPane tabbedPane;
private final TemplateThemeManagePane<FormTheme> formThemesManagerPane;
private final TemplateThemeManagePane<ReportTheme> reportThemesManagerPane;
public TemplateThemeManageDialogContentPane() {
setLayout(FRGUIPaneFactory.createBorderLayout());
setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 10));
setPreferredSize(new Dimension(CONTENT_WIDTH, CONTENT_HEIGHT));
tabbedPane = new UITabbedPane();
add(tabbedPane, BorderLayout.NORTH);
formThemesManagerPane = TemplateThemeManagePane.createFormThemesManagerPane();
formThemesManagerPane.startListenThemeConfig();
reportThemesManagerPane = TemplateThemeManagePane.createReportThemesManagerPane();
reportThemesManagerPane.startListenThemeConfig();
tabbedPane.addTab(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Dialog_Form_Tab"), formThemesManagerPane);
tabbedPane.addTab(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Dialog_Report_Tab"), reportThemesManagerPane);
tabbedPane.setSelectedIndex(0);
JTemplate<?,?> template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
if (template != null) {
TemplateThemeConfig<? extends TemplateTheme> config = template.getUsingTemplateThemeConfig();
if (config == reportThemesManagerPane.getConfig()) {
tabbedPane.setSelectedIndex(1);
}
}
}
public TemplateThemeConfig<? extends TemplateTheme> getConfig() {
if (tabbedPane.getSelectedIndex() == 0) {
return FormThemeConfig.getInstance();
} else {
return ReportThemeConfig.getInstance();
}
}
public void exit() {
formThemesManagerPane.stopListenThemeConfig();
formThemesManagerPane.stopAsyncFetchTheme();
reportThemesManagerPane.stopListenThemeConfig();
reportThemesManagerPane.stopAsyncFetchTheme();
}
public TemplateThemeManageDialog() {
super();
overallPane.showThemeManagingPane();
}
}

25
designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeProfileDialog.java

@ -25,22 +25,33 @@ import java.util.Set;
* Created by Starryi on 2021/8/13
*/
public class TemplateThemeProfileDialog<T extends TemplateTheme> extends TemplateThemeDialog {
private static final int PADDING_VERTICAL = 4;
public static TemplateThemeProfilePane<? extends TemplateTheme> currentVisibleProfilePane;
public static final int CONTENT_WIDTH = 1010;
public static final int CONTENT_HEIGHT = 542;
private final TemplateThemeProfilePane<T> profilePane;
public TemplateThemeProfileDialog(Window parent, TemplateThemeProfilePane<T> profilePane) {
super(parent, profilePane.getTitle(), CONTENT_WIDTH, CONTENT_HEIGHT);
this.profilePane = profilePane;
TemplateThemeProfileDialog.currentVisibleProfilePane = profilePane;
setupContentPane();
setupActionButtons();
}
@Override
protected JPanel createContentPane() {
JPanel content = FRGUIPaneFactory.createBorderLayout_S_Pane();
content.setPreferredSize(new Dimension(CONTENT_WIDTH, CONTENT_HEIGHT));
content.add(profilePane, BorderLayout.CENTER);
return content;
}
setContentPane(createDialogContentPane(content, createActionButtons(profilePane)));
currentVisibleProfilePane = profilePane;
@Override
protected UIButton[] createRightButtons() {
return createActionButtons(profilePane);
}
@Override
@ -51,7 +62,7 @@ public class TemplateThemeProfileDialog<T extends TemplateTheme> extends Templat
public static List<Color> getEditingColorScheme() {
if (currentVisibleProfilePane != null) {
return currentVisibleProfilePane.getCurrentColorScheme();
return currentVisibleProfilePane.getThemeEditorPane().getCurrentColorScheme();
}
return null;
}
@ -60,10 +71,6 @@ public class TemplateThemeProfileDialog<T extends TemplateTheme> extends Templat
return currentVisibleProfilePane != null;
}
protected int getPaddingVertical(){
return PADDING_VERTICAL;
}
private UIButton[] createActionButtons(final TemplateThemeProfilePane<T> profilePane) {
List<UIButton> uiButtonList = new ArrayList<>();

106
designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeUsingDialog.java

@ -1,111 +1,13 @@
package com.fr.design.mainframe.theme.dialog;
import com.fr.base.theme.TemplateTheme;
import com.fr.base.theme.TemplateThemeConfig;
import com.fr.base.theme.ThemedTemplate;
import com.fr.design.event.ChangeEvent;
import com.fr.design.event.ChangeListener;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.theme.TemplateThemeListPane;
import com.fr.design.mainframe.theme.ui.BorderUtils;
import com.fr.workspace.WorkContext;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.border.CompoundBorder;
import java.awt.BorderLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
* @author Starryi
* @version 1.0
* Created by Starryi on 2021/8/13
*/
public class
TemplateThemeUsingDialog<T extends TemplateTheme> extends TemplateThemeDialog {
public static final int CONTENT_WIDTH = TemplateThemeListPane.CONTENT_WIDTH + 42;
public static final int CONTENT_HEIGHT = TemplateThemeListPane.CONTENT_HEIGHT + 23;
private final TemplateThemeListPane<T> themeListPane;
private final ThemedTemplate currentTemplate;
public TemplateThemeUsingDialog(Window parent, ThemedTemplate template, TemplateThemeConfig<T> config) {
super(parent, Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Using_Dialog_Title"), CONTENT_WIDTH, CONTENT_HEIGHT);
this.currentTemplate = template;
this.themeListPane = new TemplateThemeListPane<>(false, config, null);
JPanel content = createContent();
UIButton openThemeManagerButton = createOpenThemeManagerButton();
UIButton completeButton = createCompleteButton();
setContentPane(createDialogContentPane(content,
new UIButton[]{ openThemeManagerButton },
new UIButton[]{ completeButton }
));
themeListPane.startListenThemeConfig();
themeListPane.setSelectedChangeListener(new ChangeListener() {
@Override
public void fireChanged(ChangeEvent event) {
TemplateTheme theme = themeListPane.getSelectedTheme();
if (theme != null) {
currentTemplate.setTemplateTheme(theme);
themeListPane.repaint();
}
}
});
}
private JPanel createContent() {
JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane();
container.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 10));
JPanel themeListPaneContainer = FRGUIPaneFactory.createBorderLayout_S_Pane();
themeListPaneContainer.setBorder(new CompoundBorder(
BorderUtils.createTitleBorder(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Using_Dialog_Select"), 12),
BorderFactory.createEmptyBorder(0, 10, 0, 10)
));
themeListPaneContainer.add(themeListPane, BorderLayout.CENTER);
container.add(themeListPaneContainer, BorderLayout.CENTER);
return container;
}
private UIButton createOpenThemeManagerButton() {
if (WorkContext.getCurrent().isRoot()) {
UIButton button = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Dialog_Title"));
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
TemplateThemeManageDialog dialog = new TemplateThemeManageDialog(TemplateThemeUsingDialog.this);
dialog.setVisible(true);
}
});
return button;
}
return null;
}
private UIButton createCompleteButton() {
UIButton button = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Using_Dialog_Complete"));
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
exit();
}
});
return button;
}
public void exit() {
themeListPane.stopListenThemeConfig();
themeListPane.stopAsyncFetchTheme();
super.exit();
public class TemplateThemeUsingDialog extends TemplateThemeGridPagesDialog {
public TemplateThemeUsingDialog() {
super();
overallPane.showThemeUsingPane();
}
}

30
designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ComponentStyleEditPane.java

@ -2,8 +2,7 @@ package com.fr.design.mainframe.theme.edit;
import com.fr.base.theme.settings.ThemedComponentStyle;
import com.fr.design.designer.IntervalConstants;
import com.fr.design.dialog.AttrScrollPane;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.icontainer.UIScrollPane;
import com.fr.design.gui.style.ComponentBodyStylePane;
import com.fr.design.gui.style.ComponentIntegralStylePane;
import com.fr.design.gui.style.ComponentTitleStylePane;
@ -18,10 +17,9 @@ import com.fr.general.act.BorderPacker;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
/**
* @author Starryi
@ -50,7 +48,8 @@ public class ComponentStyleEditPane extends JPanel {
},
new JComponent[] { createTabContainer(componentTitleStylePane), createTabContainer(componentBodyStylePane), createTabContainer(componentIntegralStylePane) }
);
add(content, BorderLayout.NORTH);
content.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
add(content, BorderLayout.CENTER);
}
public void populateBean(ThemedComponentStyle style) {
@ -115,21 +114,20 @@ public class ComponentStyleEditPane extends JPanel {
}
private JComponent createTabContainer(final JPanel component) {
JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane();
container.setPreferredSize(new Dimension(container.getPreferredSize().width, 220));
JPanel content = FRGUIPaneFactory.createBorderLayout_S_Pane();
JPanel tipLabelPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
tipLabelPane.setBorder(BorderFactory.createEmptyBorder(3, 0, 0, 0));
UILabel tipLabel = LabelUtils.createLabel(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Component_Style_Tip"), new Color(153, 153, 153));
JTextArea tipLabel = LabelUtils.createAutoWrapLabel(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Component_Style_Tip"), new Color(153, 153, 153));
tipLabelPane.add(tipLabel);
container.add(tipLabelPane, BorderLayout.NORTH);
container.add(new AttrScrollPane() {
@Override
protected JPanel createContentPane() {
return component;
}
}, BorderLayout.CENTER);
content.add(tipLabelPane, BorderLayout.NORTH);
content.add(component, BorderLayout.CENTER);
UIScrollPane scrollPane = new UIScrollPane(content);
scrollPane.setBorder(BorderFactory.createEmptyBorder());
JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane();
container.add(scrollPane, BorderLayout.CENTER);
return container;

4
designer-base/src/main/java/com/fr/design/mainframe/theme/edit/cell/CellStyleEditPane.java

@ -12,7 +12,7 @@ import com.fr.design.gui.frpane.AttributeChangeListener;
import com.fr.design.gui.style.AbstractBasicStylePane;
import com.fr.design.gui.style.AlignmentPane;
import com.fr.design.gui.style.BorderPane;
import com.fr.design.gui.style.FormatPane;
import com.fr.design.gui.style.TextFontTippedPane;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.theme.ui.BorderUtils;
@ -94,7 +94,7 @@ public class CellStyleEditPane extends MultiTabPane<ThemedCellStyle> {
@Override
protected List<BasicPane> initPaneList() {
paneList = new ArrayList<>();
paneList.add(new FormatPane());
paneList.add(new TextFontTippedPane(false));
paneList.add(new BorderPane());
paneList.add(new AlignmentPane());
return paneList;

4
designer-base/src/main/java/com/fr/design/mainframe/theme/edit/cell/NoBorderPaneCellStyleEditPane.java

@ -2,7 +2,7 @@ package com.fr.design.mainframe.theme.edit.cell;
import com.fr.design.dialog.BasicPane;
import com.fr.design.gui.style.AlignmentPane;
import com.fr.design.gui.style.FormatPane;
import com.fr.design.gui.style.TextFontTippedPane;
import java.util.ArrayList;
import java.util.List;
@ -12,7 +12,7 @@ public class NoBorderPaneCellStyleEditPane extends CellStyleEditPane {
@Override
protected List<BasicPane> initPaneList() {
paneList = new ArrayList<>();
paneList.add(new FormatPane());
paneList.add(new TextFontTippedPane(false));
paneList.add(new AlignmentPane());
return paneList;
}

19
designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/LabelUtils.java

@ -3,6 +3,9 @@ package com.fr.design.mainframe.theme.edit.ui;
import com.fr.design.gui.ilable.UILabel;
import com.fr.general.FRFont;
import javax.swing.BorderFactory;
import javax.swing.JTextArea;
import javax.swing.plaf.basic.BasicTextAreaUI;
import java.awt.Color;
import java.awt.Font;
@ -26,4 +29,20 @@ public class LabelUtils {
uiLabel.setFont(newFont);
return uiLabel;
}
public static JTextArea createAutoWrapLabel(String title, Color color) {
JTextArea tipLabel = new JTextArea();
tipLabel.setUI(new BasicTextAreaUI());
tipLabel.setForeground(color);
Font newFont = FRFont.getInstance(tipLabel.getFont().getFontName(), Font.PLAIN, 12);
tipLabel.setFont(newFont);
tipLabel.setBorder(BorderFactory.createEmptyBorder());
tipLabel.setEnabled(false);
tipLabel.setText(title);
tipLabel.setLineWrap(true);
tipLabel.setWrapStyleWord(true);
tipLabel.setOpaque(false);
tipLabel.setBackground(null);
return tipLabel;
}
}

1
designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/TabbedPane.java

@ -25,7 +25,6 @@ public class TabbedPane extends JPanel {
public TabbedPane(String[] names, JComponent[] panes) {
setLayout(FRGUIPaneFactory.createBorderLayout());
setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
for (JComponent pane :panes) {
pane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

27
designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ComponentPreviewPane.java

@ -31,6 +31,7 @@ import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Insets;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.Stroke;
@ -99,7 +100,20 @@ public abstract class ComponentPreviewPane extends UINoOpaquePanel implements Th
Utils.clipByRoundBorder(g2d, getWidth(), getHeight(), roundedBorder.getRoundedCorner(), roundedBorder.getThickness());
}
int titleHeight = titlePane == null ? 0 : titlePane.getHeight();
Border containerBorder = container.getBorder();
Insets insets = containerBorder.getBorderInsets(container);
int titleHeight = titlePane == null ? 0 : titlePane.getHeight() + insets.top;
//绘制标题背景
if (titlePane != null) {
Label data = titlePane.getData();
float opacity = data.getBackgroundOpacity();
Background background = data.getBackground();
if (background != null) {
Utils.paintBackground((Graphics2D) g, background, new Rectangle2D.Double(0, 0, getWidth(), titleHeight), opacity);
}
}
//绘制主体背景
Utils.paintBackground(g2d, style.getBackground(), new Rectangle2D.Double(0, titleHeight, getWidth(), getHeight() - titleHeight), style.getAlpha());
Utils.paintBackground(g2d, style.getBorderImage(), new Rectangle2D.Double(0, 0, getWidth(), getHeight()), style.getBorderImageOpacity());
@ -133,17 +147,14 @@ public abstract class ComponentPreviewPane extends UINoOpaquePanel implements Th
this.setBorder(new BottomLineBorder(componentStyle.getStyle().getColor(), componentStyle.getStyle().getBorder()));
}
public Label getData(){
return data;
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Dimension size = getSize();
Background background = data.getBackground();
float opacity = data.getBackgroundOpacity();
if (background != null) {
Utils.paintBackground((Graphics2D) g, background, new Rectangle2D.Double(0, 0, size.getWidth(), size.getHeight()), opacity);
}
Graphics2D g2d = (Graphics2D) g.create();
Background inset = data.getInsetImage();
Image insetImage = inset instanceof ImageBackground ? ((ImageBackground) inset).getImage() : null;

13
designer-base/src/main/java/com/fr/design/mainframe/theme/preview/FormThemePreviewPane.java

@ -14,6 +14,7 @@ import com.fr.design.mainframe.theme.preview.ecpreview.ECComponentPreviewPane;
import com.fr.general.Background;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.chart.PiePlot4VanChart;
import com.fr.plugin.chart.attr.VanChartLegend;
import com.fr.plugin.chart.attr.axis.VanChartAxis;
import com.fr.plugin.chart.base.AttrLabel;
import com.fr.plugin.chart.base.VanChartTools;
@ -34,7 +35,6 @@ import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import static com.fr.design.i18n.Toolkit.i18nText;
/**
* @author Starryi
* @version 1.0
@ -65,7 +65,7 @@ public class FormThemePreviewPane extends TemplateThemePreviewPane<FormTheme> {
}
};
columnChartPanel.setLayout(new BorderLayout());
columnChartPreviewPane = createChartPreviewPane(initColumnChart(), i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_Column_Title"));
columnChartPreviewPane = createChartPreviewPane(initColumnChart(), i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_Comp_Title1"));
columnChartPanel.add(columnChartPreviewPane, BorderLayout.CENTER);
JPanel pieChartPanel = new UINoOpaquePanel() {
@ -74,7 +74,7 @@ public class FormThemePreviewPane extends TemplateThemePreviewPane<FormTheme> {
}
};
pieChartPanel.setLayout(new BorderLayout());
pieChartPreviewPane = createChartPreviewPane(initPieChart(), i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_Pie_Title"));
pieChartPreviewPane = createChartPreviewPane(initPieChart(), i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_Comp_Title2"));
pieChartPanel.add(pieChartPreviewPane, BorderLayout.CENTER);
chartContent.add(columnChartPanel, BorderLayout.CENTER);
chartContent.add(pieChartPanel, BorderLayout.EAST);
@ -180,11 +180,14 @@ public class FormThemePreviewPane extends TemplateThemePreviewPane<FormTheme> {
vanChartTools.setFullScreen(false);
PiePlot4VanChart plot = chart.getPlot();
plot.getLegend().setPosition(Constants.BOTTOM);
VanChartLegend legend = (VanChartLegend) plot.getLegend();
legend.setPosition(Constants.BOTTOM);
legend.setCustomSize(true);
legend.setMaxHeight(28);
plot.getGradientStyle().setGradientType(GradientType.NONE);
plot.setInnerRadiusPercent(75);
plot.getRadius().setRadiusType(RadiusType.FIXED);
plot.getRadius().setRadius(80);
plot.getRadius().setRadius(70);
Object[] category = {StringUtils.EMPTY};
Object[] series = {"A1", "B1", "C1", "D1", "E1", "F1", "G1", "H1"};

67
designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ecpreview/ECPreviewPane.java

@ -2,20 +2,16 @@ package com.fr.design.mainframe.theme.preview.ecpreview;
import com.fr.base.theme.TemplateTheme;
import com.fr.base.theme.settings.ThemedCellStyleList;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.theme.preview.UINoOpaquePanel;
import com.fr.design.mainframe.theme.preview.ecpreview.cell.AbstractPreviewCell;
import com.fr.design.mainframe.theme.preview.ecpreview.cell.PreviewCell;
import com.fr.log.FineLoggerFactory;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.io.BufferedReader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
@ -25,70 +21,41 @@ import java.util.List;
* Created by Starryi on 2021/8/13
*/
public class ECPreviewPane extends AbstractECPreviewPane {
private static String csv =
"城市 当月目标 当月完成 月完成率 年完成率\n" +
"合肥市 248,938 348,938 140% 140%\n" +
"邵阳市 248,938 348,938 140% 140%\n" +
"合计 1,071,460 1,371,460 128% 128%";
private final List<String[]> DATA_LIST = createDataList();
private static final String BLANK_CHAR = " ";
private List<AbstractPreviewCell> headerCellList = new ArrayList<>();
private List<AbstractPreviewCell> contentCellList = new ArrayList<>();
private List<AbstractPreviewCell> hightLightCellList = new ArrayList<>();
private List<String[]> createDataList() {
List<String[]> data = new ArrayList<>();
try (BufferedReader reader = new BufferedReader(new StringReader(csv))) {
String textLine;
while ((textLine = reader.readLine()) != null) {
String[] texts = textLine.split(BLANK_CHAR);
data.add(texts);
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
return data;
}
private final List<AbstractPreviewCell> headerCellList = new ArrayList<>();
private final List<AbstractPreviewCell> contentCellList = new ArrayList<>();
private final List<AbstractPreviewCell> highLightCellList = new ArrayList<>();
private static final int COL_COUNT = 5;
private static final int CONTENT_ROW_COUNT = 2;
public ECPreviewPane() {
this.setPreferredSize(new Dimension(517, 147));
this.setBorder(BorderFactory.createEmptyBorder(0, 1, 2, 1));
this.setLayout(FRGUIPaneFactory.createBorderLayout());
String[] titleArr = DATA_LIST.get(0);
String[] endArr = DATA_LIST.get(DATA_LIST.size() - 1);
JPanel titlePane = new UINoOpaquePanel(new GridLayout());
this.add(titlePane, BorderLayout.NORTH);
for (String title : titleArr) {
PreviewCell cell = new PreviewCell(title);
for (int i = 0; i < COL_COUNT; i++) {
PreviewCell cell = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Header"));
cell.setPreferredSize(new Dimension(103, 36));
titlePane.add(cell);
headerCellList.add(cell);
}
JPanel contentPane = new UINoOpaquePanel(new GridLayout(2, 5, 0, 0));
this.add(contentPane, BorderLayout.CENTER);
for (int i = 1; i < DATA_LIST.size() - 1; i++) {
String[] textLine = DATA_LIST.get(i);
for (int j = 0; j < textLine.length; j++) {
String text = textLine[j];
PreviewCell cell = new PreviewCell(text);
cell.setPreferredSize(new Dimension(103, 33));
contentPane.add(cell);
contentCellList.add(cell);
}
for (int i = 0; i < COL_COUNT * CONTENT_ROW_COUNT; i++) {
PreviewCell cell = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Main_Text"));
cell.setPreferredSize(new Dimension(103, 33));
contentPane.add(cell);
contentCellList.add(cell);
}
JPanel endPane = new UINoOpaquePanel(new GridLayout());
this.add(endPane, BorderLayout.SOUTH);
for (String text : endArr) {
PreviewCell cell = new PreviewCell(text);
for (int i = 0; i < COL_COUNT; i++) {
PreviewCell cell = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Highlight_Text"));
cell.setPreferredSize(new Dimension(103, 33));
endPane.add(cell);
hightLightCellList.add(cell);
highLightCellList.add(cell);
}
}
@Override
@ -96,7 +63,7 @@ public class ECPreviewPane extends AbstractECPreviewPane {
ThemedCellStyleList cellStyleConfig = theme.getCellStyleList();
refresh(headerCellList, getReportHeaderStyle(cellStyleConfig));
refresh(contentCellList, getMainContentStyle(cellStyleConfig));
refresh(hightLightCellList, getHighLightStyle(cellStyleConfig));
refresh(highLightCellList, getHighLightStyle(cellStyleConfig));
}

50
designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ecpreview/ECReportPreviewPane.java

@ -22,13 +22,15 @@ import java.util.ArrayList;
import java.util.List;
public class ECReportPreviewPane extends UINoOpaquePanel implements ThemePreviewed<ReportTheme> {
private List<AbstractPreviewCell> headerTitleCellList = new ArrayList<>();
private List<AbstractPreviewCell> headerCellList = new ArrayList<>();
private List<AbstractPreviewCell> titleCellList = new ArrayList<>();
private List<AbstractPreviewCell> contentCellList = new ArrayList<>();
private List<AbstractPreviewCell> highLightCellList = new ArrayList<>();
private final List<AbstractPreviewCell> headerTitleCellList = new ArrayList<>();
private final List<AbstractPreviewCell> headerCellList = new ArrayList<>();
private final List<AbstractPreviewCell> titleCellList = new ArrayList<>();
private final List<AbstractPreviewCell> contentCellList = new ArrayList<>();
private final List<AbstractPreviewCell> highLightCellList = new ArrayList<>();
private static final int CONTENT_ROW_COUNT = 3;
private static final int COL_COUNT = 5;
private PreviewPane previewPane;
private final PreviewPane previewPane;
public ECReportPreviewPane() {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
@ -58,26 +60,26 @@ public class ECReportPreviewPane extends UINoOpaquePanel implements ThemePreview
private JPanel createNorthPane() {
JPanel northPane = FRGUIPaneFactory.createBorderLayout_NO_Opaque_Pane();
AbstractPreviewCell bigTitleCell = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_EC_Big_Title"));
AbstractPreviewCell bigTitleCell = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_Cell_Style_Big_Title"));
bigTitleCell.setPreferredSize(new Dimension(615, 46));
headerTitleCellList.add(bigTitleCell);
northPane.add(bigTitleCell, BorderLayout.NORTH);
CornerPreviewCell cornerCell = new CornerPreviewCell(new String[]{Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_EC_Product"),
Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_EC_Data"), Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_EC_Statistical_Dimension")},
new Point2D[]{new Point(159, 71), new Point(226, 49)});
cornerCell.setPreferredSize(new Dimension(226, 71));
CornerPreviewCell cornerCell = new CornerPreviewCell(new String[]{Toolkit.i18nText("Fine-Design_Basic_Column_Name"),
Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_EC_Data"), Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_Row_Name")},
new Point2D[]{new Point(159, 71), new Point(225, 49)});
cornerCell.setPreferredSize(new Dimension(225, 71));
headerCellList.add(cornerCell);
northPane.add(cornerCell, BorderLayout.WEST);
JPanel centerPane = FRGUIPaneFactory.createBorderLayout_NO_Opaque_Pane();
northPane.add(centerPane, BorderLayout.CENTER);
PreviewCell cell = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_EC_Statistical_By_Area"));
PreviewCell cell = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Small_Title"));
titleCellList.add(cell);
cell.setPreferredSize(new Dimension(308, 38));
centerPane.add(cell, BorderLayout.NORTH);
JPanel eastSouthPane = new UINoOpaquePanel(new GridLayout());
PreviewCell cell1 = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_EC_East_China"));
PreviewCell cell2 = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_EC_South_China"));
PreviewCell cell3 = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_EC_Subtotal"));
PreviewCell cell1 = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Header"));
PreviewCell cell2 = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Header"));
PreviewCell cell3 = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Header"));
headerCellList.add(cell1);
headerCellList.add(cell2);
headerCellList.add(cell3);
@ -92,14 +94,14 @@ public class ECReportPreviewPane extends UINoOpaquePanel implements ThemePreview
JPanel centerPane = FRGUIPaneFactory.createBorderLayout_NO_Opaque_Pane();
JPanel westPane = FRGUIPaneFactory.createBorderLayout_NO_Opaque_Pane();
centerPane.add(westPane, BorderLayout.WEST);
PreviewCell cell1 = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_EC_Drink"));
PreviewCell cell1 = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Small_Title"));
titleCellList.add(cell1);
cell1.setPreferredSize(new Dimension(112, 153));
westPane.add(cell1, BorderLayout.WEST);
JPanel gridPane = new UINoOpaquePanel(new GridLayout(5, 1));
for (int i = 0; i < 5; i++) {
PreviewCell cell = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_EC_Apple_Juice"));
cell.setPreferredSize(new Dimension(114, 31));
for (int i = 0; i < COL_COUNT; i++) {
PreviewCell cell = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Header"));
cell.setPreferredSize(new Dimension(113, 31));
headerCellList.add(cell);
gridPane.add(cell);
}
@ -107,14 +109,16 @@ public class ECReportPreviewPane extends UINoOpaquePanel implements ThemePreview
JPanel innerCenterPane = new UINoOpaquePanel(new GridLayout(5, 3));
centerPane.add(innerCenterPane, BorderLayout.CENTER);
for (int i = 0; i < 15; i++) {
PreviewCell cell = new PreviewCell("35600");
cell.setPreferredSize(new Dimension(123, 31));
if ((i + 1) % 3 == 0) {
for (int i = 0; i < COL_COUNT * CONTENT_ROW_COUNT; i++) {
PreviewCell cell ;
if ((i + 1) % CONTENT_ROW_COUNT == 0) {
cell = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Highlight_Text"));
highLightCellList.add(cell);
} else {
cell = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Main_Text"));
contentCellList.add(cell);
}
cell.setPreferredSize(new Dimension(123, 31));
innerCenterPane.add(cell);
}

100
designer-base/src/main/java/com/fr/design/mainframe/theme/ui/AutoCheckTextField.java

@ -0,0 +1,100 @@
package com.fr.design.mainframe.theme.ui;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.i18n.Toolkit;
import com.fr.stable.StringUtils;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
/**
* @author Starryi
* @version 1.0
* Created by Starryi on 2021/9/18
*/
public class AutoCheckTextField extends UITextField implements DocumentListener, FocusListener {
private DuplicateChecker duplicatedChecker;
private CheckListener checkListener;
public AutoCheckTextField() {
getDocument().addDocumentListener(this);
addFocusListener(this);
}
public void setDuplicatedChecker(DuplicateChecker checker) {
this.duplicatedChecker = checker;
}
public void setNameCheckListener(CheckListener checkListener) {
this.checkListener = checkListener;
}
private boolean isEmpty(String name) {
return StringUtils.isEmpty(name);
}
private boolean isDuplicated(String name) {
if (duplicatedChecker != null) {
return duplicatedChecker.isDuplicated(name);
}
return false;
}
private boolean checkValid(boolean notifyEmptyTip) {
String name = getText();
String error = StringUtils.EMPTY;
boolean valid = true;
if (isEditable()) {
if (isEmpty(name)) {
valid = false;
if (notifyEmptyTip) {
error = Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Empty_Name_Error_Tip");
}
} else if (isDuplicated(name)) {
valid = false;
error = Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Duplicated_Name_Error_Tip");
}
}
if (checkListener != null) {
checkListener.onChecked(error, valid);
}
return valid;
}
public boolean checkValid() {
return checkValid(true);
}
@Override
public void insertUpdate(DocumentEvent e) {
checkValid(false);
}
@Override
public void removeUpdate(DocumentEvent e) {
checkValid(false);
}
@Override
public void changedUpdate(DocumentEvent e) {
}
@Override
public void focusGained(FocusEvent e) {
checkValid(false);
}
@Override
public void focusLost(FocusEvent e) {
checkValid(true);
}
public interface CheckListener {
void onChecked(String error, boolean valid);
}
public interface DuplicateChecker {
boolean isDuplicated(String name);
}
}

26
designer-base/src/main/java/com/fr/design/mainframe/theme/ui/AutoCheckThemeNameTextField.java

@ -0,0 +1,26 @@
package com.fr.design.mainframe.theme.ui;
import com.fr.base.theme.TemplateTheme;
import com.fr.base.theme.TemplateThemeConfig;
/**
* @author Starryi
* @version 1.0
* Created by Starryi on 2021/9/18
*/
public class AutoCheckThemeNameTextField<T extends TemplateTheme> extends AutoCheckTextField {
private TemplateThemeConfig<T> config;
public AutoCheckThemeNameTextField() {
setDuplicatedChecker(new DuplicateChecker() {
@Override
public boolean isDuplicated(String name) {
return config != null && config.contains(name);
}
});
}
public void setThemeConfig(TemplateThemeConfig<T> config) {
this.config = config;
}
}

114
designer-base/src/main/java/com/fr/design/mainframe/theme/ui/BreadcrumbBar.java

@ -0,0 +1,114 @@
package com.fr.design.mainframe.theme.ui;
import com.fr.design.gui.ilable.UILabel;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.plaf.basic.BasicButtonUI;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
* @author Starryi
* @version 1.0
* Created by Starryi on 2021/10/9
*/
public class BreadcrumbBar extends JPanel {
private JButton currentCrumb;
public BreadcrumbBar() {
setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
}
public void addCrumb(final String text, final BreadcrumbBackListener backListener) {
if (currentCrumb != null) {
currentCrumb.setSelected(false);
add(createSeparator());
}
final JButton breadcrumb = createBreadcrumb(text);
breadcrumb.setSelected(true);
add(breadcrumb);
currentCrumb = breadcrumb;
final int index = getComponentCount() - 1;
breadcrumb.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
removeTailCrumbs(index + 1);
breadcrumb.setSelected(true);
currentCrumb = breadcrumb;
if (backListener != null) {
backListener.onBreadcrumbBack(text);
}
}
});
}
private void removeTailCrumbs(int from) {
Component[] components = getComponents();
for (int i = from; i < components.length; i++) {
remove(components[i]);
}
revalidate();
repaint();
}
public void clear() {
removeAll();
currentCrumb = null;
}
protected Component createSeparator() {
UILabel separator = new UILabel("/");
separator.setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 8));
separator.setPreferredSize(new Dimension(separator.getPreferredSize().width, 17));
return separator;
}
protected JButton createBreadcrumb(String text) {
JButton button = new BreadcrumbButton(text);
button.setPreferredSize(new Dimension(button.getPreferredSize().width, 17));
return button;
}
public static class BreadcrumbButton extends JButton {
public BreadcrumbButton(String text) {
super(text);
setMargin(new Insets(0, 0, 0, 0));
setBorder(BorderFactory.createEmptyBorder());
setUI(new BasicButtonUI());
setBorderPainted(false);
setOpaque(false);
setBackground(null);
}
@Override
public Insets getMargin() {
Insets insets = super.getMargin();
if (insets != null) {
insets.set(0, 0, 0, 0);
}
return insets;
}
@Override
public void setSelected(boolean b) {
super.setSelected(b);
setForeground(b ? new Color(0x419BF9) : new Color(0x838384));
repaint();
}
}
public interface BreadcrumbBackListener {
void onBreadcrumbBack(String text);
}
}

8
designer-base/src/main/java/com/fr/design/mainframe/toolbar/ToolBarMenuDock.java

@ -408,7 +408,9 @@ public abstract class ToolBarMenuDock {
menuDef.addShortCut(new OpenRecentReportMenuDef());
addCloseCurrentTemplateAction(menuDef);
if (!DesignModeContext.isDuchampMode()) {
addCloseCurrentTemplateAction(menuDef);
}
scs = plus.shortcut4FileMenu();
if (!ArrayUtils.isEmpty(scs)) {
@ -467,6 +469,10 @@ public abstract class ToolBarMenuDock {
return new UILabel();
}
public Component createGuideEntryPane() {
return new UILabel();
}
public Component createNotificationCenterPane(){
return new UILabel();
}

61
designer-base/src/main/java/com/fr/design/os/impl/DatabaseDialogAction.java

@ -1,18 +1,8 @@
package com.fr.design.os.impl;
import com.fr.design.data.datapane.connect.ConnectionManagerPane;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.editlock.EditLockUtils;
import com.fr.design.data.datapane.connect.ConnectionListPane;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.DesignerFrame;
import com.fr.file.ConnectionConfig;
import com.fr.stable.os.support.OSBasedAction;
import com.fr.transaction.CallBackAdaptor;
import com.fr.transaction.Configurations;
import com.fr.transaction.WorkerFacade;
import com.fr.report.LockItem;
import static com.fr.design.actions.server.ConnectionListAction.doWithDatasourceManager;
/**
* 数据连接窗口
@ -33,54 +23,7 @@ public class DatabaseDialogAction implements OSBasedAction {
}
private void openDesignDatabaseManager() {
DesignerFrame designerFrame = DesignerContext.getDesignerFrame();
final ConnectionConfig datasourceManager = ConnectionConfig.getInstance();
final ConnectionManagerPane databaseManagerPane = new ConnectionManagerPane() {
public void complete() {
ConnectionConfig connectionConfig = datasourceManager.mirror();
populate(connectionConfig);
}
protected void renameConnection(String oldName, String newName) {
datasourceManager.renameConnection(oldName, newName);
}
};
final BasicDialog databaseListDialog = databaseManagerPane.showLargeWindow(designerFrame, null);
databaseListDialog.addDialogActionListener(new DialogActionAdapter() {
public void doOk() {
if (!databaseManagerPane.isNamePermitted()) {
databaseListDialog.setDoOKSucceed(false);
return;
}
Configurations.modify(new WorkerFacade(ConnectionConfig.class) {
@Override
public void run() {
databaseManagerPane.update(datasourceManager);
}
}.addCallBack(new CallBackAdaptor() {
@Override
public boolean beforeCommit() {
//如果更新失败,则不关闭对话框,也不写xml文件,并且将对话框定位在请重命名的那个对象页面
return doWithDatasourceManager(datasourceManager, databaseManagerPane, databaseListDialog);
}
@Override
public void afterCommit() {
DesignerContext.getDesignerBean("databasename").refreshBeanElement();
// 定义数据连接弹窗关闭后,解锁
EditLockUtils.unlock(LockItem.CONNECTION);
}
}));
}
@Override
public void doCancel() {
super.doCancel();
// 定义数据连接弹窗关闭后,解锁
EditLockUtils.unlock(LockItem.CONNECTION);
}
});
databaseListDialog.setVisible(true);
ConnectionListPane.showDialog(DesignerContext.getDesignerFrame());
}

2
designer-base/src/main/java/com/fr/design/report/fit/menupane/ReportFitAttrAction.java

@ -60,7 +60,7 @@ public class ReportFitAttrAction extends JTemplateAction {
}
final FitProvider wbTpl = (FitProvider) jwb.getTarget();
ReportFitAttr fitAttr = wbTpl.getReportFitAttr();
TemplateFitAttrPane templateFitAttrPane = new TemplateFitAttrPane();
TemplateFitAttrPane templateFitAttrPane = new TemplateFitAttrPane(jwb);
showReportFitDialog(fitAttr, jwb, wbTpl, templateFitAttrPane);
}

9
designer-base/src/main/java/com/fr/design/report/fit/menupane/TemplateFitAttrPane.java

@ -1,6 +1,5 @@
package com.fr.design.report.fit.menupane;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.report.fit.BaseFitAttrPane;
@ -15,7 +14,10 @@ import java.awt.event.ItemListener;
public class TemplateFitAttrPane extends BaseFitAttrPane {
public TemplateFitAttrPane() {
private JTemplate jwb;
public TemplateFitAttrPane(JTemplate jwb) {
this.jwb = jwb;
initComponents();
}
@ -23,7 +25,7 @@ public class TemplateFitAttrPane extends BaseFitAttrPane {
protected void initComponents() {
super.initComponents();
for (FitAttrModel fitAttrModel : fitAttrModelList) {
if (fitAttrModel.isAvailable(HistoryTemplateListCache.getInstance().getCurrentEditingTemplate())) {
if (fitAttrModel.isAvailable(jwb)) {
populateModel(fitAttrModel);
break;
}
@ -71,7 +73,6 @@ public class TemplateFitAttrPane extends BaseFitAttrPane {
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
if(isTemplateSingleSet()){
JTemplate jwb = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
if (jwb != null) {
FitProvider wbTpl = (FitProvider) jwb.getTarget();
ReportFitAttr fitAttr = wbTpl.getReportFitAttr();

22
designer-base/src/main/java/com/fr/design/style/color/NewColorSelectPane.java

@ -39,8 +39,10 @@ import java.util.List;
public class NewColorSelectPane extends BasicPane implements ColorSelectable {
private static final long serialVersionUID = -8634152305687249392L;
private static final int WIDTH = 197;
private static final int HEIGHT = 250;
private static final int WIDTH = 216;
private static final int HEIGHT = 230;
private static final int DEFAULT_COLOR_HOR_INTERVAL = 4;
//颜色衍生的数量
private static final int DEFAULT_DERIVE_COUNT = 5;
@ -81,7 +83,7 @@ public class NewColorSelectPane extends BasicPane implements ColorSelectable {
initSelectButton(isSupportTransparent);
// center
JPanel centerPane = FRGUIPaneFactory.createY_AXISBoxInnerContainer_S_Pane();
centerPane.setBorder(BorderFactory.createEmptyBorder(10, 4, 0, 4));
centerPane.setBorder(BorderFactory.createEmptyBorder(10, 6, 0, 6));
this.add(centerPane, BorderLayout.CENTER);
menuColorPane = getMenuColorPane();
@ -126,14 +128,14 @@ public class NewColorSelectPane extends BasicPane implements ColorSelectable {
customButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
JPanel centerPane1 = new JPanel(new BorderLayout(0, 0));
centerPane1.setBorder(BorderFactory.createEmptyBorder(9, 0, 11, 0));
centerPane1.setBorder(BorderFactory.createEmptyBorder(8, 0, 9, 0));
centerPane1.add(customButton, BorderLayout.CENTER);
customButton.setPreferredSize(new Dimension(197, 20));
centerPane.add(centerPane1);
}
private JPanel createStandardColorPane() {
JPanel jPanel = new JPanel(new GridLayout(1, 10, 3, 0));
JPanel jPanel = new JPanel(new GridLayout(1, 10, DEFAULT_COLOR_HOR_INTERVAL, 0));
Color[] colorArray = ColorFactory.STANDARD_COLORS;
for (int i = 0; i < colorArray.length; i++) {
jPanel.add(new ColorCell(colorArray[i], this));
@ -150,8 +152,8 @@ public class NewColorSelectPane extends BasicPane implements ColorSelectable {
themeColorPane.add(menuColorPane, BorderLayout.SOUTH);
menuColorPane.setLayout(new BorderLayout(0, 10));
JPanel northPane = new JPanel(new GridLayout(1, 8, 3, 0));
JPanel centerPane = new JPanel(new GridLayout(1, 8, 3, 0));
JPanel northPane = new JPanel(new GridLayout(1, 8, DEFAULT_COLOR_HOR_INTERVAL, 0));
JPanel centerPane = new JPanel(new GridLayout(1, 8, DEFAULT_COLOR_HOR_INTERVAL, 0));
menuColorPane.add(northPane, BorderLayout.NORTH);
menuColorPane.add(centerPane, BorderLayout.CENTER);
@ -189,7 +191,7 @@ public class NewColorSelectPane extends BasicPane implements ColorSelectable {
northPane.add(themeColorCellGrid[i][0]);
}
for (int i = 0; i < colorArray.length; i++) {
JPanel columnPane = new JPanel(new GridLayout(DEFAULT_DERIVE_COUNT - 1, 1, 0, 3));
JPanel columnPane = new JPanel(new GridLayout(DEFAULT_DERIVE_COUNT - 1, 1, 0, 0));
for (int j = 1; j < DEFAULT_DERIVE_COUNT; j++) {
columnPane.add(themeColorCellGrid[i][j]);
}
@ -233,7 +235,7 @@ public class NewColorSelectPane extends BasicPane implements ColorSelectable {
private void initMenuColorPane() {
menuColorPane.setLayout(new GridLayout(5, 8, 3, 3));
menuColorPane.setLayout(new GridLayout(5, 8, DEFAULT_COLOR_HOR_INTERVAL, 0));
Color[] colorArray = this.getColorArray();
for (int i = 0; i < colorArray.length; i++) {
Color color = colorArray[i] == null ? UsedColorPane.DEFAULT_COLOR : colorArray[i];
@ -409,7 +411,7 @@ public class NewColorSelectPane extends BasicPane implements ColorSelectable {
private void initialComponents() {
int total = columns;
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(1, columns + 1, 3, 3));
panel.setLayout(new GridLayout(1, columns + 1, DEFAULT_COLOR_HOR_INTERVAL, 0));
panel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
//最近使用颜色
Color[] colors = DesignerEnvManager.getEnvManager().getColorConfigManager().getColors();

5
designer-base/src/main/java/com/fr/design/ui/ModernUIPane.java

@ -26,6 +26,7 @@ import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.Map;
/**
@ -170,6 +171,10 @@ public class ModernUIPane<T> extends BasicPane {
public void clearCache() {
if (browser != null) {
browser.getCacheStorage().clearCache();
File file = new File(browser.getContext().getCacheDir());
if (file.exists()) {
file.delete();
}
}
}

60
designer-base/src/main/java/com/fr/design/utils/ComponentUtils.java

@ -1,11 +1,13 @@
package com.fr.design.utils;
import com.fr.general.ComparatorUtils;
import com.fr.stable.StringUtils;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.List;
/**
* 工具类提供常用的工具方法
@ -151,4 +153,62 @@ public class ComponentUtils {
}
return false;
}
public static Component findComponentByName(Component container, String componentName) {
Component target = null;
if (container instanceof Container) {
for (Component component: ((Container)container).getComponents()) {
if (componentName.equals(component.getName())) {
return component;
}
if (component instanceof JRootPane) {
JRootPane nestedJRootPane = (JRootPane)component;
target = findComponentByName(nestedJRootPane.getContentPane(), componentName);
} else if (component instanceof Container){
target = findComponentByName( component, componentName);
}
if (target != null) {
return target;
}
}
}
return null;
}
public static Component findComponentByClass(Component container, Class clazz) {
Component target = null;
if (container instanceof Container) {
for (Component component: ((Container)container).getComponents()) {
if (clazz.isInstance(component)) {
return component;
}
if (component instanceof JRootPane) {
JRootPane nestedJRootPane = (JRootPane)component;
target = findComponentByClass(nestedJRootPane.getContentPane(), clazz);
} else if (component instanceof Container){
target = findComponentByClass(component, clazz);
}
if (target != null) {
return target;
}
}
}
return null;
}
public static List<Component> findComponentsByClass(Component container, Class clazz) {
List<Component> components= new ArrayList<>();
if (container instanceof Container) {
for (Component component: ((Container)container).getComponents()) {
if (clazz.isInstance(component)) {
components.add(component);
continue;
}
if (component instanceof Container){
components.addAll(findComponentsByClass(component, clazz));
}
}
}
return components;
}
}

25
designer-base/src/main/java/com/fr/design/worker/open/OpenWorker.java

@ -7,12 +7,14 @@ import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.DesignerFrameFileDealerPane;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.utils.DesignUtils;
import com.fr.design.worker.WorkerManager;
import com.fr.exception.DecryptTemplateException;
import com.fr.file.FILE;
import com.fr.general.ComparatorUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.StringUtils;
import javax.swing.JOptionPane;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
@ -61,7 +63,7 @@ public class OpenWorker<T> extends SwingWorker<T, Void> {
} catch (CancellationException ignored) {
return;
} catch (Throwable t) {
processFailed();
processFailed(StringUtils.EMPTY);
Throwable cause = t.getCause();
if (cause instanceof DecryptTemplateException) {
FineJOptionPane.showMessageDialog(
@ -91,6 +93,11 @@ public class OpenWorker<T> extends SwingWorker<T, Void> {
if (slowly && templateCallable != null) {
try {
JTemplate<?, ?> book = templateCallable.call();
if (inValidDesigner(book)) {
String text = Toolkit.i18nText("Fine-Design_Report_Template_Version_Not_Match", DesignUtils.parseVersion(book.getTarget().getDesignerVersion()));
processFailed(text);
return;
}
FILE tplFile = book.getEditingFILE();
JTemplate<?, ?> currentTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
// 当前tab页是正在打开的模板
@ -117,11 +124,21 @@ public class OpenWorker<T> extends SwingWorker<T, Void> {
WorkerManager.getInstance().removeWorker(taskName);
}
private void processFailed() {
private boolean inValidDesigner(JTemplate<?, ?> jt) {
return jt.isOldDesigner(false) || (!jt.isJWorkBook() && jt.isNewDesigner(false));
}
private void processFailed(String text) {
this.template.setOpenFailed(true);
this.template.setOpening(false);
DesignerContext.getDesignerFrame().getCenterTemplateCardPane().showOpenFailedCover();
DesignerFrameFileDealerPane.getInstance().stateChange();
JTemplate<?, ?> currentTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
// 需要判断当前打开的模板是不是异步执行后失败的模板 是的话立即展示失败后的提示内容 否则只设置下失败的提示内容
if (ComparatorUtils.equals(currentTemplate.getEditingFILE().getName(), this.template.getName())) {
DesignerContext.getDesignerFrame().getCenterTemplateCardPane().showOpenFailedCover(text);
DesignerFrameFileDealerPane.getInstance().stateChange();
} else {
this.template.setTemplateOpenFailedTip(text);
}
WorkerManager.getInstance().removeWorker(taskName);
}

8
designer-base/src/main/java/com/fr/design/write/submit/CustomJobPane.java

@ -13,6 +13,7 @@ import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.DialogActionAdapter;
import com.fr.stable.ListMap;
import com.fr.stable.StringUtils;
import com.fr.design.utils.gui.GUICoreUtils;
@ -115,7 +116,12 @@ public abstract class CustomJobPane extends BasicBeanPane {
@Override
public void populateBean(Object ob) {
if (ob instanceof AbstractClassJob) {
if (ob == null) {
// 自定义提交新增时初始化页面 REPORT-59256
this.classNameTextField.setText(StringUtils.EMPTY);
this.objectProperiesPane.populateBean(new ListMap());
}
else if (ob instanceof AbstractClassJob) {
AbstractClassJob cj = (AbstractClassJob) ob;
this.classNameTextField.setText(cj.getClassName());
this.objectProperiesPane.populateBean(cj.getPropertyMap());

2
designer-base/src/main/java/com/fr/env/ErrorDialog.java vendored

@ -39,7 +39,7 @@ public class ErrorDialog extends JDialog implements ActionListener {
messagePanel.setBorder(BorderFactory.createEmptyBorder(5,0,0,0));
MessageWithLink messageWithLink = new MessageWithLink(message + ",", Toolkit.i18nText("Fine-Design_Basic_Sync_Help"), CloudCenter.getInstance().acquireUrlByKind("help.replacejars", "https://help.fanruan.com/finereport/doc-view-3268.html"));
messageWithLink.setPreferredSize(new Dimension(108, 20));
messageWithLink.setPreferredSize(new Dimension(150, 20));
JPanel messageLinkPane = FRGUIPaneFactory.createBorderLayout_L_Pane();
messageLinkPane.setBorder(BorderFactory.createEmptyBorder(5, 8, 5, 0));
messageLinkPane.add(messageWithLink);

3
designer-base/src/main/java/com/fr/env/SyncFailedPluginsDialog.java vendored

@ -5,6 +5,7 @@ import com.fr.design.dialog.link.MessageWithLink;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.itextarea.UITextArea;
import com.fr.design.i18n.DesignSizeI18nManager;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.DesignerContext;
@ -62,7 +63,7 @@ public class SyncFailedPluginsDialog extends JDialog {
JPanel messagePane = FRGUIPaneFactory.createBorderLayout_S_Pane();
MessageWithLink messageWithLink = new MessageWithLink(Toolkit.i18nText("Fine-Design_Basic_Sync_Plugin_Fail_Suggestion"),Toolkit.i18nText("Fine-Design_Basic_Sync_Deal_Immediately"),
CloudCenter.getInstance().acquireUrlByKind("help.installplugins", "https://help.fanruan.com/finereport/doc-view-2198.html"));
messageWithLink.setPreferredSize(new Dimension(316, 20));
messageWithLink.setPreferredSize(DesignSizeI18nManager.getInstance().i18nDimension("com.fr.env.SyncFailedPluginsDialog.messageWithLink"));
messagePane.add(messageWithLink);
messagePane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 0));

22
designer-base/src/main/java/com/fr/file/FILEChooserPane.java

@ -29,6 +29,9 @@ import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.mainframe.DesignerFrame;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.event.Event;
import com.fr.event.EventDispatcher;
import com.fr.event.Listener;
import com.fr.file.filetree.FileNode;
import com.fr.file.filter.ChooseFileFilter;
import com.fr.file.filter.FILEFilter;
@ -45,6 +48,8 @@ import com.fr.stable.os.windows.WindowsDetector;
import com.fr.stable.project.ProjectConstants;
import com.fr.workspace.WorkContext;
import com.fr.workspace.Workspace;
import com.fr.workspace.WorkspaceEvent;
import javax.swing.AbstractAction;
import javax.swing.AbstractListModel;
import javax.swing.ActionMap;
@ -66,7 +71,6 @@ import javax.swing.ListModel;
import javax.swing.ListSelectionModel;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.ListSelectionEvent;
@ -644,7 +648,7 @@ public class FILEChooserPane extends BasicPane {
this.suffix = suffix;
if (!text.endsWith(suffix)) {
text = text + suffix;
text = removeSuffix(text) + suffix;
}
fileNameTextField.removeDocumentListener();
fileNameTextField.setText(text);
@ -660,6 +664,14 @@ public class FILEChooserPane extends BasicPane {
fileNameTextField.setFilter(new DefaultCompletionFilter(names));
}
/**
* 移除文件后缀的方法
* 解决cptx文件的另存为操作默认会出现双后缀的bug(xxx.cptx.cpt)
**/
private String removeSuffix(String text){
return FileExtension.CPTX.matchExtension(text) ? text.substring(0, text.length() - FileExtension.CPTX.getSuffix().length()) : text;
}
/**
* 打开对话框
@ -1326,6 +1338,12 @@ public class FILEChooserPane extends BasicPane {
LocationButtonPane.this.repaint(10);
}
});
EventDispatcher.listen(WorkspaceEvent.AfterSwitch, new Listener<Workspace>() {
@Override
public void on(Event event, Workspace param) {
setPopDir(null);
}
});
}
public void highLightButton(FILE dir) {

2
designer-base/src/main/java/com/fr/nx/app/designer/toolbar/TransformResultInfo.java

@ -57,7 +57,7 @@ public class TransformResultInfo {
return InterProviderFactory.getProvider().getLocText("Fine-Plugin_Engine_Transform_Success_Tip");
case UNSUPPORT:
return transformLog + "\n"
+ InterProviderFactory.getProvider().getLocText("Fine-Plugin_Engine_Transform_Unsupport_Tip");
+ InterProviderFactory.getProvider().getLocText("Fine-Plugin_Engine_X_Unsupport_Tip");
}
return transformLog;
}

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

Loading…
Cancel
Save