Browse Source

Merge pull request #11976 in DESIGN/design from bugfix/11.0 to release/11.0

* commit '051bf9c362c9f1de654787a536d8bfd929640751': (42 commits)
  REPORT-91074 解决冲突
  REPORT-91074 解决冲突
  改下类名
  fix:代码规范
  fix:代码规范修改
  REPORT-83195 卡顿点优化-回退一下开发者模式部分代码,设计有点问题
  fix:代码修改
  REPORT-93901 打开js高级编辑界面设计器卡死需重启 & REPORT-83195 卡顿点优化 卡顿/卡死问题修改
  REPORT-93901 打开js高级编辑界面设计器卡死需重启 & REPORT-83195 卡顿点优化 卡顿/卡死问题修改
  REPORT-93901 打开js高级编辑界面设计器卡死需重启 & REPORT-83195 卡顿点优化 卡顿/卡死问题修改
  REPORT-83195 卡顿点优化-根据插件提示修改了一下代码规范
  REPORT-83195 卡顿点优化-根据插件提示修改了一下代码规范
  fix:代码规范
  REPORT-83195 卡顿点优化-根据插件提示修改了一下代码规范
  fix:处理代码兼容
  fix:修改代码规范
  fix:修改代码规范
  REPORT-83195 卡顿点优化-开发者模式
  fix:修改代码规范
  REPORT-83195 卡顿点优化-单元格初次添加图表卡死
  ...
release/11.0
superman 2 years ago
parent
commit
844e6d809b
  1. 2
      designer-base/src/main/java/com/fr/design/EnvChangeEntrance.java
  2. 8
      designer-base/src/main/java/com/fr/design/actions/file/CloseCurrentTemplateAction.java
  3. 4
      designer-base/src/main/java/com/fr/design/actions/file/RenameAction.java
  4. 2
      designer-base/src/main/java/com/fr/design/actions/file/SwitchExistEnv.java
  5. 46
      designer-base/src/main/java/com/fr/design/data/BasicTableDataTreePane.java
  6. 2
      designer-base/src/main/java/com/fr/design/data/DesignTableDataManager.java
  7. 68
      designer-base/src/main/java/com/fr/design/file/CloseOption.java
  8. 41
      designer-base/src/main/java/com/fr/design/file/HistoryTemplateListCache.java
  9. 351
      designer-base/src/main/java/com/fr/design/file/MultiTemplateTabMenuFactory.java
  10. 576
      designer-base/src/main/java/com/fr/design/file/MultiTemplateTabPane.java
  11. 6
      designer-base/src/main/java/com/fr/design/file/MutilTempalteTabPane.java
  12. 6
      designer-base/src/main/java/com/fr/design/file/NewTemplatePane.java
  13. 39
      designer-base/src/main/java/com/fr/design/file/SaveSomeTemplatePane.java
  14. 291
      designer-base/src/main/java/com/fr/design/file/TemplateTabManager.java
  15. 129
      designer-base/src/main/java/com/fr/design/file/TemplateTabOperateProvider.java
  16. 364
      designer-base/src/main/java/com/fr/design/file/impl/AbstractTemplateTabOperate.java
  17. 41
      designer-base/src/main/java/com/fr/design/file/impl/DefaultTemplateTabOperate.java
  18. 124
      designer-base/src/main/java/com/fr/design/file/impl/EmptyTemplateTabOperate.java
  19. 31
      designer-base/src/main/java/com/fr/design/gui/controlpane/UIListGroupControlPane.java
  20. 65
      designer-base/src/main/java/com/fr/design/javascript/JSContentWithDescriptionPane.java
  21. 2
      designer-base/src/main/java/com/fr/design/locale/impl/VideoMark.java
  22. 29
      designer-base/src/main/java/com/fr/design/mainframe/CenterRegionContainerPane.java
  23. 8
      designer-base/src/main/java/com/fr/design/mainframe/DefaultToolKitConfig.java
  24. 4
      designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java
  25. 10
      designer-base/src/main/java/com/fr/design/mainframe/DesignerFrameFileDealerPane.java
  26. 139
      designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java
  27. 10
      designer-base/src/main/java/com/fr/design/mainframe/ToolKitConfigStrategy.java
  28. 10
      designer-base/src/main/java/com/fr/design/mainframe/toolbar/ToolBarMenuDock.java
  29. 8
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/FileVersionCellEditor.java
  30. 8
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/FileVersionsPanel.java
  31. 4
      designer-base/src/main/java/com/fr/design/worker/open/OpenWorker.java
  32. 52
      designer-base/src/main/java/com/fr/design/worker/save/SaveWorker.java
  33. 50
      designer-base/src/main/java/com/fr/design/worker/save/type/SaveType.java
  34. 81
      designer-base/src/main/java/com/fr/design/worker/save/type/SaveTypeWorker.java
  35. 8
      designer-base/src/main/java/com/fr/nx/app/designer/toolbar/TemplateTransformer.java
  36. 6
      designer-base/src/main/java/com/fr/start/BaseDesigner.java
  37. 4
      designer-base/src/main/java/com/fr/start/common/DesignerOpenEmptyPanel.java
  38. 31
      designer-chart/src/main/java/com/fr/design/mainframe/ChartPropertyPane.java
  39. 10
      designer-form/src/main/java/com/fr/design/designer/creator/XNumberEditor.java
  40. 4
      designer-form/src/main/java/com/fr/design/fit/common/TemplateTool.java
  41. 5
      designer-form/src/main/java/com/fr/design/parameter/RootDesignDefinePane.java
  42. 5
      designer-form/src/main/java/com/fr/design/preview/DeveloperPreview.java
  43. 1
      designer-form/src/main/java/com/fr/design/widget/ui/designer/mobile/ScanCodeMobileDefinePane.java
  44. 87
      designer-form/src/main/java/com/fr/design/widget/ui/designer/mobile/component/MobileTextFieldInputSettingPane.java
  45. 4
      designer-realize/src/main/java/com/fr/design/mainframe/JWorkBook.java
  46. 20
      designer-realize/src/main/java/com/fr/design/webattr/EventPane.java
  47. 1
      designer-realize/src/main/java/com/fr/design/widget/ui/mobile/ScanCodeMobilePane.java
  48. 4
      designer-realize/src/main/java/com/fr/start/MainDesigner.java

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

@ -134,7 +134,7 @@ public class EnvChangeEntrance {
}
//REPORT-13810如果只是添加了工作目录,没有切换,这里ToolArea也是要显示新建的工作目录
JTemplate template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
if (template != null) {
if (JTemplate.isValid(template)) {
template.refreshToolArea();
}
PluginErrorDesignReminder.getInstance().remindStartFailedPlugins();

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

@ -3,7 +3,7 @@ package com.fr.design.actions.file;
import com.fr.design.actions.UpdateAction;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.file.HistoryTemplateListPane;
import com.fr.design.file.MultiTemplateTabPane;
import com.fr.design.file.TemplateTabManager;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.menu.KeySetUtils;
@ -28,9 +28,9 @@ public class CloseCurrentTemplateAction extends UpdateAction {
* @param e 事件
*/
public void actionPerformed(ActionEvent e) {
MultiTemplateTabPane.getInstance().setIsCloseCurrent(true);
MultiTemplateTabPane.getInstance().closeFormat(HistoryTemplateListPane.getInstance().getCurrentEditingTemplate());
MultiTemplateTabPane.getInstance().closeSpecifiedTemplate(HistoryTemplateListPane.getInstance().getCurrentEditingTemplate());
TemplateTabManager.getInstance().setCloseCurrent(true);
TemplateTabManager.getInstance().closeFormat(HistoryTemplateListPane.getInstance().getCurrentEditingTemplate());
TemplateTabManager.getInstance().closeSpecifiedTemplate(HistoryTemplateListPane.getInstance().getCurrentEditingTemplate());
}
@Override

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

@ -7,7 +7,7 @@ import com.fr.design.actions.UpdateAction;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.file.FileOperations;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.file.MultiTemplateTabPane;
import com.fr.design.file.TemplateTabManager;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.itextfield.UITextField;
@ -88,7 +88,7 @@ public class RenameAction extends UpdateAction {
}
new FileRenameDialog(node);
MultiTemplateTabPane.getInstance().repaint();
TemplateTabManager.getInstance().refresh();
DesignerFrameFileDealerPane.getInstance().stateChange();
}

2
designer-base/src/main/java/com/fr/design/actions/file/SwitchExistEnv.java

@ -68,7 +68,7 @@ public class SwitchExistEnv extends MenuDef {
EnvChangeEntrance.getInstance().chooseEnv(envName);
} else {
SaveSomeTemplatePane saveSomeTemplatePane = new SaveSomeTemplatePane(true);
if (saveSomeTemplatePane.showSavePane()) {
if (saveSomeTemplatePane.showSavePane(true)) {
// 用户模板保存后,才进行切换目录操作
EnvChangeEntrance.getInstance().switch2Env(envName);
}

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

@ -5,14 +5,17 @@ import com.fr.base.TableData;
import com.fr.base.svg.IconUtils;
import com.fr.data.MultiResultTableData;
import com.fr.data.TableDataSource;
import com.fr.data.impl.DBTableData;
import com.fr.design.DesignModelAdapter;
import com.fr.design.actions.UpdateAction;
import com.fr.design.data.datapane.TableDataCreatorProducer;
import com.fr.design.data.datapane.TableDataNameObjectCreator;
import com.fr.design.data.datapane.TableDataSourceOP;
import com.fr.design.data.datapane.TableDataTree;
import com.fr.design.data.datapane.auth.TableDataAuthHelper;
import com.fr.design.data.tabledata.ResponseDataSourceChange;
import com.fr.design.data.tabledata.tabledatapane.AbstractTableDataPane;
import com.fr.design.data.tabledata.tabledatapane.loading.TableDataLoadingPane;
import com.fr.design.data.tabledata.wrapper.MultiResultTableDataWrapper;
import com.fr.design.data.tabledata.wrapper.TableDataWrapper;
import com.fr.design.data.tabledata.wrapper.TemplateTableDataWrapper;
@ -42,6 +45,8 @@ import javax.swing.DefaultCellEditor;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.tree.TreeCellEditor;
@ -51,6 +56,7 @@ import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Collection;
import java.util.EventObject;
import java.util.HashMap;
import java.util.HashSet;
@ -449,7 +455,45 @@ public abstract class BasicTableDataTreePane extends DockingView implements Resp
storeProcedureDataWrapper.previewData(MultiResultTableDataWrapper.PREVIEW_ALL);
}
} else {
((TableDataWrapper) data).previewData();
TableDataWrapper wrapper = ((TableDataWrapper) data);
if (TableDataAuthHelper.needCheckAuthWhenEdit(wrapper.getTableData())) {
// 先打开一个Loading面板
TableDataLoadingPane loadingPane = new TableDataLoadingPane();
BasicDialog loadingDialog = loadingPane.showLargeWindow(SwingUtilities.getWindowAncestor(BasicTableDataTreePane.this), null);
// 查询权限
new SwingWorker<Boolean, Void>() {
@Override
protected Boolean doInBackground() throws Exception {
// 获取无权限连接名称集合
Collection<String> noAuthConnections = TableDataAuthHelper.getNoAuthConnections();
// 获取当前数据集对应的数据连接名称
String connectionName = TableDataAuthHelper.getConnectionNameByDBTableData((DBTableData) wrapper.getTableData());
return !noAuthConnections.contains(connectionName);
}
@Override
protected void done() {
try {
Boolean hasAuth = get();
if (hasAuth) {
// 有权限时,关闭Loading面板,打开编辑面板
loadingDialog.setVisible(false);
wrapper.previewData();
} else {
// 无权限时,给出无权限提示
loadingPane.switchTo(TableDataLoadingPane.NO_AUTH_PANE_NAME);
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error("loading connection error in remote design", e.getMessage());
// 查询权限失败时,给出报错提示
loadingPane.switchTo(TableDataLoadingPane.ERROR_NAME);
}
}
}.execute();
loadingDialog.setVisible(true);
} else {
wrapper.previewData();
}
}
} catch (Exception ex) {

2
designer-base/src/main/java/com/fr/design/data/DesignTableDataManager.java

@ -32,6 +32,7 @@ import com.fr.file.TableDataConfig;
import com.fr.general.ComparatorUtils;
import com.fr.general.data.DataModel;
import com.fr.general.data.TableDataException;
import com.fr.general.sql.sqlnote.SqlNoteConstants;
import com.fr.log.FineLoggerFactory;
import com.fr.module.ModuleContext;
import com.fr.script.Calculator;
@ -571,6 +572,7 @@ public abstract class DesignTableDataManager {
parameter.setValue(parameterMap.get(parameter.getName()));
}
}
parameterMap.put(SqlNoteConstants.SQL_NOTE_TEMPLATE, HistoryTemplateListCache.getInstance().getCurrentEditingTemplate().getEditingFILE().getPath());
return DataOperator.getInstance().previewTableData(TableDataSourceTailor.extractTableData(tableDataSource), tabledata, parameterMap, rowCount);
} catch (Exception e) {
throw new TableDataException(e.getMessage(), e);

68
designer-base/src/main/java/com/fr/design/file/CloseOption.java

@ -0,0 +1,68 @@
package com.fr.design.file;
import com.fr.design.i18n.Toolkit;
/**
* @author kerry
* @since 11.0
* created on 2023-04-14
**/
public enum CloseOption {
/**
* 关闭左侧所有模板
*/
Left(Toolkit.i18nText("Fine-Design_Close_templates_To_The_Left")) {
@Override
public boolean shouldClose(int tplIndex, int i) {
return i < tplIndex;
}
},
/**
* 关闭右侧所有模板
*/
Right(Toolkit.i18nText("Fine-Design_Close_templates_To_The_Right")) {
@Override
public boolean shouldClose(int tplIndex, int i) {
return i > tplIndex;
}
},
/**
* 关闭所有模板
*/
All(Toolkit.i18nText("Fine-Design_Close_All_templates")),
/**
* 关闭其他模板
*/
Others(Toolkit.i18nText("Fine-Design_Close_Other_templates")) {
@Override
public boolean shouldClose(int tplIndex, int i) {
return i != tplIndex;
}
};
private String optionName;
public String getOptionName() {
return this.optionName;
}
CloseOption(String optionName) {
this.optionName = optionName;
}
/**
* 判断指定索引模板是否应该被关闭
* @param tplIndex
* @param i
* @return
*/
public boolean shouldClose(int tplIndex, int i) {
return true;
}
}

41
designer-base/src/main/java/com/fr/design/file/HistoryTemplateListCache.java

@ -75,7 +75,7 @@ public class HistoryTemplateListCache implements CallbackEvent {
historyList.remove(contains(selected));
selected.getEditingFILE().closeTemplate();
FineLoggerFactory.getLogger().info(Toolkit.i18nText("Fine-Design_Basic_Template_Closed_Warn_Text", selected.getEditingFILE().getName()));
MultiTemplateTabPane.getInstance().refreshOpenedTemplate(historyList);
TemplateTabManager.getInstance().refreshOpenedTemplate(historyList);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
@ -134,10 +134,10 @@ public class HistoryTemplateListCache implements CallbackEvent {
if (contains(jt) == -1) {
addHistory();
}
MultiTemplateTabPane.getInstance().refreshOpenedTemplate(historyList);
TemplateTabManager.getInstance().refreshOpenedTemplate(historyList);
//设置tab栏为当前选中的那一栏
if (editingTemplate != null) {
MultiTemplateTabPane.getInstance().setSelectedIndex(contains(jt));
TemplateTabManager.getInstance().resetSelectIndex(jt);
}
}
@ -268,13 +268,14 @@ public class HistoryTemplateListCache implements CallbackEvent {
boolean replaceWithJVirtualTemplate = overTemplate.getEditingFILE().exists()
&& overTemplate.isALLSaved()
&& overTemplate != editingTemplate
&& overTemplate.checkEnable();
&& overTemplate.checkEnable()
&& overTemplate.supportCache();
if (replaceWithJVirtualTemplate) {
closeVirtualSelectedReport(overTemplate);
historyList.set(i, new JVirtualTemplate(overTemplate.getEditingFILE()));
}
}
MultiTemplateTabPane.getInstance().refreshOpenedTemplate(historyList);
TemplateTabManager.getInstance().refreshOpenedTemplate(historyList);
}
@ -285,35 +286,27 @@ public class HistoryTemplateListCache implements CallbackEvent {
// path like reportlets/xx/xxx/xxx
String path = file.getPath() + suffix;
ListIterator<JTemplate<?, ?>> iterator = historyList.listIterator();
List list = new ArrayList();
for(JTemplate jTemplate : historyList){
list.add(jTemplate);
}
ListIterator<JTemplate<?, ?>> iterator = list.listIterator();
while (iterator.hasNext()) {
JTemplate<?, ?> template = iterator.next();
String tPath = template.getPath();
if (isDir ? tPath.startsWith(path) : tPath.equals(path)) {
int size = getHistoryCount();
iterator.remove();
int index = iterator.nextIndex();
if (size == index + 1 && index > 0) {
//如果删除的是后一个Tab,则定位到前一个
MultiTemplateTabPane.getInstance().setSelectedIndex(index - 1);
}
historyList.remove(template);
TemplateTabManager.getInstance().deleteOpenedTemplate(template);
}
}
//如果打开过,则删除,实时刷新多tab面板
int openFileCount = getHistoryCount();
if (openFileCount == 0) {
DesignerContext.getDesignerFrame().addAndActivateJTemplate();
}
JTemplate selectedFile = MultiTemplateTabPane.getInstance().getSelectedFile();
JTemplate selectedFile = TemplateTabManager.getInstance().getSelectedFile();
if (!isCurrentEditingFile(selectedFile.getPath())) {
//如果此时面板上的实时刷新的selectedIndex得到的和历史的不一样
DesignerContext.getDesignerFrame().activateJTemplate(selectedFile);
}
MultiTemplateTabPane.getInstance().repaint();
TemplateTabManager.getInstance().refresh();
}
@ -474,7 +467,7 @@ public class HistoryTemplateListCache implements CallbackEvent {
int index = contains(this.editingTemplate);
this.editingTemplate = jt;
historyList.set(index, jt);
MultiTemplateTabPane.getInstance().refreshOpenedTemplate(historyList);
MultiTemplateTabPane.getInstance().setSelectedIndex(contains(jt));
TemplateTabManager.getInstance().refreshOpenedTemplate(historyList);
TemplateTabManager.getInstance().resetSelectIndex(jt);
}
}

351
designer-base/src/main/java/com/fr/design/file/MultiTemplateTabMenuFactory.java

@ -0,0 +1,351 @@
package com.fr.design.file;
import com.fr.design.constants.UIConstants;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.imenu.UIMenuItem;
import com.fr.design.gui.imenu.UIScrollPopUpMenu;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.utils.TemplateUtils;
import com.fr.file.FILE;
import com.fr.general.IOUtils;
import com.fr.stable.StringUtils;
import com.fr.stable.collections.CollectionUtils;
import com.fr.third.javax.annotation.Nonnull;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* 右侧下拉菜单的工厂类
* @author Carlson
* @since 11.0
* created on 2023-04-14
**/
public class MultiTemplateTabMenuFactory {
private static final Icon CLOSE = IOUtils.readIcon("/com/fr/design/images/buttonicon/close_icon.png");
private static final Icon MOUSE_OVER_CLOSE = IOUtils.readIcon("/com/fr/design/images/buttonicon/mouseoverclose icon.png");
private static final Icon MOUSE_PRESS_CLOSE = IOUtils.readIcon("/com/fr/design/images/buttonicon/pressclose icon.png");
private static final int ITEM_SIZE = 25;
private UIScrollPopUpMenu menu = null;
private static MultiTemplateTabMenuFactory INSTANCE = new MultiTemplateTabMenuFactory();
private MultiTemplateTabMenuFactory() {
}
/**
* 返回右侧下拉菜单的工厂类
* @return
*/
public static MultiTemplateTabMenuFactory getInstance() {
return INSTANCE;
}
/**
* tab上的下拉菜单
*/
public UIScrollPopUpMenu createMenu() {
menu = new UIScrollPopUpMenu();
menu.setBorder(BorderFactory.createEmptyBorder(-3, 3, 3, 0));
menu.add(initCloseOther());
menu.add(createEmptyRow());
menu.addSeparator();
menu.add(createEmptyRow());
menu.add(createCategory(Toolkit.i18nText("Fine-Design_Basic_Tab_Current_Category_Templates")));
Component[] items = createCurrentCategory();
for (Component item : items) {
menu.add(item);
}
items = createOtherCategory();
if (items.length > 0) {
menu.addSeparator();
menu.add(createEmptyRow());
menu.add(createCategory(Toolkit.i18nText("Fine-Design_Basic_Tab_Other_Category_Templates")));
for (Component item : items) {
menu.add(item);
}
}
Dimension dimension = menu.getPreferredSize();
dimension.width += ITEM_SIZE;
menu.setPreferredSize(dimension);
return menu;
}
/**
* 关闭其它按钮
*/
private UIMenuItem initCloseOther() {
UIMenuItem closeOther = new UIMenuItem(Toolkit.i18nText("Fine-Design_Basic_Tab_Close_Other_Templates_Of_Current_Category"));
closeOther.setHorizontalAlignment(SwingConstants.CENTER);
Dimension dimension = closeOther.getPreferredSize();
dimension.height = ITEM_SIZE;
closeOther.setPreferredSize(dimension);
closeOther.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
TemplateTabManager.getInstance().closeOthers();
}
});
if (TemplateTabManager.getInstance().getCurrentOperator().getOpenedJTemplates().size() <= 1) {
closeOther.setEnabled(false);
}
return closeOther;
}
private void closeAndFreeLock(@Nonnull JTemplate<?, ?> template) {
FILE file = template.getEditingFILE();
// 只有是环境内的文件,才执行释放锁
if (file != null && file.isEnvFile()) {
// release lock
TemplateResourceManager.getResource().closeTemplate(file.getPath());
}
}
/**
* 美观用
*/
private JPanel createEmptyRow() {
return new JPanel() {
@Override
public Dimension getPreferredSize() {
Dimension d = super.getPreferredSize();
d.height = 1;
return d;
}
};
}
/**
* 模板分类item
*/
private UIButton createCategory(String categoryName) {
UIButton button = new UIButton(categoryName);
button.setBorderPainted(false);
button.setExtraPainted(false);
button.setPreferredSize(new Dimension(menu.getWidth(), ITEM_SIZE));
button.setOpaque(true);
button.setBackground(UIConstants.NORMAL_BACKGROUND);
button.setHorizontalAlignment(SwingConstants.LEFT);
button.setForeground(UIConstants.FLESH_BLUE);
return button;
}
/**
* 创建 当前分类模板 item数组
*/
private Component[] createCurrentCategory() {
return createListDownItem(TemplateTabManager.getInstance().getCurrentOperator().getOpenedJTemplates());
}
/**
* 创建 其它分类模板 item数组
*/
private Component[] createOtherCategory() {
List<JTemplate<?, ?>> openedTemplates = new ArrayList<>();
Map<String, List<JTemplate<?, ?>>> map = TemplateTabManager.getInstance().getAllOpenedTemplateMap();
for (Map.Entry<String, List<JTemplate<?, ?>>> entry : map.entrySet()) {
if (!StringUtils.equals(TemplateTabManager.getInstance().getCurrentOperator().getOperatorType(), entry.getKey())) {
openedTemplates.addAll(entry.getValue());
}
}
return createListDownItem(openedTemplates);
}
/**
* 根据template列表创建多个item
*/
private Component[] createListDownItem(List<JTemplate<?, ?>> openedTemplates) {
if (!CollectionUtils.isEmpty(openedTemplates)) {
Component[] templates = new Component[openedTemplates.size()];
for (int i = 0; i < openedTemplates.size(); i++) {
templates[i] = createListDownMenuItem(openedTemplates.get(i));
}
return templates;
}
return new Component[0];
}
/**
* 根据template对象创建item
*/
private Component createListDownMenuItem(JTemplate<?, ?> template) {
JPanel jPanel = new JPanel();
jPanel.setPreferredSize(new Dimension(menu.getWidth(), ITEM_SIZE));
jPanel.setLayout(new BorderLayout());
MenuItemButtonGroup menuItemButtonGroup = new MenuItemButtonGroup(template);
if (template == HistoryTemplateListCache.getInstance().getCurrentEditingTemplate()) {
menuItemButtonGroup.templateButton.setForeground(UIConstants.FLESH_BLUE);
}
jPanel.add(menuItemButtonGroup.iconButton, BorderLayout.WEST);
jPanel.add(menuItemButtonGroup.templateButton, BorderLayout.CENTER);
jPanel.add(menuItemButtonGroup.closeButton, BorderLayout.EAST);
return jPanel;
}
/**
* menu的item由模板图标模板名模板关闭按钮组成
*/
private class MenuItemButtonGroup {
private final UIButton iconButton;
private final UIButton templateButton;
private final UIButton closeButton;
public MenuItemButtonGroup(JTemplate<?, ?> template) {
iconButton = createIconButton(template);
templateButton = createTemplateButton(template);
closeButton = createCloseButton();
initListener(template);
}
/**
* item[0] 模板图标按钮初始化
*/
private UIButton createIconButton(JTemplate<?, ?> template) {
UIButton button = new UIButton(template.getIcon(), template.getIcon(), template.getIcon());
button.setPreferredSize(new Dimension(ITEM_SIZE, ITEM_SIZE));
button.setOpaque(true);
button.setBackground(UIConstants.NORMAL_BACKGROUND);
return button;
}
/**
* item[1] 切换模板按钮初始化
*/
private UIButton createTemplateButton(JTemplate<?, ?> template) {
UIButton button = new UIButton(TemplateUtils.createLockeTemplatedName(template, template.getTemplateName()));
button.setBorderPainted(false);
button.setExtraPainted(false);
button.setPreferredSize(new Dimension(menu.getWidth() - ITEM_SIZE * 2, ITEM_SIZE));
button.setOpaque(true);
button.setBackground(UIConstants.NORMAL_BACKGROUND);
button.setHorizontalAlignment(SwingConstants.LEFT);
return button;
}
/**
* item[2] 关闭模板图标按钮初始化
*/
private UIButton createCloseButton() {
UIButton button = new UIButton(CLOSE, MOUSE_OVER_CLOSE, MOUSE_PRESS_CLOSE);
button.setPreferredSize(new Dimension(ITEM_SIZE, ITEM_SIZE));
button.setOpaque(true);
button.setBackground(UIConstants.NORMAL_BACKGROUND);
button.setVisible(false);
return button;
}
private void initListener(JTemplate<?, ?> template) {
initIconButtonListener();
initTemplateButtonListener(template);
initCloseButtonListener(template);
}
/**
* item[0] 模板图标按钮鼠标事件
*/
private void initIconButtonListener() {
iconButton.addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e) {
fireMouseEnteredEvent();
}
@Override
public void mouseExited(MouseEvent e) {
fireMouseExitedEvent();
}
});
}
/**
* item[1] 切换模板按钮鼠标事件
*/
private void initTemplateButtonListener(JTemplate<?, ?> template) {
templateButton.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
menu.setVisible(false);
TemplateTabManager.getInstance().switchByJTemplate(template);
}
@Override
public void mouseEntered(MouseEvent e) {
fireMouseEnteredEvent();
}
@Override
public void mouseExited(MouseEvent e) {
fireMouseExitedEvent();
}
});
}
/**
* item[2] 关闭模板按钮鼠标事件
*/
private void initCloseButtonListener(JTemplate<?, ?> template) {
closeButton.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
menu.setVisible(false);
TemplateTabManager.getInstance().closeByJTemplate(template);
}
@Override
public void mouseEntered(MouseEvent e) {
fireMouseEnteredEvent();
}
@Override
public void mouseExited(MouseEvent e) {
fireMouseExitedEvent();
}
});
}
/**
* mouse移入item范围
*/
private void fireMouseEnteredEvent() {
iconButton.setBackground(UIConstants.HOVER_BLUE);
templateButton.setBackground(UIConstants.HOVER_BLUE);
closeButton.setBackground(UIConstants.HOVER_BLUE);
closeButton.setVisible(true);
}
/**
* mouse移出item范围
*/
private void fireMouseExitedEvent() {
iconButton.setBackground(UIConstants.NORMAL_BACKGROUND);
templateButton.setBackground(UIConstants.NORMAL_BACKGROUND);
closeButton.setBackground(UIConstants.NORMAL_BACKGROUND);
closeButton.setVisible(false);
}
}
}

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

@ -1,38 +1,25 @@
package com.fr.design.file;
import com.fr.base.BaseUtils;
import com.fr.base.GraphHelper;
import com.fr.base.svg.IconUtils;
import com.fr.base.vcs.DesignerMode;
import com.fr.design.actions.UpdateAction;
import com.fr.design.actions.file.LocateAction;
import com.fr.design.constants.UIConstants;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.gui.imenu.UIMenuItem;
import com.fr.design.gui.imenu.UIPopupMenu;
import com.fr.design.gui.imenu.UIScrollPopUpMenu;
import com.fr.design.i18n.DesignSizeI18nManager;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.mainframe.TemplateSavingChecker;
import com.fr.design.mainframe.manager.search.TemplateTreeSearchManager;
import com.fr.design.utils.DesignUtils;
import com.fr.design.utils.TemplateUtils;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.design.utils.gui.GUIPaintUtils;
import com.fr.design.worker.WorkerManager;
import com.fr.design.worker.save.CallbackSaveWorker;
import com.fr.file.FILE;
import com.fr.file.FileNodeFILE;
import com.fr.general.ComparatorUtils;
import com.fr.general.IOUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.Constants;
import com.fr.third.javax.annotation.Nonnull;
import com.fr.workspace.WorkContext;
import com.fr.workspace.server.lock.TplOperator;
import javax.swing.BorderFactory;
import javax.swing.ButtonModel;
@ -41,11 +28,8 @@ import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.MenuElement;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.plaf.basic.BasicMenuItemUI;
import java.awt.AWTEvent;
@ -59,7 +43,6 @@ import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.AWTEventListener;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
@ -71,14 +54,9 @@ import java.awt.geom.Path2D;
import java.awt.geom.RoundRectangle2D;
import java.util.List;
import static com.fr.design.dialog.FineJOptionPane.showConfirmDialog;
import static javax.swing.JOptionPane.OK_CANCEL_OPTION;
import static javax.swing.JOptionPane.OK_OPTION;
import static javax.swing.JOptionPane.WARNING_MESSAGE;
/**
* 改个名字一个拼写 n 个错误
*
* 模板tab的操作和ui已拆分后续需要添加模板tab的操作在 TemplateTabManager 中添加
* @author daisy
* @version 11.0
* <p>
@ -114,10 +92,6 @@ public class MultiTemplateTabPane extends JComponent {
private static MultiTemplateTabPane THIS;
//用于存放工作簿
private java.util.List<JTemplate<?, ?>> openedTemplate;
//选中的Tab项
private int selectedIndex = 0;
//
private int mouseOveredIndex = -1;
@ -136,16 +110,11 @@ public class MultiTemplateTabPane extends JComponent {
//记录关闭按钮的状态
private int closeIconIndex = -1;
private boolean isCloseCurrent = false;
private Icon clodeMode = CLOSE;
private Icon listDownMode = LIST_DOWN;
private boolean isShowList = false;
//自动新建的模板B若没有进行任何编辑,切换到其他
//
// 模板时,模板B会自动关闭
private JTemplate<?, ?> temTemplate = null;
public static MultiTemplateTabPane getInstance() {
if (THIS == null) {
@ -165,8 +134,6 @@ public class MultiTemplateTabPane extends JComponent {
this.setBorder(null);
this.setForeground(new Color(58, 56, 58));
this.setFont(DesignUtils.getDefaultGUIFont().applySize(12));
openedTemplate = HistoryTemplateListCache.getInstance().getHistoryList();
selectedIndex = openedTemplate.size() - 1;
AWTEventListener awt = new AWTEventListener() {
@Override
public void eventDispatched(AWTEvent event) {
@ -206,45 +173,13 @@ public class MultiTemplateTabPane extends JComponent {
//根据当前i18n语言环境,动态调整popupMenu的宽度
menu.setPreferredSize(new Dimension((int) DesignSizeI18nManager.getInstance().
i18nDimension("com.fr.design.file.MultiTemplateTabPane.popUpMenu").getWidth(), height));
GUICoreUtils.showPopupMenu(menu, MultiTemplateTabPane.getInstance(), e.getX(), MultiTemplateTabPane.getInstance().getY() - 1 + MultiTemplateTabPane.getInstance().getHeight());
GUICoreUtils.showPopupMenu(menu, MultiTemplateTabPane.this, e.getX(), MultiTemplateTabPane.this.getY() - 1 + MultiTemplateTabPane.this.getHeight());
}
}
}
});
}
enum CloseOption {
Left(Toolkit.i18nText("Fine-Design_Close_templates_To_The_Left")) {
@Override
boolean shouldClose(int tplIndex, int i) {
return i < tplIndex;
}
},
Right(Toolkit.i18nText("Fine-Design_Close_templates_To_The_Right")) {
@Override
boolean shouldClose(int tplIndex, int i) {
return i > tplIndex;
}
},
All(Toolkit.i18nText("Fine-Design_Close_All_templates")),
Others(Toolkit.i18nText("Fine-Design_Close_Other_templates")) {
@Override
boolean shouldClose(int tplIndex, int i) {
return i != tplIndex;
}
};
String optionName;
CloseOption(String optionName) {
this.optionName = optionName;
}
boolean shouldClose(int tplIndex, int i) {
return true;
}
}
private static class CloseMenuItemJSeparator extends JSeparator {
@Override
@ -272,41 +207,10 @@ public class MultiTemplateTabPane extends JComponent {
@Override
public void actionPerformed(ActionEvent e) {
//处于搜索模式时,先退出搜索模式,再定位
if (TemplateTreeSearchManager.getInstance().isInSearchMode()) {
TemplateTreeSearchManager.getInstance().outOfSearchMode();
TemplateTreePane.getInstance().refreshDockingView();
}
JTemplate<?, ?> template = openedTemplate.get(this.tplIndex);
locateTemplate(template);
//DefaultTemplateTabOperate.getInstance().locateTemplateInTree(this.tplIndex);
TemplateTabManager.getInstance().getCurrentOperator().locateTemplateInTree(this.tplIndex);
}
private void locateTemplate(JTemplate<?, ?> template) {
FILE currentTemplate = template.getEditingFILE();
//模板不属于当前环境,跟预览一样先提示保存,再定位模板
//如果是拖拽进来的模板单单用exist不能判断,这边参考预览的判断逻辑(browserTemplate),补充一下
if (!currentTemplate.exists() || !(currentTemplate instanceof FileNodeFILE)) {
int selVal = showConfirmDialog(
DesignerContext.getDesignerFrame(),
Toolkit.i18nText("Fine-Design_Basic_Web_Preview_Message"),
Toolkit.i18nText("Fine-Design_Basic_Preview_Tool_Tips"),
OK_CANCEL_OPTION,
WARNING_MESSAGE
);
if (OK_OPTION == selVal) {
CallbackSaveWorker worker = template.saveAs();
worker.start(template.getRuntimeId());
worker.addSuccessCallback(new Runnable() {
@Override
public void run() {
gotoEditingTemplateLeaf(template.getPath());
}
});
}
} else {
gotoEditingTemplateLeaf(template.getPath());
}
}
}
private class RightMenuCloseAction extends UpdateAction {
@ -316,230 +220,82 @@ public class MultiTemplateTabPane extends JComponent {
public RightMenuCloseAction(CloseOption option, int tplIndex) {
this.option = option;
this.setName(option.optionName);
this.setName(option.getOptionName());
this.tplIndex = tplIndex;
}
@Override
public void actionPerformed(ActionEvent e) {
SaveSomeTemplatePane saveSomeTempaltePane = new SaveSomeTemplatePane(false);
if (saveSomeTempaltePane.showSavePane()) {
JTemplate<?, ?>[] templates = new JTemplate<?, ?>[openedTemplate.size()];
for (int i = 0; i < openedTemplate.size(); i++) {
templates[i] = openedTemplate.get(i);
}
JTemplate<?, ?> currentTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
closeTemplate(templates, currentTemplate);
if (option == CloseOption.All) {
DesignerContext.getDesignerFrame().addAndActivateJTemplate();
} else {
DesignerContext.getDesignerFrame().activateJTemplate(currentTemplate);
}
MultiTemplateTabPane.getInstance().repaint();
}
}
private void closeTemplate(JTemplate<?, ?>[] templates, JTemplate<?, ?> currentTemplate) {
for (int i = 0; i < templates.length; i++) {
if (option.shouldClose(tplIndex, i)) {
JTemplate<?, ?> jTemplate = templates[i];
if (jTemplate == currentTemplate) {
currentTemplate = option == CloseOption.All ? null : templates[tplIndex];
}
//判断关闭的模板是不是格式刷的被参照的模板
openedTemplate.remove(jTemplate);
if (jTemplate != currentTemplate) {
MultiTemplateTabPane.getInstance().closeFormat(jTemplate);
HistoryTemplateListCache.getInstance().closeSelectedReport(jTemplate);
closeAndFreeLock(jTemplate);
}
}
}
TemplateTabManager.getInstance().getCurrentOperator().closeAction(option, this.tplIndex);
MultiTemplateTabPane.this.repaint();
}
private void closeAndFreeLock(@Nonnull JTemplate<?, ?> template) {
FILE file = template.getEditingFILE();
// 只有是环境内的文件,才执行释放锁
if (file != null && file.isEnvFile()) {
// release lock
WorkContext.getCurrent().get(TplOperator.class).closeAndFreeFile(file.getPath());
}
}
}
/**
* 留作兼容
* @return
*/
@Deprecated
public JTemplate getSelectedFile() {
if (openedTemplate.size() == selectedIndex) {
selectedIndex = Math.max(--selectedIndex, 0);
}
return openedTemplate.get(selectedIndex);
return TemplateTabManager.getInstance().getSelectedFile();
}
/**
* 关闭掉当前已打开文件列表中指定的文件
*
* @param file 指定的文件
*/
@Deprecated
public void closeFileTemplate(FILE file) {
for (JTemplate<?, ?> temp : openedTemplate) {
if (ComparatorUtils.equals(file, temp.getEditingFILE())) {
closeSpecifiedTemplate(temp);
break;
}
}
TemplateTabManager.getInstance().closeFileTemplate(file);
}
@Override
public Dimension getPreferredSize() {
Dimension dimension = super.getPreferredSize();
dimension.height = HEIGHT;
return dimension;
}
private UIMenuItem initCloseOther() {
UIMenuItem closeOther = new UIMenuItem(Toolkit.i18nText("Fine-Design_Basic_FS_Close_Other_Templates"));
// Yvan: 英文下文本显示不全,后续发现如果将模板名设置的比较短,其它语言也会出现显示不全的问题,所以设置一下文本水平居中
closeOther.setHorizontalAlignment(SwingConstants.CENTER);
setListDownItemPreferredSize(closeOther);
closeOther.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (openedTemplate.size() == 1) {
return;
}
if (!TemplateSavingChecker.check()) {
return;
}
SaveSomeTemplatePane saveSomeTempaltePane = new SaveSomeTemplatePane(false);
//点击关闭其他模板,并且点击确定保存
if (saveSomeTempaltePane.showSavePane()) {
JTemplate<?, ?>[] panes = new JTemplate<?, ?>[openedTemplate.size()];
for (int i = 0; i < openedTemplate.size(); i++) {
panes[i] = openedTemplate.get(i);
}
for (int i = 0; i < panes.length; i++) {
if (i != selectedIndex) {
JTemplate<?, ?> jTemplate = panes[i];
//判断关闭的模板是不是格式刷的被参照的模板
openedTemplate.remove(jTemplate);
closeFormat(jTemplate);
HistoryTemplateListCache.getInstance().closeSelectedReport(jTemplate);
closeAndFreeLock(jTemplate);
}
}
JTemplate<?, ?> currentTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
HistoryTemplateListCache.getInstance().removeAllHistory();
DesignerContext.getDesignerFrame().activateJTemplate(currentTemplate);
THIS.repaint();
}
//如果取消保存了,则不关闭其他模板
}
});
if (openedTemplate.size() == 1) {
closeOther.setEnabled(false);
}
return closeOther;
}
private UIMenuItem[] createListDownTemplate() {
UIMenuItem[] templates = new UIMenuItem[openedTemplate.size()];
for (int i = 0; i < openedTemplate.size(); i++) {
final int index = i;
final JTemplate tem = openedTemplate.get(i);
templates[i] = new UIMenuItem(tempalteShowName(tem), tem.getIcon());
templates[i].setUI(new UIListDownItemUI());
setListDownItemPreferredSize(templates[i]);
if (i == selectedIndex) {
//画选中的高亮
templates[i].setBackground(UIConstants.SHADOW_CENTER);
}
templates[i].addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
selectedIndex = index;
tem.activeNewJTemplate();
}
});
}
return templates;
}
private void setListDownItemPreferredSize(UIMenuItem item) {
Dimension dimension = item.getPreferredSize();
dimension.height = LIST_DOWN_HEIGHT;
item.setPreferredSize(dimension);
}
private String tempalteShowName(JTemplate<?, ?> template) {
String name = TemplateUtils.createLockeTemplatedName(template, template.getTemplateName());
if (!template.isSaved() && !name.endsWith(" *")) {
name += " *";
}
return name;
}
/**
* 刷新打开模板
*
* @param history 模板
*/
@Deprecated
public void refreshOpenedTemplate(List<JTemplate<?, ?>> history) {
openedTemplate = history;
TemplateTabManager.getInstance().refreshOpenedTemplate(history);
}
/**
* 设置临时Template
* @param auotCreate
*/
@Deprecated
public void setTemTemplate(JTemplate<?, ?> auotCreate) {
temTemplate = auotCreate;
TemplateTabManager.getInstance().setTemTemplate(auotCreate);
}
/**
* 设置选中模板索引
* @param index
*/
@Deprecated
public void setSelectedIndex(int index) {
TemplateTabManager.getInstance().getCurrentOperator().setSelectIndex(index);
}
private void showListDown() {
@Override
public Dimension getPreferredSize() {
Dimension dimension = super.getPreferredSize();
dimension.height = HEIGHT;
return dimension;
}
UIScrollPopUpMenu menu = new UIScrollPopUpMenu();
menu.setBorder(BorderFactory.createEmptyBorder(-3, 3, 3, 0));
menu.add(initCloseOther());
JSeparator separator = new JSeparator() {
@Override
public Dimension getPreferredSize() {
Dimension d = super.getPreferredSize();
d.height = 1;
return d;
}
};
menu.add(new JPanel() {
@Override
public Dimension getPreferredSize() {
Dimension d = super.getPreferredSize();
d.height = 1;
return d;
}
});
separator.setForeground(UIConstants.LINE_COLOR);
menu.add(separator);
menu.add(new JPanel() {
@Override
public Dimension getPreferredSize() {
Dimension d = super.getPreferredSize();
d.height = 1;
return d;
}
});
UIMenuItem[] items = createListDownTemplate();
for (int i = 0; i < items.length; i++) {
menu.add(items[i]);
}
GUICoreUtils.showPopupMenu(menu, MultiTemplateTabPane.getInstance(), MultiTemplateTabPane.getInstance().getWidth() - menu.getPreferredSize().width, getY() - 1 + getHeight());
private String tempalteShowName(JTemplate<?, ?> template) {
return TemplateTabManager.getInstance().getTemplateShowName(template);
}
public void setSelectedIndex(int index) {
selectedIndex = index;
private void showListDown() {
UIScrollPopUpMenu menu = MultiTemplateTabMenuFactory.getInstance().createMenu();
GUICoreUtils.showPopupMenu(menu, MultiTemplateTabPane.this, MultiTemplateTabPane.this.getWidth() - menu.getPreferredSize().width, getY() - 1 + getHeight());
}
@ -566,15 +322,18 @@ public class MultiTemplateTabPane extends JComponent {
paintDefaultBackground(g2d);
//最多能画的个数
int maxTemplateNum = (int) (maxWidth) / MINWIDTH;
int templateTabCount = TemplateTabManager.getInstance().getCurrentOperator().getOpenedJTemplates().size();
int currentSelectedIndex = TemplateTabManager.getInstance().getCurrentOperator().getSelectIndex();
//计算开始画的最小模板index和最大模板index
calMinAndMaxIndex(maxTemplateNum);
calculateRealAverageWidth(maxWidth, maxTemplateNum);
int maxStringlength = calculateStringMaxLength();
if (selectedIndex >= openedTemplate.size()) {
selectedIndex = openedTemplate.size() - 1;
if ( currentSelectedIndex >= templateTabCount) {
TemplateTabManager.getInstance().getCurrentOperator().setSelectIndex(
templateTabCount - 1);
}
if (selectedIndex < 0) {
selectedIndex = 0;
if (TemplateTabManager.getInstance().getCurrentOperator().getSelectIndex() < 0) {
TemplateTabManager.getInstance().getCurrentOperator().setSelectIndex(0);
}
double templateStartX = 0;
startX = new int[maxPaintIndex - minPaintIndex + 1];
@ -582,7 +341,7 @@ public class MultiTemplateTabPane extends JComponent {
//从可以开始展示在tab面板上的tab开始画
for (int i = minPaintIndex; i <= maxPaintIndex; i++) {
JTemplate template = openedTemplate.get(i);
JTemplate template = TemplateTabManager.getInstance().getCurrentOperator().getOpenedJTemplates().get(i);
Icon icon = template.getIcon();
String name = tempalteShowName(template);
//如果tab名字的长度大于最大能显示的英文字符长度,则进行省略号处理
@ -599,7 +358,7 @@ public class MultiTemplateTabPane extends JComponent {
} else {
selectedIcon = CLOSE;
}
if (i == selectedIndex) {
if (i == TemplateTabManager.getInstance().getCurrentOperator().getSelectIndex()) {
if (template.isSaving()) {
selectedIcon = WHITE_SAVING_CLOSE_ICON;
}
@ -608,8 +367,8 @@ public class MultiTemplateTabPane extends JComponent {
if (template.isSaving()) {
selectedIcon = GREY_SAVING_CLOSE_ICON;
}
boolean isLeft = i < selectedIndex;
startX[i - minPaintIndex] = paintUnSelectedTab(g2d, icon, templateStartX, name, selectedIcon, isLeft, mouseOveredIndex, i);
boolean left = i < TemplateTabManager.getInstance().getCurrentOperator().getSelectIndex();
startX[i - minPaintIndex] = paintUnSelectedTab(g2d, icon, templateStartX, name, selectedIcon, left, mouseOveredIndex, i);
}
templateStartX += realWidth;
}
@ -684,38 +443,39 @@ public class MultiTemplateTabPane extends JComponent {
}
private void calMinAndMaxIndex(int maxTemplateNum) {
int templateTabCount = TemplateTabManager.getInstance().getCurrentOperator().getOpenedJTemplates().size();
//如果个数大于最多能容纳的个数,则多余的进行处理
if (openedTemplate.size() > maxTemplateNum) {
if (templateTabCount > maxTemplateNum) {
//所点击列表中的标签页处在标签页栏最后一个标签页之后,则标签页栏左移至所点击标签页出现
if (selectedIndex >= maxPaintIndex) {
minPaintIndex = selectedIndex - maxTemplateNum + 1;
maxPaintIndex = selectedIndex;
if (TemplateTabManager.getInstance().getCurrentOperator().getSelectIndex() >= maxPaintIndex) {
minPaintIndex = TemplateTabManager.getInstance().getCurrentOperator().getSelectIndex() - maxTemplateNum + 1;
maxPaintIndex = TemplateTabManager.getInstance().getCurrentOperator().getSelectIndex();
if (minPaintIndex <= 0) {
minPaintIndex = 0;
maxPaintIndex = maxTemplateNum - 1;
}
} else if (selectedIndex <= minPaintIndex) {
} else if (TemplateTabManager.getInstance().getCurrentOperator().getSelectIndex() <= minPaintIndex) {
//所点击列表中的标签页处在标签页栏第一个标签页之前,则标签页栏右移至所点击标签页出现
minPaintIndex = selectedIndex;
minPaintIndex = TemplateTabManager.getInstance().getCurrentOperator().getSelectIndex();
maxPaintIndex = minPaintIndex + maxTemplateNum - 1;
if (maxPaintIndex > openedTemplate.size() - 1) {
maxPaintIndex = openedTemplate.size() - 1;
if (maxPaintIndex > templateTabCount- 1) {
maxPaintIndex = templateTabCount - 1;
}
} else {
if (selectedIndex >= openedTemplate.size() - 1) {
selectedIndex = openedTemplate.size() - 1;
maxPaintIndex = selectedIndex;
minPaintIndex = selectedIndex - maxTemplateNum + 1;
if (TemplateTabManager.getInstance().getCurrentOperator().getSelectIndex() >= templateTabCount - 1) {
TemplateTabManager.getInstance().getCurrentOperator().setSelectIndex(templateTabCount - 1);
maxPaintIndex = TemplateTabManager.getInstance().getCurrentOperator().getSelectIndex();
minPaintIndex = TemplateTabManager.getInstance().getCurrentOperator().getSelectIndex() - maxTemplateNum + 1;
} else {
maxPaintIndex = minPaintIndex + maxTemplateNum - 1;
if (maxPaintIndex > openedTemplate.size() - 1) {
maxPaintIndex = openedTemplate.size() - 1;
if (maxPaintIndex > templateTabCount - 1) {
maxPaintIndex = templateTabCount - 1;
}
}
}
} else {
minPaintIndex = 0;
maxPaintIndex = openedTemplate.size() - 1;
maxPaintIndex = templateTabCount - 1;
}
}
@ -723,7 +483,7 @@ public class MultiTemplateTabPane extends JComponent {
//个数小于最多能容纳的个数的情况下,看看宽度每个要画多少
private void calculateRealAverageWidth(double maxwidth, int templateNum) {
int num = openedTemplate.size() > templateNum ? templateNum : openedTemplate.size();
int num = TemplateTabManager.getInstance().getCurrentOperator().getOpenedJTemplates().size() > templateNum ? templateNum : TemplateTabManager.getInstance().getCurrentOperator().getOpenedJTemplates().size();
realWidth = (int) (maxwidth / (num));
if (realWidth > MAXWIDTH) {
realWidth = MAXWIDTH;
@ -887,10 +647,13 @@ public class MultiTemplateTabPane extends JComponent {
generalPath.closePath();
}
/**
* 设置是否关闭当前打开的模板
* @param isCloseCurrent
*/
@Deprecated
public void setIsCloseCurrent(boolean isCloseCurrent) {
this.isCloseCurrent = isCloseCurrent;
TemplateTabManager.getInstance().setCloseCurrent(isCloseCurrent);
}
/**
@ -898,57 +661,35 @@ public class MultiTemplateTabPane extends JComponent {
*
* @param specifiedTemplate 模板
*/
@Deprecated
public void closeSpecifiedTemplate(JTemplate<?, ?> specifiedTemplate) {
if (specifiedTemplate == null) {
return;
}
TemplateTabManager.getInstance().closeSpecifiedTemplate(specifiedTemplate);
}
if (!specifiedTemplate.isALLSaved() && !DesignerMode.isVcsMode()) {
specifiedTemplate.stopEditing();
int returnVal = FineJOptionPane.showConfirmDialog(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Design_Basic_Utils_Would_You_Like_To_Save") + " \"" + specifiedTemplate.getEditingFILE() + "\" ?",
Toolkit.i18nText("Fine-Design_Basic_Confirm"), JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
if (returnVal == JOptionPane.YES_OPTION) {
CallbackSaveWorker worker = specifiedTemplate.save();
worker.addSuccessCallback(new Runnable() {
@Override
public void run() {
FineLoggerFactory.getLogger().info(Toolkit.i18nText("Fine-Design_Basic_Template_Already_Saved", specifiedTemplate.getEditingFILE().getName()));
closeTpl(specifiedTemplate);
}
});
worker.start(specifiedTemplate.getRuntimeId());
} else if (returnVal == JOptionPane.NO_OPTION) {
closeTpl(specifiedTemplate);
private boolean isOverCloseIcon(int evtX) {
boolean overCloseIcon = false;
for (int i = 0; i < startX.length; i++) {
if (evtX >= startX[i] && evtX <= startX[i] + CLOSE.getIconWidth()) {
overCloseIcon = true;
break;
}
} else {
closeTpl(specifiedTemplate);
}
return overCloseIcon;
}
private void closeTpl(@Nonnull JTemplate<?, ?> specifiedTemplate) {
HistoryTemplateListCache.getInstance().closeSelectedReport(specifiedTemplate);
closeAndFreeLock(specifiedTemplate);
activePrevTemplateAfterClose();
}
private void closeAndFreeLock(@Nonnull JTemplate<?, ?> template) {
FILE file = template.getEditingFILE();
// 只有是环境内的文件,才执行释放锁
if (file != null && file.isEnvFile()) {
// release lock
TemplateResourceManager.getResource().closeTemplate(file.getPath());
}
private boolean isOverListDown(int evtX) {
int maxWidth = getWidth() - LIST_BUTTON_WIDTH;
return evtX >= (maxWidth + SMALLGAP) && evtX <= (getWidth() - SMALLGAP);
}
/**
* 后台关闭当前编辑模板
*/
@Deprecated
public void closeCurrentTpl() {
JTemplate jTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
this.setIsCloseCurrent(true);
this.closeFormat(jTemplate);
this.closeSpecifiedTemplate(jTemplate);
TemplateTabManager.getInstance().closeCurrentTpl();
}
/**
@ -956,71 +697,25 @@ public class MultiTemplateTabPane extends JComponent {
*
* @param closedTemplate 模板
*/
@Deprecated
public void closeFormat(JTemplate closedTemplate) {
//表单不需要处理
if (!closedTemplate.isJWorkBook()) {
return;
}
if (DesignerContext.getFormatState() == DesignerContext.FORMAT_STATE_NULL) {
return;
}
//是被参照的模板被关闭,则重置格式刷
closedTemplate.doConditionCancelFormat();
TemplateTabManager.getInstance().closeFormat(closedTemplate);
}
/**
* 关闭掉一个模板之后激活新的待显示模板
*/
@Deprecated
public void activePrevTemplateAfterClose() {
if (openedTemplate.isEmpty()) {
//新建并激活模板
DesignerContext.getDesignerFrame().addAndActivateJTemplate();
selectedIndex = 0;
//此时刚自动新建的模板在HistoryTemplateListCache的editingTemplate
temTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
} else {
// 如果关闭的模板是当前选中的模板,则重新激活当前 selectIndex 的模板;
// selectIndex 没有变化,但是对应的模板已经变成了前一张模板
if (closeIconIndex == selectedIndex || isCloseCurrent) {
// 如果当前关闭的模板在最右侧,那么预览上一个,防止数组越界
if (selectedIndex >= maxPaintIndex) {
// selectIndex 不会 <0 因为如果关闭的是打开的最后一个模板,那么关闭之后 openedTemplate.isEmpty() = true
selectedIndex--;
}
isCloseCurrent = false;
}
// 如果关闭的模板不是当前选中的模板,那么重新获取一下当前模板的 index,激活该 index
else {
JTemplate template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
selectedIndex = HistoryTemplateListCache.getInstance().contains(template);
}
if (selectedIndex < openedTemplate.size()) {
//如果是已后台关闭的模板,则重新打开文件
openedTemplate.get(selectedIndex).activeOldJTemplate();
}
}
}
private boolean isOverCloseIcon(int evtX) {
boolean isOverCloseIcon = false;
for (int i = 0; i < startX.length; i++) {
if (evtX >= startX[i] && evtX <= startX[i] + CLOSE.getIconWidth()) {
isOverCloseIcon = true;
break;
}
}
return isOverCloseIcon;
TemplateTabManager.getInstance().activePrevTemplateAfterClose();
}
private boolean isOverListDown(int evtX) {
int maxWidth = getWidth() - LIST_BUTTON_WIDTH;
return evtX >= (maxWidth + SMALLGAP) && evtX <= (getWidth() - SMALLGAP);
/**
* 处理自动新建的模板 在切换时的处理
*/
@Deprecated
public void doWithtemTemplate() {
TemplateTabManager.getInstance().doWithtemTemplate();
}
@ -1036,29 +731,6 @@ public class MultiTemplateTabPane extends JComponent {
return -1;
}
/**
* 处理自动新建的模板 在切换时的处理
*/
public void doWithtemTemplate() {
//temtemplate保存的一定是手动新建的没有编辑或是编辑了没有保存的模板
//没有保存,说明有编辑;已经保存在磁盘里的文件,说明有过处理,并且已经保存,此时切换都不将其自动关闭
if (temTemplate == null || temTemplate == HistoryTemplateListCache.getInstance().getCurrentEditingTemplate()) {
return;
}
if (!temTemplate.isSaved() || !temTemplate.getEditingFILE().isMemFile()) {
temTemplate = null;
}
//自动新建的模板B若没有进行任何编辑(新建模板没有进行任何编辑时saved都是true):还没有存盘
if (temTemplate != null && temTemplate.getEditingFILE().isMemFile() && temTemplate.isSaved()) {
HistoryTemplateListCache.getInstance().closeSelectedReport(temTemplate);
temTemplate = null;
setSelectedIndex(HistoryTemplateListCache.getInstance().contains(HistoryTemplateListCache.getInstance().getCurrentEditingTemplate()));
}
}
private class UIListDownItemUI extends BasicMenuItemUI {
@Override
protected void paintBackground(Graphics g, JMenuItem menuItem, Color bgColor) {
@ -1161,44 +833,13 @@ public class MultiTemplateTabPane extends JComponent {
closeIconIndex = getTemplateIndex(evtX);
clodeMode = MOUSE_PRESS_CLOSE;
//关闭close图标所在的模板{
JTemplate<?, ?> template = openedTemplate.get(closeIconIndex);
if (template.isOpening()) {
WorkerManager.getInstance().cancelWorker(template.getPath());
} else if (template.isSaving()) {
boolean completed = WorkerManager.getInstance().isCompleted(template.getTarget().getTemplateID());
if (!completed) {
FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(),
Toolkit.i18nText("Fine-Design_Close_Template_Tip", template.getEditingFILE().getName()));
return;
}
}
//参考CloseCurrentTemplateAction,在closeFormat与closeSpecifiedTemplate之前要先设定isCloseCurrent,这样关闭之后才会自动切换tab
if (checkCurrentClose(template)) {
setIsCloseCurrent(true);
}
closeFormat(template);
closeSpecifiedTemplate(template);
DesignerContext.getDesignerFrame().getContentFrame().repaint();
TemplateTabManager.getInstance().getCurrentOperator().closeByIndex(closeIconIndex);
isShowList = false;
} else {
//没有点击关闭和ListDown按钮,则切换到点击的模板处
closeIconIndex = -1;
clodeMode = CLOSE;
int tempSelectedIndex = selectedIndex;
if (selectedIndex != getTemplateIndex(evtX) && getTemplateIndex(evtX) != -1) {
openedTemplate.get(selectedIndex).stopEditing();
selectedIndex = getTemplateIndex(evtX);
//如果在权限编辑情况下,不允许切换到表单类型的工作簿
if (DesignerMode.isAuthorityEditing() && !openedTemplate.get(selectedIndex).isJWorkBook()) {
DesignerContext.getDesignerFrame().addAndActivateJTemplate(openedTemplate.get(tempSelectedIndex));
FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Design_Basic_Form_Authority_Edited_Cannot_Be_Supported")
+ "!", Toolkit.i18nText("Fine-Design_Basic_Alert"), JOptionPane.WARNING_MESSAGE);
MultiTemplateTabPane.this.repaint();
return;
}
JTemplate evtXTemplate = openedTemplate.get(getTemplateIndex(evtX));
evtXTemplate.activeNewJTemplate();
}
TemplateTabManager.getInstance().getCurrentOperator().switchTpl(getTemplateIndex(evtX));
isShowList = false;
}
MultiTemplateTabPane.this.repaint();
@ -1209,11 +850,6 @@ public class MultiTemplateTabPane extends JComponent {
}
private boolean checkCurrentClose(JTemplate template) {
JTemplate currentTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
return JTemplate.isValid(currentTemplate) && ComparatorUtils.equals(template.getPath(), currentTemplate.getPath());
}
private class MultiTemplateTabMouseMotionListener implements MouseMotionListener {
/**
* 鼠标拖拽
@ -1237,7 +873,7 @@ public class MultiTemplateTabPane extends JComponent {
//看是否需要显示toolTip
if (mouseOveredIndex != -1 && isNeedToolTips[mouseOveredIndex - minPaintIndex]) {
setToolTipText(openedTemplate.get(mouseOveredIndex).getEditingFILE().getName());
setToolTipText(TemplateTabManager.getInstance().getCurrentOperator().getOpenedJTemplates().get(mouseOveredIndex).getEditingFILE().getName());
} else {
setToolTipText(null);
}

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

@ -1,5 +1,7 @@
package com.fr.design.file;
import com.fr.design.file.impl.DefaultTemplateTabOperate;
/**
* @author shine
* @version 10.0
@ -14,11 +16,11 @@ public class MutilTempalteTabPane {
}
public void setIsCloseCurrent(boolean b) {
MultiTemplateTabPane.getInstance().setIsCloseCurrent(b);
TemplateTabManager.getInstance().setCloseCurrent(b);
}
public void activePrevTemplateAfterClose() {
MultiTemplateTabPane.getInstance().activePrevTemplateAfterClose();
DefaultTemplateTabOperate.getInstance().activePrevTemplateAfterClose(true);
}
}

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

@ -81,11 +81,15 @@ public abstract class NewTemplatePane extends JComponent implements MouseListene
}
if (isOverNewIcon(evtX) && newWorkBookIconMode != GRAY_NEW_CPT) {
newWorkBookIconMode = getMousePressNew();
DesignerContext.getDesignerFrame().addAndActivateJTemplate();
createNewTemplate();
}
this.repaint();
}
protected void createNewTemplate() {
DesignerContext.getDesignerFrame().addAndActivateJTemplate();
}
/**
*鼠标松开
* @param e 事件

39
designer-base/src/main/java/com/fr/design/file/SaveSomeTemplatePane.java

@ -3,8 +3,8 @@ package com.fr.design.file;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.BasicPane;
import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.event.StateChangeListener;
import com.fr.design.file.impl.DefaultTemplateTabOperate;
import com.fr.design.gui.icheckbox.UICheckBox;
import com.fr.design.gui.icontainer.UIScrollPane;
import com.fr.design.gui.ilable.UILabel;
@ -19,10 +19,10 @@ import com.fr.general.ComparatorUtils;
import com.fr.log.FineLoggerFactory;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;
/**
* Author : daisy
@ -151,8 +151,32 @@ public class SaveSomeTemplatePane extends BasicPane {
}
/**
* 显示未保存弹窗
* @return
*/
public boolean showSavePane() {
populate();
return showSavePane(false);
}
/**
* 显示未保存弹窗
* @param switchEnv
* @return
*/
public boolean showSavePane(boolean switchEnv) {
return switchEnv ?
showSavePane(DefaultTemplateTabOperate.getInstance().getOpenedJTemplates()) :
showSavePane(HistoryTemplateListPane.getInstance().getHistoryList());
}
/**
* 显示未保存弹窗
* @param jTemplates
* @return
*/
public boolean showSavePane(List<JTemplate<?, ?>> jTemplates) {
populate(jTemplates);
//如果有未保存的文件 ,则跳出保存对话框,选择要存储的项目
if (!unSavedTemplate.isEmpty()) {
dialog.setVisible(true);
@ -162,8 +186,15 @@ public class SaveSomeTemplatePane extends BasicPane {
return isAllSaved;
}
/**
* 兼容方法
*/
@Deprecated
public void populate() {
java.util.List<JTemplate<?, ?>> opendedTemplate = HistoryTemplateListPane.getInstance().getHistoryList();
populate(HistoryTemplateListPane.getInstance().getHistoryList());
}
private void populate(java.util.List<JTemplate<?, ?>> opendedTemplate) {
JTemplate<?, ?> currentTemplate = HistoryTemplateListPane.getInstance().getCurrentEditingTemplate();
for (int i = 0; i < opendedTemplate.size(); i++) {
if (isneedToAdd(opendedTemplate.get(i), currentTemplate)) {

291
designer-base/src/main/java/com/fr/design/file/TemplateTabManager.java

@ -0,0 +1,291 @@
package com.fr.design.file;
import com.finebi.cbb.utils.CompareUtils;
import com.fr.design.file.impl.DefaultTemplateTabOperate;
import com.fr.design.file.impl.EmptyTemplateTabOperate;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.JTemplate;
import com.fr.file.FILE;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 模板tab的操作统一管理类
* @author kerry
* @since 11.0
* created on 2023-04-14
**/
public class TemplateTabManager {
private static class Holder {
private static final TemplateTabManager SINGLETON = new TemplateTabManager();
}
/**
* 返回TemplateTabManager单例对象
* @return
*/
public static TemplateTabManager getInstance() {
return Holder.SINGLETON;
}
private TemplateTabManager() {
list.add(DefaultTemplateTabOperate.getInstance());
}
private List<TemplateTabOperateProvider> list = new ArrayList<>();
/**
* 支持注册新的Operator
* @param templateTabOperateProvider
*/
public void register(TemplateTabOperateProvider templateTabOperateProvider) {
this.list.add(templateTabOperateProvider);
}
/**
* 移除operator
* @param templateTabOperateProvider
*/
public void remove(TemplateTabOperateProvider templateTabOperateProvider) {
this.list.remove(templateTabOperateProvider);
}
private boolean closeCurrent = false;
//自动新建的模板B若没有进行任何编辑,切换到其他
// 模板时,模板B会自动关闭
private JTemplate<?, ?> temTemplate = null;
public boolean isCloseCurrent() {
return closeCurrent;
}
public void setCloseCurrent(boolean closeCurrent) {
this.closeCurrent = closeCurrent;
}
public void setTemTemplate(JTemplate<?, ?> temTemplate) {
this.temTemplate = temTemplate;
}
/**
* 刷新tab栏
*/
public void refresh() {
getCurrentOperator().refresh();
}
/**
* 从模板树删除文件
*/
public void deleteOpenedTemplate(JTemplate<?, ?> template) {
TemplateTabOperateProvider provider = getOperatorByTemplate(template);
provider.deleteOpenedTemplate(template);
this.refresh();
}
public JTemplate getSelectedFile() {
return getCurrentOperator().getSelectedFile();
}
/**
* 关闭掉当前文件列表中指定的文件
*
* @param file 指定的文件
*/
public void closeFileTemplate(FILE file) {
for (TemplateTabOperateProvider provider : list) {
provider.closeFileTemplate(file);
}
}
/**
* 关闭指定模板
*
* @param specifiedTemplate
*/
public void closeSpecifiedTemplate(JTemplate<?, ?> specifiedTemplate) {
getCurrentOperator().closeSpecifiedTemplate(specifiedTemplate);
}
/**
* 刷新打开模板
*
* @param tempalteLsit
*/
public void refreshOpenedTemplate(List<JTemplate<?, ?>> tempalteLsit) {
for (TemplateTabOperateProvider provider : list) {
provider.refreshOpenedTemplate(tempalteLsit);
}
}
/**
* 处理自动新建的模板 在切换时的处理
*/
public void doWithtemTemplate() {
//temtemplate保存的一定是手动新建的没有编辑或是编辑了没有保存的模板
//没有保存,说明有编辑;已经保存在磁盘里的文件,说明有过处理,并且已经保存,此时切换都不将其自动关闭
if (temTemplate == null || temTemplate == HistoryTemplateListCache.getInstance().getCurrentEditingTemplate()) {
return;
}
if (!temTemplate.isSaved() || !temTemplate.getEditingFILE().isMemFile()) {
temTemplate = null;
}
//自动新建的模板B若没有进行任何编辑(新建模板没有进行任何编辑时saved都是true):还没有存盘
if (temTemplate != null && temTemplate.getEditingFILE().isMemFile() && temTemplate.isSaved()) {
HistoryTemplateListCache.getInstance().closeSelectedReport(temTemplate);
temTemplate = null;
resetSelectIndex(HistoryTemplateListCache.getInstance().getCurrentEditingTemplate());
}
}
/**
* 重置选中index
* @param jTemplate
*/
public void resetSelectIndex(JTemplate jTemplate) {
getCurrentOperator().resetSelectIndex(jTemplate);
}
/**
* 激活新模板
*/
public void activeNewTemplate() {
//先看其他模式中是否有已打开的模板,有的话切换过去
for (TemplateTabOperateProvider templateTabOperateProvider : list) {
if (templateTabOperateProvider.getOpenedJTemplates().size() != 0) {
templateTabOperateProvider.getSelectedFile().activeNewJTemplate();
refresh();
return;
}
}
//都没有的话,新建并激活模板
DesignerContext.getDesignerFrame().addAndActivateJTemplate();
//此时刚自动新建的模板在HistoryTemplateListCache的editingTemplate
TemplateTabManager.getInstance().setTemTemplate(HistoryTemplateListCache.getInstance().getCurrentEditingTemplate());
refresh();
}
/**
* 后台关闭当前编辑模板
*/
public void closeCurrentTpl() {
JTemplate jTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
this.setCloseCurrent(true);
this.closeFormat(jTemplate);
this.closeSpecifiedTemplate(jTemplate);
}
/**
* 关闭指定索引值模板
*
* @param index
*/
public void closeByIndex(int index) {
getCurrentOperator().closeByIndex(index);
}
/**
* 关闭指定索引值模板
*
* @param jTemplate
*/
public void closeByJTemplate(JTemplate jTemplate) {
TemplateTabOperateProvider operator = getOperatorByOperatorType(jTemplate.getTemplateTabOperatorType());
operator.closeByIndex(operator.getJTemplateIndex(jTemplate));
}
/**
* 切换到指定tab栏的指定索引值模板
*
* @param jTemplate
*/
public void switchByJTemplate(JTemplate jTemplate) {
TemplateTabOperateProvider operator = getOperatorByOperatorType(jTemplate.getTemplateTabOperatorType());
operator.switchTpl(operator.getJTemplateIndex(jTemplate));
}
/**
* 获取所有打开的模板map
*
* @return
*/
public Map<String, List<JTemplate<?, ?>>> getAllOpenedTemplateMap() {
Map<String, List<JTemplate<?, ?>>> resultMap = new HashMap<>();
for (TemplateTabOperateProvider provider : list) {
resultMap.put(provider.getOperatorType(), provider.getOpenedJTemplates());
}
return resultMap;
}
/**
* 留作兼容
*/
public void activePrevTemplateAfterClose(){
getCurrentOperator().activePrevTemplateAfterClose();
}
/**
* 关闭其他
*/
public void closeOthers() {
TemplateTabOperateProvider currentOperator = getCurrentOperator();
currentOperator.closeAction(CloseOption.Others,
currentOperator.getJTemplateIndex(HistoryTemplateListCache.getInstance().getCurrentEditingTemplate()));
}
public String getTemplateShowName(JTemplate temTemplate){
return getCurrentOperator().getTemplateShowName(temTemplate);
}
/**
* 关闭模板
*
* @param closedTemplate 模板
*/
public void closeFormat(JTemplate closedTemplate) {
//表单不需要处理
if (!closedTemplate.isJWorkBook()) {
return;
}
if (DesignerContext.getFormatState() == DesignerContext.FORMAT_STATE_NULL) {
return;
}
//是被参照的模板被关闭,则重置格式刷
closedTemplate.doConditionCancelFormat();
}
public TemplateTabOperateProvider getCurrentOperator() {
return getOperatorByTemplate(HistoryTemplateListCache.getInstance().getCurrentEditingTemplate());
}
private TemplateTabOperateProvider getOperatorByTemplate(JTemplate jTemplate) {
return getOperatorByOperatorType(jTemplate.getTemplateTabOperatorType());
}
private TemplateTabOperateProvider getOperatorByOperatorType(String type) {
for (TemplateTabOperateProvider provider : list) {
if (CompareUtils.isEqual(provider.getOperatorType(), type)) {
return provider;
}
}
return EmptyTemplateTabOperate.getInstance();
}
}

129
designer-base/src/main/java/com/fr/design/file/TemplateTabOperateProvider.java

@ -0,0 +1,129 @@
package com.fr.design.file;
import com.fr.design.mainframe.JTemplate;
import com.fr.file.FILE;
import java.util.List;
/**
* 模板tab的操作接口
* @author kerry
* @since 11.0
* created on 2023-04-14
**/
public interface TemplateTabOperateProvider {
/**
* 找到模板树中的位置
*/
void locateTemplateInTree(int tplIndex);
/**
* 右键一系列关闭操作
*
* @param option closeType
* @param index
*/
void closeAction(CloseOption option, int index);
/**
* 切换模板
*
* @param templateIndex 模板索引值
*/
void switchTpl(int templateIndex);
/**
* 获取打开模板的基本信息
*
* @return
*/
List<JTemplate<?, ?>> getOpenedJTemplates();
/**
* 根据指定索引关闭模板
* @param index
*/
void closeByIndex(int index);
/**
* 关闭指定模板
*
* @param specifiedTemplate
*/
void closeSpecifiedTemplate(JTemplate<?, ?> specifiedTemplate);
/**
* 删除已打开的模板
*/
void deleteOpenedTemplate(JTemplate<?, ?> template);
/**
* 获取选中模板
* @return
*/
JTemplate getSelectedFile();
/**
* 刷新ui
*/
void refresh();
/**
* 重置下选中的Index
* @param jTemplate
*/
void resetSelectIndex(JTemplate jTemplate);
/**
* 刷新下打开的模板list
* @param list
*/
void refreshOpenedTemplate(List<JTemplate<?, ?>> list);
/**
* 关闭指定节点
* @param file
*/
void closeFileTemplate(FILE file);
/**
* 获取操作类型标识
* @return
*/
String getOperatorType();
/**
* 获取当前选中模板的index
* @return
*/
int getSelectIndex();
/**
* 设置当前选中模板的index
* @return
*/
void setSelectIndex(int index);
/**
* 获取指定模板在operator中的索引值
* @param jTemplate
* @return
*/
int getJTemplateIndex(JTemplate jTemplate);
/**
* 获取template在tab中显示的名称
* @param jTemplate
* @return
*/
String getTemplateShowName(JTemplate jTemplate);
/**
* 留作兼容在关闭模板后激活前一个模板
*/
void activePrevTemplateAfterClose();
}

364
designer-base/src/main/java/com/fr/design/file/impl/AbstractTemplateTabOperate.java

@ -0,0 +1,364 @@
package com.fr.design.file.impl;
import com.finebi.cbb.utils.CompareUtils;
import com.fr.base.vcs.DesignerMode;
import com.fr.design.actions.file.LocateAction;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.file.CloseOption;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.file.SaveSomeTemplatePane;
import com.fr.design.file.TemplateTabManager;
import com.fr.design.file.TemplateTabOperateProvider;
import com.fr.design.file.TemplateTreePane;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.mainframe.manager.search.TemplateTreeSearchManager;
import com.fr.design.utils.TemplateUtils;
import com.fr.design.worker.WorkerManager;
import com.fr.design.worker.save.CallbackSaveWorker;
import com.fr.file.FILE;
import com.fr.file.FileNodeFILE;
import com.fr.general.ComparatorUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.third.javax.annotation.Nonnull;
import com.fr.workspace.WorkContext;
import com.fr.workspace.server.lock.TplOperator;
import javax.swing.JOptionPane;
import java.util.ArrayList;
import java.util.List;
import static com.fr.design.dialog.FineJOptionPane.showConfirmDialog;
import static javax.swing.JOptionPane.OK_CANCEL_OPTION;
import static javax.swing.JOptionPane.OK_OPTION;
import static javax.swing.JOptionPane.WARNING_MESSAGE;
/**
* 模板tab的操作抽象类
* @author kerry
* @since 11.0
* created on 2023-04-14
**/
public abstract class AbstractTemplateTabOperate implements TemplateTabOperateProvider {
private static final String UNSAVED_SUFFIX = " *";
//用于存放工作簿
private java.util.List<JTemplate<?, ?>> openedTemplate = new ArrayList<>();
//选中的Tab项
private int selectedIndex = -1;
public AbstractTemplateTabOperate() {
}
@Override
public void locateTemplateInTree(int tplIndex) {
//处于搜索模式时,先退出搜索模式,再定位
if (TemplateTreeSearchManager.getInstance().isInSearchMode()) {
TemplateTreeSearchManager.getInstance().outOfSearchMode();
TemplateTreePane.getInstance().refreshDockingView();
}
JTemplate<?, ?> template = openedTemplate.get(tplIndex);
locateTemplate(template);
}
private void locateTemplate(JTemplate<?, ?> template) {
FILE currentTemplate = template.getEditingFILE();
//模板不属于当前环境,跟预览一样先提示保存,再定位模板
//如果是拖拽进来的模板单单用exist不能判断,这边参考预览的判断逻辑(browserTemplate),补充一下
boolean needSave = (!currentTemplate.exists() || !(currentTemplate instanceof FileNodeFILE)) && template.canBeSaved();
if (needSave) {
int selVal = showConfirmDialog(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Design_Basic_Web_Preview_Message"), Toolkit.i18nText("Fine-Design_Basic_Preview_Tool_Tips"), OK_CANCEL_OPTION, WARNING_MESSAGE);
if (OK_OPTION == selVal) {
CallbackSaveWorker worker = template.saveAs();
worker.start(template.getRuntimeId());
worker.addSuccessCallback(new Runnable() {
@Override
public void run() {
LocateAction.gotoEditingTemplateLeaf(template.getPath());
}
});
}
} else {
LocateAction.gotoEditingTemplateLeaf(template.getPath());
}
}
@Override
public void closeAction(CloseOption option, int index) {
SaveSomeTemplatePane saveSomeTempaltePane = new SaveSomeTemplatePane(true);
if (saveSomeTempaltePane.showSavePane(this.openedTemplate)) {
JTemplate<?, ?>[] templates = new JTemplate<?, ?>[openedTemplate.size()];
for (int i = 0; i < openedTemplate.size(); i++) {
templates[i] = openedTemplate.get(i);
}
JTemplate<?, ?> currentTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
closeTemplate(templates, currentTemplate, option, index);
if (openedTemplate.isEmpty()) {
TemplateTabManager.getInstance().activeNewTemplate();
selectedIndex = 0;
} else {
DesignerContext.getDesignerFrame().activateJTemplate(currentTemplate);
}
}
}
/**
* 根据指定索引值关闭模板
* @param index
*/
public void closeByIndex(int index) {
//关闭close图标所在的模板{
JTemplate<?, ?> template = openedTemplate.get(index);
if (template.isOpening()) {
WorkerManager.getInstance().cancelWorker(template.getPath());
} else if (template.isSaving()) {
boolean completed = WorkerManager.getInstance().isCompleted(template.getTarget().getTemplateID());
if (!completed) {
FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Design_Close_Template_Tip", template.getEditingFILE().getName()));
return;
}
}
//参考CloseCurrentTemplateAction,在closeFormat与closeSpecifiedTemplate之前要先设定isCloseCurrent,这样关闭之后才会自动切换tab
if (checkCurrentClose(template)) {
TemplateTabManager.getInstance().setCloseCurrent(true);
}
TemplateTabManager.getInstance().closeFormat(template);
closeSpecifiedTemplate(template);
DesignerContext.getDesignerFrame().getContentFrame().repaint();
}
private boolean checkCurrentClose(JTemplate template) {
JTemplate currentTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
return JTemplate.isValid(currentTemplate) && ComparatorUtils.equals(template.getPath(), currentTemplate.getPath());
}
private void closeTemplate(JTemplate<?, ?>[] templates, JTemplate<?, ?> currentTemplate, CloseOption option, int tplIndex) {
for (int i = 0; i < templates.length; i++) {
if (option.shouldClose(tplIndex, i)) {
JTemplate<?, ?> jTemplate = templates[i];
if (jTemplate == currentTemplate) {
currentTemplate = option == CloseOption.All ? null : templates[tplIndex];
}
//判断关闭的模板是不是格式刷的被参照的模板
openedTemplate.remove(jTemplate);
if (jTemplate != currentTemplate) {
TemplateTabManager.getInstance().closeFormat(jTemplate);
HistoryTemplateListCache.getInstance().closeSelectedReport(jTemplate);
closeAndFreeLock(jTemplate);
}
}
}
}
private void closeAndFreeLock(@Nonnull JTemplate<?, ?> template) {
FILE file = template.getEditingFILE();
// 只有是环境内的文件,才执行释放锁
if (file != null && file.isEnvFile()) {
// release lock
WorkContext.getCurrent().get(TplOperator.class).closeAndFreeFile(file.getPath());
}
}
@Override
public void switchTpl(int templateIndex) {
int tempSelectedIndex = selectedIndex;
JTemplate jTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
boolean shouldSwitch = (selectedIndex != templateIndex || !this.accept(jTemplate.getTemplateTabOperatorType()))
&& templateIndex != -1;
if (shouldSwitch) {
openedTemplate.get(selectedIndex).stopEditing();
selectedIndex = templateIndex;
//如果在权限编辑情况下,不允许切换到表单类型的工作簿
if (DesignerMode.isAuthorityEditing() && !openedTemplate.get(selectedIndex).isJWorkBook()) {
DesignerContext.getDesignerFrame().addAndActivateJTemplate(openedTemplate.get(tempSelectedIndex));
FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Design_Basic_Form_Authority_Edited_Cannot_Be_Supported") + "!", Toolkit.i18nText("Fine-Design_Basic_Alert"), WARNING_MESSAGE);
return;
}
JTemplate evtTemplate = openedTemplate.get(templateIndex);
evtTemplate.activeNewJTemplate();
}
}
@Override
public void deleteOpenedTemplate(JTemplate<?, ?> template) {
if (!openedTemplate.contains(template)) {
return;
}
openedTemplate.remove(template);
if (openedTemplate.size() == 0) {
TemplateTabManager.getInstance().activeNewTemplate();
return;
}
if (openedTemplate.size() == selectedIndex) {
//如果删除的是后一个Tab,则定位到前一个
this.selectedIndex--;
}
}
@Override
public JTemplate getSelectedFile() {
if (openedTemplate.size() == selectedIndex) {
selectedIndex = Math.max(--selectedIndex, 0);
}
return openedTemplate.get(selectedIndex);
}
/**
* 关闭掉当前已打开文件列表中指定的文件
*
* @param file 指定的文件
*/
public void closeFileTemplate(FILE file) {
for (JTemplate<?, ?> temp : openedTemplate) {
if (ComparatorUtils.equals(file, temp.getEditingFILE())) {
closeSpecifiedTemplate(temp);
break;
}
}
}
/**
* 关闭模板
*
* @param specifiedTemplate 模板
*/
public void closeSpecifiedTemplate(JTemplate<?, ?> specifiedTemplate) {
if (specifiedTemplate == null && !openedTemplate.contains(specifiedTemplate)) {
return;
}
if (!specifiedTemplate.isALLSaved() && !DesignerMode.isVcsMode()) {
specifiedTemplate.stopEditing();
int returnVal = FineJOptionPane.showConfirmDialog(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Design_Basic_Utils_Would_You_Like_To_Save") + " \"" + specifiedTemplate.getEditingFILE() + "\" ?", Toolkit.i18nText("Fine-Design_Basic_Confirm"), JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
if (returnVal == JOptionPane.YES_OPTION) {
CallbackSaveWorker worker = specifiedTemplate.save();
worker.addSuccessCallback(new Runnable() {
@Override
public void run() {
FineLoggerFactory.getLogger().info(Toolkit.i18nText("Fine-Design_Basic_Template_Already_Saved", specifiedTemplate.getEditingFILE().getName()));
closeTpl(specifiedTemplate);
}
});
worker.start(specifiedTemplate.getRuntimeId());
} else if (returnVal == JOptionPane.NO_OPTION) {
closeTpl(specifiedTemplate);
}
} else {
closeTpl(specifiedTemplate);
}
}
private void closeTpl(@Nonnull JTemplate<?, ?> specifiedTemplate) {
HistoryTemplateListCache.getInstance().closeSelectedReport(specifiedTemplate);
closeAndFreeLock(specifiedTemplate);
activePrevTemplateAfterClose(specifiedTemplate == HistoryTemplateListCache.getInstance().getCurrentEditingTemplate());
}
/**
* 关闭掉一个模板之后激活新的待显示模板
*/
@Override
public void activePrevTemplateAfterClose(){
activePrevTemplateAfterClose(TemplateTabManager.getInstance().isCloseCurrent());
}
/**
* 关闭掉一个模板之后激活新的待显示模板
*/
public void activePrevTemplateAfterClose(boolean isCurrentSelectedTpl) {
if (openedTemplate.isEmpty()) {
TemplateTabManager.getInstance().activeNewTemplate();
selectedIndex = 0;
} else {
// 如果关闭的模板是当前选中的模板,则重新激活当前 selectIndex 的模板;
// selectIndex 没有变化,但是对应的模板已经变成了前一张模板
if (isCurrentSelectedTpl || TemplateTabManager.getInstance().isCloseCurrent()) {
// 如果当前关闭的模板在最右侧,那么预览上一个,防止数组越界
if (selectedIndex >= openedTemplate.size()) {
// selectIndex 不会 <0 因为如果关闭的是打开的最后一个模板,那么关闭之后 openedTemplate.isEmpty() = true
selectedIndex--;
}
TemplateTabManager.getInstance().setCloseCurrent(false);
}
// 如果关闭的模板不是当前选中的模板,那么重新获取一下当前模板的 index,激活该 index
else {
JTemplate template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
selectedIndex = this.openedTemplate.indexOf(template);
}
if (selectedIndex < openedTemplate.size()) {
//如果是已后台关闭的模板,则重新打开文件
openedTemplate.get(selectedIndex).activeOldJTemplate();
}
}
TemplateTabManager.getInstance().refresh();
}
@Override
public void resetSelectIndex(JTemplate jTemplate) {
this.selectedIndex = openedTemplate.indexOf(jTemplate);
TemplateTabManager.getInstance().refresh();
}
/**
* 刷新已打开的模板
* @param list
*/
public void refreshOpenedTemplate(List<JTemplate<?, ?>> list) {
List<JTemplate<?, ?>> result = new ArrayList<>();
for (JTemplate jTemplate : list) {
if (this.accept(jTemplate.getTemplateTabOperatorType())) {
result.add(jTemplate);
}
}
this.openedTemplate = result;
TemplateTabManager.getInstance().refresh();
}
public List<JTemplate<?, ?>> getOpenedJTemplates() {
return this.openedTemplate;
}
@Override
public void setSelectIndex(int index) {
this.selectedIndex = index;
}
@Override
public int getSelectIndex() {
return this.selectedIndex;
}
@Override
public int getJTemplateIndex(JTemplate jTemplate) {
return this.openedTemplate.indexOf(jTemplate);
}
/**
* 是否支持指定操作类型
* @param type
* @return
*/
public boolean accept(String type) {
return CompareUtils.isEqual(getOperatorType(), type);
}
@Override
public String getTemplateShowName(JTemplate template) {
String name = TemplateUtils.createLockeTemplatedName(template, template.getTemplateName());
if (!template.isSaved() && !name.endsWith(UNSAVED_SUFFIX)) {
name += UNSAVED_SUFFIX;
}
return name;
}
}

41
designer-base/src/main/java/com/fr/design/file/impl/DefaultTemplateTabOperate.java

@ -0,0 +1,41 @@
package com.fr.design.file.impl;
import com.fr.design.file.MultiTemplateTabPane;
/**
* 默认的模板tab的操作类
* @author kerry
* @since 11.0
* created on 2023-04-14
**/
public class DefaultTemplateTabOperate extends AbstractTemplateTabOperate {
public static final String OPERATOR_TYPE = "DEFAULT_TEMPLATE_TAB_OPERATOR";
private static class Holder {
private static final DefaultTemplateTabOperate SINGLETON = new DefaultTemplateTabOperate();
}
private DefaultTemplateTabOperate() {
super();
}
/**
* 返回DefaultTemplateTabOperate 单例
* @return
*/
public static DefaultTemplateTabOperate getInstance() {
return Holder.SINGLETON;
}
@Override
public void refresh() {
MultiTemplateTabPane.getInstance().repaint();
}
@Override
public String getOperatorType() {
return OPERATOR_TYPE;
}
}

124
designer-base/src/main/java/com/fr/design/file/impl/EmptyTemplateTabOperate.java

@ -0,0 +1,124 @@
package com.fr.design.file.impl;
import com.fr.design.file.CloseOption;
import com.fr.design.file.TemplateTabOperateProvider;
import com.fr.design.mainframe.JTemplate;
import com.fr.file.FILE;
import com.fr.stable.StringUtils;
import java.util.ArrayList;
import java.util.List;
/**
* 空的模板tab的操作类
* @author kerry
* @since 11.0
* created on 2023-04-14
**/
public class EmptyTemplateTabOperate implements TemplateTabOperateProvider {
private static class Holder {
private static final EmptyTemplateTabOperate SINGLETON = new EmptyTemplateTabOperate();
}
private EmptyTemplateTabOperate() {
}
/**
* 返回空的模板taboperator单例
* @return
*/
public static EmptyTemplateTabOperate getInstance() {
return Holder.SINGLETON;
}
@Override
public void locateTemplateInTree(int tplIndex) {
}
@Override
public void closeAction(CloseOption option, int index) {
}
@Override
public void closeByIndex(int index) {
}
@Override
public void switchTpl(int templateIndex) {
}
@Override
public List<JTemplate<?, ?>> getOpenedJTemplates() {
return new ArrayList<>();
}
@Override
public void closeSpecifiedTemplate(JTemplate<?, ?> specifiedTemplate) {
}
@Override
public void deleteOpenedTemplate(JTemplate<?, ?> template) {
}
@Override
public JTemplate getSelectedFile() {
return null;
}
@Override
public void refresh() {
}
@Override
public void resetSelectIndex(JTemplate jTemplate) {
}
@Override
public void refreshOpenedTemplate(List<JTemplate<?, ?>> list) {
}
@Override
public void closeFileTemplate(FILE file) {
}
@Override
public String getOperatorType() {
return StringUtils.EMPTY;
}
@Override
public int getSelectIndex() {
return 0;
}
@Override
public void setSelectIndex(int index) {
}
@Override
public int getJTemplateIndex(JTemplate jTemplate) {
return 0;
}
@Override
public String getTemplateShowName(JTemplate jTemplate) {
return StringUtils.EMPTY;
}
@Override
public void activePrevTemplateAfterClose() {
}
}

31
designer-base/src/main/java/com/fr/design/gui/controlpane/UIListGroupControlPane.java

@ -28,14 +28,7 @@ import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.lang.reflect.Constructor;
@ -146,7 +139,7 @@ public abstract class UIListGroupControlPane extends UIControlPane implements Li
}
this.checkButtonEnabled();
refreshEventListWrapperPane();
this.checkGroupPaneSize();
this.updateGroupPaneSize(contentPane);
isPopulating = false;
}
@ -214,7 +207,7 @@ public abstract class UIListGroupControlPane extends UIControlPane implements Li
nameEdList.addModNameActionListener(new ModNameActionListener() {
@Override
public void nameModed(int index, String oldName, String newName) {
checkGroupPaneSize();
updateGroupPaneSize(contentPane);
saveSettings();
}
});
@ -304,24 +297,30 @@ public abstract class UIListGroupControlPane extends UIControlPane implements Li
public void onAddItem(NameableCreator creator) {
updateSelectedNameList(creator);
getCommonHandlers().onAddItem(creator);
checkGroupPaneSize();
updateGroupPaneSize(contentPane);
}
@Override
public void onRemoveItem() {
getCommonHandlers().onRemoveItem();
refreshEventListWrapperPane();
checkGroupPaneSize();
updateGroupPaneSize(contentPane);
}
@Override
public void onCopyItem() {
getCommonHandlers().onCopyItem();
checkGroupPaneSize();
updateGroupPaneSize(contentPane);
}
private void checkGroupPaneSize() {
/**
* 根据父面板更新对应的面板宽度
* 如果小于父面板的宽度就填充到与父面板宽度一致
*
* @param parentPane 父面板
*/
private void updateGroupPaneSize(JPanel parentPane) {
int width = 180;
Iterator<Map.Entry<String, ListWrapperPane>> iterator = nameEdListMap.entrySet().iterator();
while (iterator.hasNext()) {
@ -331,7 +330,9 @@ public abstract class UIListGroupControlPane extends UIControlPane implements Li
width = Math.max(width, calculateUIListMaxCellWidth(uiList.getModel(), uiList.getFontMetrics(uiList.getFont())));
}
iterator = nameEdListMap.entrySet().iterator();
width += 30;
//contentPane是外层的Panel,如果不进行判断的话宽度就可能会小于contentPanel,右侧会有空隙
//所以需要判断一下,如果外层比较宽就取外层的宽度,防止空隙出现
width = Math.max(width + 30, parentPane == null ? 0 : parentPane.getWidth());
while (iterator.hasNext()) {
Map.Entry<String, ListWrapperPane> entry = iterator.next();
ListWrapperPane wrapperPane = entry.getValue();

65
designer-base/src/main/java/com/fr/design/javascript/JSContentWithDescriptionPane.java

@ -36,6 +36,7 @@ import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.SwingWorker;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TreeSelectionEvent;
@ -69,6 +70,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.ExecutionException;
public class JSContentWithDescriptionPane extends JSContentPane implements KeyListener {
@ -109,6 +111,8 @@ public class JSContentWithDescriptionPane extends JSContentPane implements KeyLi
private static final String URL_FOR_TEST_NETWORK = "https://www.baidu.com";
private static final String DOCUMENT_SEARCH_URL = "https://help.fanruan.com/finereport/api-helpdoc-title-";
private String currentValue;
private static CardLayout card;
@ -125,7 +129,6 @@ public class JSContentWithDescriptionPane extends JSContentPane implements KeyLi
* 云中心Js高级编辑器帮助链接前缀在配置文件中对应的配置文件key
*/
private static final String PROPS_LINK_KEY_DEFAULT = "Fine-Design-CloudCenter_Js_Editor_Default";
public JSContentWithDescriptionPane(String[] args) {
this.setLayout(new BorderLayout());
//===============================
@ -361,27 +364,51 @@ public class JSContentWithDescriptionPane extends JSContentPane implements KeyLi
private void doHelpDocumentSearch() {
Object value = interfaceNameList.getSelectedValue();
if (value != null) {
String url = LocaleLinkProvider.getInstance().getLink(PROPS_LINK_KEY, PROPS_LINK_KEY_DEFAULT);
try {
String result = HttpToolbox.get(url);
JSONObject jsonObject = new JSONObject(result);
JSONArray jsonArray = jsonObject.optJSONArray("list");
if (jsonArray != null) {
DefaultListModel helpDOCModel = (DefaultListModel) helpDOCList.getModel();
helpDOCModel.clear();
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject resultJSONObject = jsonArray.optJSONObject(i);
String docURL = resultJSONObject.optString("url");
String name = resultJSONObject.optString("title").trim();
HelpDocument helpDocument = new HelpDocument(docURL, name);
helpDOCModel.addElement(helpDocument);
new SwingWorker<List<HelpDocument>, Void>() {
@Override
protected List<HelpDocument> doInBackground() {
List<HelpDocument> helpDocuments = new ArrayList<>();
updateHelpDocuments(value, helpDocuments);
return helpDocuments;
}
@Override
protected void done() {
try {
List<HelpDocument> helpDocuments = get();
DefaultListModel helpDOCModel = (DefaultListModel) helpDOCList.getModel();
helpDOCModel.clear();
for (HelpDocument helpDocument : helpDocuments) {
helpDOCModel.addElement(helpDocument);
}
} catch (InterruptedException | ExecutionException e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
} catch (JSONException e) {
FineLoggerFactory.getLogger().debug(e.getMessage(), e);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}.execute();
}
}
private void updateHelpDocuments(Object value, List<HelpDocument> helpDocuments) {
String url = LocaleLinkProvider.getInstance().getLink(PROPS_LINK_KEY, PROPS_LINK_KEY_DEFAULT);
try {
String result = HttpToolbox.get(url);
JSONObject jsonObject = new JSONObject(result);
JSONArray jsonArray = jsonObject.optJSONArray("list");
if (jsonArray != null) {
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject resultJSONObject = jsonArray.optJSONObject(i);
String docURL = resultJSONObject.optString("url");
String name = resultJSONObject.optString("title").trim();
HelpDocument helpDocument = new HelpDocument(docURL, name);
helpDocuments.add(helpDocument);
}
}
} catch (JSONException e) {
FineLoggerFactory.getLogger().debug(e.getMessage(), e);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}

2
designer-base/src/main/java/com/fr/design/locale/impl/VideoMark.java

@ -16,7 +16,7 @@ public class VideoMark implements LocaleMark<String> {
private Map<Locale, String> map = new HashMap<>();
private static final String VIDEO_EN = CloudCenter.getInstance().acquireUrlByKind("bbs.video.en_US", "http://www.finereport.com/en/Learning-path");
private static final String VIDEO_CN = CloudCenter.getInstance().acquireUrlByKind("bbs.video.zh_CN", "https://edu.fanruan.com/video?class1=16&class2=0");
private static final String VIDEO_CN = CloudCenter.getInstance().acquireUrlByKind("bbs.video.zh_CN", "https://home.fanruan.com/finereport/video");
private static final String VIDEO_TW = CloudCenter.getInstance().acquireUrlByKind("bbs.video.zh_TW", "http://www.finereport.com/tw/video");
public VideoMark() {

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

@ -230,12 +230,11 @@ public class CenterRegionContainerPane extends JPanel {
// 颜色,字体那些按钮的工具栏
toolbarPane.add(toolbarComponent = ad.resetToolBar(toolbarComponent, plus), BorderLayout.CENTER);
if (strategy.hasToolBarPane(plus)) {
this.add(toolbarPane, BorderLayout.NORTH);
} else {
this.remove(toolbarPane);
JPanel customNorthPane = strategy.customNorthPane(toolbarPane,plus);
if (!isExist(customNorthPane)){
this.removeNorth();
this.add(customNorthPane, BorderLayout.NORTH);
}
if (strategy.hasTemplateTabPane(plus)) {
eastCenterPane.add(templateTabPane, BorderLayout.CENTER);
} else {
@ -250,6 +249,26 @@ public class CenterRegionContainerPane extends JPanel {
resetByDesignMode();
}
private void removeNorth(){
Component[] components = this.getComponents();
for(Component c : components){
if (c!= centerTemplateCardPane){
this.remove(c);
}
}
}
private boolean isExist(JPanel customNorthPane) {
Component[] components = this.getComponents();
for (Component component : components) {
if (component == customNorthPane) {
return true;
}
}
return false;
}
private void resetByDesignMode() {
if (DesignModeContext.isDuchampMode()) {
eastPane.remove(largeToolbar);

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

@ -3,6 +3,9 @@ package com.fr.design.mainframe;
import com.fr.design.base.mode.DesignModeContext;
import com.fr.design.mainframe.toolbar.ToolBarMenuDockPlus;
import javax.swing.JPanel;
public class DefaultToolKitConfig implements ToolKitConfigStrategy {
@Override
public boolean hasTemplateTabPane(ToolBarMenuDockPlus plus) {
@ -18,4 +21,9 @@ public class DefaultToolKitConfig implements ToolKitConfigStrategy {
public boolean hasToolBarPane(ToolBarMenuDockPlus plus) {
return plus.hasToolBarPane();
}
@Override
public JPanel customNorthPane(JPanel toolBarPane, ToolBarMenuDockPlus plus) {
return toolBarPane;
}
}

4
designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java

@ -21,8 +21,8 @@ import com.fr.design.event.TargetModifiedEvent;
import com.fr.design.event.TargetModifiedListener;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.file.HistoryTemplateListPane;
import com.fr.design.file.MultiTemplateTabPane;
import com.fr.design.file.SaveSomeTemplatePane;
import com.fr.design.file.TemplateTabManager;
import com.fr.design.file.TemplateTreePane;
import com.fr.design.fun.OemProcessor;
import com.fr.design.fun.impl.AbstractTemplateTreeShortCutProvider;
@ -1110,7 +1110,7 @@ public class DesignerFrame extends JFrame implements JTemplateActionListener, Ta
// 新的form不往前兼容
if (inValidDesigner(jt)) {
this.addAndActivateJTemplate();
MultiTemplateTabPane.getInstance().setTemTemplate(
TemplateTabManager.getInstance().setTemTemplate(
HistoryTemplateListCache.getInstance().getCurrentEditingTemplate());
} else {
this.addAndActivateJTemplate(jt);

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

@ -21,7 +21,7 @@ import com.fr.design.file.FileOperations;
import com.fr.design.file.FileToolbarStateChangeListener;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.file.HistoryTemplateListPane;
import com.fr.design.file.MultiTemplateTabPane;
import com.fr.design.file.TemplateTabManager;
import com.fr.design.file.TemplateTreePane;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ilable.UILabel;
@ -275,7 +275,7 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt
TableDataTreePane.getInstance(DesignModelAdapter.getCurrentModelAdapter());
HistoryTemplateListPane.getInstance().setCurrentEditingTemplate(jt);
//处理自动新建的模板
MultiTemplateTabPane.getInstance().doWithtemTemplate();
TemplateTabManager.getInstance().doWithtemTemplate();
if (DesignerMode.isAuthorityEditing()) {
RolesAlreadyEditedPane.getInstance().refreshDockingView();
}
@ -547,10 +547,10 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt
for (JTemplate jTemplate : HistoryTemplateListCache.getInstance().getHistoryList()) {
if (ComparatorUtils.equals(jTemplate.getEditingFILE().getPath(), path)) {
if (isCurrentEditing) {
MultiTemplateTabPane.getInstance().setIsCloseCurrent(true);
TemplateTabManager.getInstance().setCloseCurrent(true);
}
MultiTemplateTabPane.getInstance().closeFormat(jTemplate);
MultiTemplateTabPane.getInstance().closeSpecifiedTemplate(jTemplate);
TemplateTabManager.getInstance().closeFormat(jTemplate);
TemplateTabManager.getInstance().closeSpecifiedTemplate(jTemplate);
return;
}
}

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

@ -33,6 +33,7 @@ import com.fr.design.dialog.InformationWarnPane;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.file.HistoryTemplateListPane;
import com.fr.design.file.TemplateResourceManager;
import com.fr.design.file.impl.DefaultTemplateTabOperate;
import com.fr.design.fun.DesignerFrameUpButtonProvider;
import com.fr.design.fun.MenuHandler;
import com.fr.design.fun.PreviewProvider;
@ -61,6 +62,8 @@ import com.fr.design.utils.DesignUtils;
import com.fr.design.worker.save.CallbackSaveWorker;
import com.fr.design.worker.save.EmptyCallBackSaveWorker;
import com.fr.design.worker.save.SaveFailureHandler;
import com.fr.design.worker.save.type.SaveType;
import com.fr.design.worker.save.type.SaveTypeWorker;
import com.fr.design.write.submit.DBManipulationInWidgetEventPane;
import com.fr.design.write.submit.DBManipulationPane;
import com.fr.event.EventDispatcher;
@ -615,7 +618,7 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
* @return 是则返回true
*/
public boolean isALLSaved() {
return this.saved && this.authoritySaved;
return this.canBeSaved() && this.saved && this.authoritySaved;
}
@ -1687,24 +1690,7 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
if (!editingFILE.exists()) {
return saveAs(showLoc);
}
CallbackSaveWorker worker = new CallbackSaveWorker(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
return saveRealFileByWorker();
}
}, this);
worker.addSuccessCallback(new Runnable() {
@Override
public void run() {
callBackForSave();
//在保存后的回调中执行预编译流程
CptCompileUtil.compile(JTemplate.this);
}
});
return worker;
return getSaveCallBackSaveWorker();
}
/**
@ -1750,6 +1736,8 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
}
}
private CallbackSaveWorker saveAs(boolean showLoc) {
FILE editingFILE = this.getEditingFILE();
if (editingFILE == null) {
@ -1771,7 +1759,6 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
// 目标文件
editingFILE = fileChooser.getSelectedFILE();
}
FILE finalEditingFILE = editingFILE;
CallbackSaveWorker worker = new CallbackSaveWorker(new Callable<Boolean>() {
@Override
@ -1872,10 +1859,95 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
return saveAs(true);
}
/**
* 获取保存用到的saveWorker
*/
private CallbackSaveWorker getSaveCallBackSaveWorker() {
CallbackSaveWorker worker = new CallbackSaveWorker(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
return saveRealFileByWorker();
}
}, this);
worker.addSuccessCallback(new Runnable() {
@Override
public void run() {
callBackForSave();
//在保存后的回调中执行预编译流程
CptCompileUtil.compile(JTemplate.this);
}
});
return worker;
}
/**
* 获取保存的类别执行的callable
*/
private Callable<SaveType.TypeEnum> getSaveTypeCallable() {
return () -> {
fireJTemplateSaveBefore();
FILE editingFILE = getEditingFILE();
// carl:editingFILE没有,当然不存了,虽然不会有这种情况
if (editingFILE == null) {
return SaveType.TypeEnum.EMPTY;
}
// 检查一下editingFILE是不是已存在的文件,如果不存在则用saveAs
if (!editingFILE.exists()) {
return SaveType.TypeEnum.SAVE_AS;
}
return SaveType.TypeEnum.SAVE;
};
}
/**
* 根据保存类型获取对应的saveWorker
*
* @param saveType 保存类型
*/
private CallbackSaveWorker getSaveTypeWorker(SaveType saveType) {
CallbackSaveWorker callbackSaveWorker;
switch (saveType.getType()) {
case EMPTY:
callbackSaveWorker = new EmptyCallBackSaveWorker();
break;
case SAVE:
callbackSaveWorker = getSaveCallBackSaveWorker();
break;
default:
callbackSaveWorker = saveAs(true);
}
return callbackSaveWorker;
}
@Override
public void saveDirectly() {
CallbackSaveWorker worker = save();
worker.start(getRuntimeId());
new SaveTypeWorker(getSaveTypeCallable(), this) {
@Override
protected void done() {
try {
SaveType saveType = get();
CallbackSaveWorker callbackSaveWorker = getSaveTypeWorker(saveType);
//告诉一下后面执行的saveWorker,当前判断文件是否存在的操作是否已经进行了开始转圈的那个等待动画,避免重复
callbackSaveWorker.setSlowly(saveType.isSlowly());
callbackSaveWorker.start(getRuntimeId());
//如果是空也就是不保存,需要恢复一下界面(如果saveTypeWorker里进行了操作的话)
if (callbackSaveWorker instanceof EmptyCallBackSaveWorker) {
setSaving(false);
if (saveType.isSlowly()) {
if (ComparatorUtils.equals(getName(), HistoryTemplateListCache.getInstance().getCurrentEditingTemplate().getName())) {
DesignerContext.getDesignerFrame().getCenterTemplateCardPane().hideCover();
}
}
DesignerFrameFileDealerPane.getInstance().stateChange();
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
}.start();
}
@Override
@ -1979,7 +2051,11 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
public void setDesignerUIMode() {
DesignerUIModeConfig.getInstance().setAbsoluteMeasureUIMode();
}
public String getTemplateTabOperatorType(){
return DefaultTemplateTabOperate.OPERATOR_TYPE;
}
/**
* 判断当前的模板是否是有效的模板
*
@ -1989,4 +2065,21 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
public static boolean isValid(JTemplate jt) {
return jt != null && jt != JNullTemplate.NULL;
}
/**
* 当前模板是否可以被保存
* @return /
*/
public boolean canBeSaved(){
return true;
}
/**
* 当前的模板是否支持缓存
*
* @return /
*/
public boolean supportCache(){
return true;
}
}

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

@ -2,6 +2,9 @@ package com.fr.design.mainframe;
import com.fr.design.mainframe.toolbar.ToolBarMenuDockPlus;
import javax.swing.JPanel;
public interface ToolKitConfigStrategy {
/**
@ -24,4 +27,11 @@ public interface ToolKitConfigStrategy {
* @return
*/
boolean hasToolBarPane(ToolBarMenuDockPlus plus);
/**
* 定制工具栏
* @param toolBarPane
* @param plus
* @return
*/
JPanel customNorthPane(JPanel toolBarPane, ToolBarMenuDockPlus plus);
}

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

@ -42,6 +42,7 @@ import com.fr.design.actions.server.GlobalTableDataAction;
import com.fr.design.actions.server.PlatformManagerAction;
import com.fr.design.actions.server.PluginManagerAction;
import com.fr.design.base.mode.DesignModeContext;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.file.NewTemplatePane;
import com.fr.design.fun.MenuHandler;
import com.fr.design.fun.OemProcessor;
@ -275,7 +276,10 @@ public abstract class ToolBarMenuDock {
insertTemplateExtendMenu(plus, menuDefs);
// 添加模板菜单
menuList.addAll(Arrays.asList(menuDefs));
// 如果是JNullTemplate不能添加模板菜单,之前没有这个JNullTemplate所以没考虑
if (JTemplate.isValid(HistoryTemplateListCache.getInstance().getCurrentEditingTemplate())) {
menuList.addAll(Arrays.asList(menuDefs));
}
// 添加服务器菜单
if (WorkContext.getCurrent() != null && WorkContext.getCurrent().isRoot()) {
@ -412,9 +416,7 @@ public abstract class ToolBarMenuDock {
menuDef.addShortCut(new OpenRecentReportMenuDef());
if (!DesignModeContext.isDuchampMode()) {
addCloseCurrentTemplateAction(menuDef);
}
addCloseCurrentTemplateAction(menuDef);
scs = plus.shortcut4FileMenu();
if (!ArrayUtils.isEmpty(scs)) {

8
designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/FileVersionCellEditor.java

@ -1,7 +1,7 @@
package com.fr.design.mainframe.vcs.ui;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.file.MultiTemplateTabPane;
import com.fr.design.file.TemplateTabManager;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.DesignerFrameFileDealerPane;
import com.fr.design.mainframe.JTemplate;
@ -57,9 +57,9 @@ public class FileVersionCellEditor extends AbstractCellEditor implements TableCe
jt.stopEditing();
//只有模板路径一致时关闭当前模板
if (ComparatorUtils.equals(fileOfVersion, jt.getPath())) {
MultiTemplateTabPane.getInstance().setIsCloseCurrent(true);
MultiTemplateTabPane.getInstance().closeFormat(jt);
MultiTemplateTabPane.getInstance().closeSpecifiedTemplate(jt);
TemplateTabManager.getInstance().setCloseCurrent(true);
TemplateTabManager.getInstance().closeFormat(jt);
TemplateTabManager.getInstance().closeSpecifiedTemplate(jt);
}
//再打开cache中的模板

8
designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/FileVersionsPanel.java

@ -5,7 +5,7 @@ import com.fr.design.base.mode.DesignModeContext;
import com.fr.design.base.mode.DesignerMode;
import com.fr.design.dialog.BasicPane;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.file.MultiTemplateTabPane;
import com.fr.design.file.TemplateTabManager;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.icontainer.UIScrollPane;
import com.fr.design.gui.ilable.UILabel;
@ -115,9 +115,9 @@ public class FileVersionsPanel extends BasicPane {
// 关闭当前打开的版本
JTemplate<?, ?> jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
MultiTemplateTabPane.getInstance().setIsCloseCurrent(true);
MultiTemplateTabPane.getInstance().closeFormat(jt);
MultiTemplateTabPane.getInstance().closeSpecifiedTemplate(jt);
TemplateTabManager.getInstance().setCloseCurrent(true);
TemplateTabManager.getInstance().closeFormat(jt);
TemplateTabManager.getInstance().closeSpecifiedTemplate(jt);
updateDesignerFrame(true);

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

@ -3,7 +3,7 @@ package com.fr.design.worker.open;
import com.fr.base.chart.exception.ChartNotFoundException;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.file.MultiTemplateTabPane;
import com.fr.design.file.TemplateTabManager;
import com.fr.design.file.TemplateTreePane;
import com.fr.design.i18n.Toolkit;
import com.fr.design.lock.LockInfoDialog;
@ -87,7 +87,7 @@ public class OpenWorker<T> extends SwingWorker<T, Void> {
UIManager.getIcon("OptionPane.errorIcon"));
}
if (cause.getCause() instanceof TplLockedException) {
MultiTemplateTabPane.getInstance().closeCurrentTpl();
TemplateTabManager.getInstance().closeCurrentTpl();
TemplateTreePane.getInstance().getFileNode().setLock(UUID.randomUUID().toString());
LockInfoDialog.show(null);
}

52
designer-base/src/main/java/com/fr/design/worker/save/SaveWorker.java

@ -5,12 +5,16 @@ import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.DesignerFrameFileDealerPane;
import com.fr.design.mainframe.EastRegionContainerPane;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.ui.util.UIUtil;
import com.fr.design.worker.WorkerManager;
import com.fr.design.worker.save.type.SaveTypeWorker;
import com.fr.general.ComparatorUtils;
import com.fr.log.FineLoggerFactory;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import com.fr.third.org.apache.commons.lang3.time.StopWatch;
import javax.swing.SwingWorker;
/**
@ -34,6 +38,14 @@ public class SaveWorker extends SwingWorker<Boolean, Void> {
private boolean slowly;
public boolean isSlowly() {
return slowly;
}
public void setSlowly(boolean slowly) {
this.slowly = slowly;
}
public SaveWorker(Callable<Boolean> callable, JTemplate<?, ?> template) {
this.callable = callable;
this.template = template;
@ -47,10 +59,11 @@ public class SaveWorker extends SwingWorker<Boolean, Void> {
@Override
protected void done() {
try {
success = get();
success = get();
} catch (Exception e) {
processResult();
FineLoggerFactory.getLogger().error(e.getMessage(), e);
WorkerManager.getInstance().removeWorker(taskName);
SaveFailureHandler.getInstance().process(e);
return;
}
@ -62,6 +75,7 @@ public class SaveWorker extends SwingWorker<Boolean, Void> {
// 恢复界面
if (slowly && ComparatorUtils.equals(this.template.getName(), HistoryTemplateListCache.getInstance().getCurrentEditingTemplate().getName())) {
DesignerContext.getDesignerFrame().getCenterTemplateCardPane().hideCover();
slowly = false;
}
DesignerFrameFileDealerPane.getInstance().stateChange();
WorkerManager.getInstance().removeWorker(taskName);
@ -69,21 +83,29 @@ public class SaveWorker extends SwingWorker<Boolean, Void> {
public void start(String taskName) {
this.taskName = taskName;
StopWatch stopWatch = StopWatch.createStarted();
this.template.setSaving(true);
this.execute();
// worker纳入管理
WorkerManager.getInstance().registerWorker(taskName, this);
try {
this.get(TIME_OUT, TimeUnit.MILLISECONDS);
} catch (TimeoutException timeoutException) {
slowly = true;
// 开始禁用
EastRegionContainerPane.getInstance().updateAllPropertyPane();
DesignerContext.getDesignerFrame().getCenterTemplateCardPane().showCover();
DesignerFrameFileDealerPane.getInstance().stateChange();
} catch (Exception exception) {
FineLoggerFactory.getLogger().error(exception.getMessage(), exception);
WorkerManager.getInstance().removeWorker(taskName);
}
SaveTypeWorker.SAVE_TYPE_POOL.execute(() -> {
while (true) {
if (stopWatch.getTime() > TIME_OUT || isDone()) {
if (!isDone()) {
slowly = true;
UIUtil.invokeLaterIfNeeded(() -> {
// 开始禁用
if (slowly) {
EastRegionContainerPane.getInstance().updateAllPropertyPane();
DesignerContext.getDesignerFrame().getCenterTemplateCardPane().showCover();
DesignerFrameFileDealerPane.getInstance().stateChange();
}
});
}
stopWatch.stop();
break;
}
}
});
}
}

50
designer-base/src/main/java/com/fr/design/worker/save/type/SaveType.java

@ -0,0 +1,50 @@
package com.fr.design.worker.save.type;
/**
* 保存的类别
*
* @author John.Ying
* @since 11.0
* Created on 2023/4/14
*/
public class SaveType {
private TypeEnum type;
//保存时间是否慢(是否展示了保存中的UI界面)
private boolean slowly;
public TypeEnum getType() {
return type;
}
public void setType(TypeEnum saveType) {
this.type = saveType;
}
public boolean isSlowly() {
return slowly;
}
public void setSlowly(boolean slowly) {
this.slowly = slowly;
}
/**
* 保存类型save or saveAs or empty
*/
public enum TypeEnum {
/**
* 保存
*/
SAVE,
/**
* 另存
*/
SAVE_AS,
/**
* 空保存
*/
EMPTY;
}
}

81
designer-base/src/main/java/com/fr/design/worker/save/type/SaveTypeWorker.java

@ -0,0 +1,81 @@
package com.fr.design.worker.save.type;
import com.fr.concurrent.FineExecutors;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.DesignerFrameFileDealerPane;
import com.fr.design.mainframe.EastRegionContainerPane;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.ui.util.UIUtil;
import com.fr.third.org.apache.commons.lang3.time.StopWatch;
import javax.swing.SwingWorker;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
/**
* 判断保存类别时执行的worker
*
* @author John.Ying
* @since 11.0
* Created on 2023/4/14
*/
public class SaveTypeWorker extends SwingWorker<SaveType, Void> {
public static final ExecutorService SAVE_TYPE_POOL = FineExecutors.newSingleThreadExecutor();
private final Callable<SaveType.TypeEnum> callable;
private static final int TIME_OUT = 400;
private final JTemplate<?, ?> template;
private final SaveType saveType;
public SaveTypeWorker(Callable<SaveType.TypeEnum> callable, JTemplate<?, ?> template) {
this.callable = callable;
this.template = template;
this.saveType = new SaveType();
}
@Override
protected SaveType doInBackground() throws Exception {
this.saveType.setType(callable.call());
return this.saveType;
}
@Override
protected void done() {
}
/**
* 启动saveTypeWorker
*/
public void start() {
StopWatch stopWatch = StopWatch.createStarted();
this.template.setSaving(true);
this.execute();
SAVE_TYPE_POOL.execute(() -> {
while (true) {
//大于最大等待时间或者worker已经完成该线程都要结束循环
if (stopWatch.getTime() > TIME_OUT || isDone()) {
//如果是大于最大等待时间结束的,就需要进行等待中界面的覆盖
if (!isDone()) {
saveType.setSlowly(true);
UIUtil.invokeLaterIfNeeded(() -> {
// 开始禁用
EastRegionContainerPane.getInstance().updateAllPropertyPane();
DesignerContext.getDesignerFrame().getCenterTemplateCardPane().showCover();
DesignerFrameFileDealerPane.getInstance().stateChange();
});
}
stopWatch.stop();
break;
}
}
});
}
}

8
designer-base/src/main/java/com/fr/nx/app/designer/toolbar/TemplateTransformer.java

@ -2,7 +2,7 @@ package com.fr.nx.app.designer.toolbar;
import com.fr.base.extension.FileExtension;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.file.MultiTemplateTabPane;
import com.fr.design.file.TemplateTabManager;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.JTemplate;
import com.fr.file.FILE;
@ -103,9 +103,9 @@ public enum TemplateTransformer {
DesignerContext.getDesignerFrame().openTemplate(file);
return;
}
MultiTemplateTabPane.getInstance().setIsCloseCurrent(true);
MultiTemplateTabPane.getInstance().closeFormat(jt);
MultiTemplateTabPane.getInstance().closeSpecifiedTemplate(jt);
TemplateTabManager.getInstance().setCloseCurrent(true);
TemplateTabManager.getInstance().closeFormat(jt);
TemplateTabManager.getInstance().closeSpecifiedTemplate(jt);
DesignerContext.getDesignerFrame().openTemplate(file);
}

6
designer-base/src/main/java/com/fr/start/BaseDesigner.java

@ -8,7 +8,7 @@ import com.fr.design.DesignerEnvManager;
import com.fr.design.ExtraDesignClassManager;
import com.fr.design.constants.DesignerLaunchStatus;
import com.fr.design.file.HistoryTemplateListPane;
import com.fr.design.file.MultiTemplateTabPane;
import com.fr.design.file.TemplateTabManager;
import com.fr.design.file.TemplateTreePane;
import com.fr.design.fun.DesignerStartOpenFileProcessor;
import com.fr.design.fun.impl.DesignerStartWithEmptyFile;
@ -193,7 +193,7 @@ public abstract class BaseDesigner extends ToolBarMenuDock {
} else {
df.addAndActivateJTemplate();
// 如果没有模板,则需要确认一下
MultiTemplateTabPane.getInstance().setTemTemplate(HistoryTemplateListPane.getInstance().getCurrentEditingTemplate());
TemplateTabManager.getInstance().setTemTemplate(HistoryTemplateListPane.getInstance().getCurrentEditingTemplate());
}
}
@ -253,7 +253,7 @@ public abstract class BaseDesigner extends ToolBarMenuDock {
private boolean createNewTemplate(DesignerFrame df) {
df.addAndActivateJTemplate();
// 如果没有模板,则需要确认一下
MultiTemplateTabPane.getInstance().setTemTemplate(HistoryTemplateListPane.getInstance().getCurrentEditingTemplate());
TemplateTabManager.getInstance().setTemTemplate(HistoryTemplateListPane.getInstance().getCurrentEditingTemplate());
return true;
}

4
designer-base/src/main/java/com/fr/start/common/DesignerOpenEmptyPanel.java

@ -3,7 +3,7 @@ package com.fr.start.common;
import com.fr.base.svg.IconUtils;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.file.HistoryTemplateListPane;
import com.fr.design.file.MultiTemplateTabPane;
import com.fr.design.file.TemplateTabManager;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.DesignSizeI18nManager;
import com.fr.design.i18n.Toolkit;
@ -59,7 +59,7 @@ public class DesignerOpenEmptyPanel extends JPanel {
HistoryTemplateListCache.getInstance().setCurrentEditingTemplate(null);
df.addAndActivateJTemplate();
// 如果没有模板,则需要确认一下
MultiTemplateTabPane.getInstance().setTemTemplate(HistoryTemplateListPane.getInstance().getCurrentEditingTemplate());
TemplateTabManager.getInstance().setTemTemplate(HistoryTemplateListPane.getInstance().getCurrentEditingTemplate());
}
});
createButton.setBorder(new EmptyBorder(0, 10, 0, 10));

31
designer-chart/src/main/java/com/fr/design/mainframe/ChartPropertyPane.java

@ -9,6 +9,7 @@ import com.fr.base.chart.BaseChartCollection;
import com.fr.chart.chartattr.ChartCollection;
import com.fr.chart.charttypes.ChartTypeManager;
import com.fr.chartx.attr.ChartProvider;
import com.fr.decision.webservice.v10.map.geojson.helper.GEOJSONHelper;
import com.fr.design.ChartTypeInterfaceManager;
import com.fr.design.designer.TargetComponent;
import com.fr.design.gui.chart.BaseChartPropertyPane;
@ -19,6 +20,7 @@ import com.fr.design.utils.gui.GUICoreUtils;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.SwingWorker;
import java.awt.BorderLayout;
import java.awt.Component;
@ -95,16 +97,25 @@ public class ChartPropertyPane extends BaseChartPropertyPane {
* @param ePane 面板
*/
public void populateChartPropertyPane(ChartCollection collection, TargetComponent<?> ePane) {
String chartID = collection.getSelectedChartProvider(ChartProvider.class).getID();
updateChartEditPane(collection.getSelectedChartProvider(ChartProvider.class).getID());
setSupportCellData(true);
this.container.setEPane(ePane);
if (ChartTypeManager.getInstance().chartExit(chartID)) {
chartEditPane.populate(collection);
} else {
GUICoreUtils.setEnabled(chartEditPane, false);
}
new SwingWorker<Void, Void>() {
@Override
protected Void doInBackground() throws Exception {
GEOJSONHelper.getInstance();
return null;
}
@Override
protected void done() {
String chartID = collection.getSelectedChartProvider(ChartProvider.class).getID();
updateChartEditPane(collection.getSelectedChartProvider(ChartProvider.class).getID());
setSupportCellData(true);
container.setEPane(ePane);
if (ChartTypeManager.getInstance().chartExit(chartID)) {
chartEditPane.populate(collection);
} else {
GUICoreUtils.setEnabled(chartEditPane, false);
}
}
}.execute();
}
/**

10
designer-form/src/main/java/com/fr/design/designer/creator/XNumberEditor.java

@ -91,15 +91,15 @@ public class XNumberEditor extends XWrapperedFieldEditor {
}
}
@Override
@Override
protected JComponent initEditor() {
setBorder(FIELDBORDER);
return this;
}
@Override
protected String getIconName() {
return "number_field_16.png";
}
@Override
protected String getIconName() {
return "number_field_16.png";
}
}

4
designer-form/src/main/java/com/fr/design/fit/common/TemplateTool.java

@ -1,7 +1,7 @@
package com.fr.design.fit.common;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.file.MultiTemplateTabPane;
import com.fr.design.file.TemplateTabManager;
import com.fr.design.fit.NewJForm;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.JTemplate;
@ -86,7 +86,7 @@ public class TemplateTool {
JTemplate oldJTemplate = jTemplateList.get(i);
if (oldJTemplate != null && ComparatorUtils.equals(oldJTemplate.getEditingFILE(), newJTemplate.getEditingFILE())) {
jTemplateList.set(i, newJTemplate);
MultiTemplateTabPane.getInstance().refreshOpenedTemplate(jTemplateList);
TemplateTabManager.getInstance().refreshOpenedTemplate(jTemplateList);
return;
}
}

5
designer-form/src/main/java/com/fr/design/parameter/RootDesignDefinePane.java

@ -368,12 +368,11 @@ public class RootDesignDefinePane extends AbstractDataModify<WParameterLayout> {
wParameterLayout.setParamsFireStopEdit(fireAfterEditor.isSelected());
JTemplate jTemplate = HistoryTemplateListPane.getInstance().getCurrentEditingTemplate();
jTemplate.needAddTemplateIdAttr(useParamsTemplate.isSelected());
wParameterLayout.setBackground((Background) background.getValue());
if (extraPaneList.isEmpty()) {
background.setValue(wParameterLayout.getBackground());
wParameterLayout.setBackground((Background) background.getValue());
} else {
for (BasicBeanPane<WParameterLayout> pane : extraPaneList) {
pane.populateBean(wParameterLayout);
pane.updateBean(wParameterLayout);
}
}
//设置参数模板面板的高度

5
designer-form/src/main/java/com/fr/design/preview/DeveloperPreview.java

@ -1,7 +1,8 @@
package com.fr.design.preview;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.file.MultiTemplateTabPane;
import com.fr.design.file.TemplateTabManager;
import com.fr.design.file.TemplateTreePane;
import com.fr.design.fun.impl.AbstractPreviewProvider;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.JForm;
@ -66,7 +67,7 @@ public class DeveloperPreview extends AbstractPreviewProvider {
}
private void onPreview(JTemplate<?, ?> jt) {
MultiTemplateTabPane.getInstance().closeCurrentTpl();
TemplateTabManager.getInstance().closeCurrentTpl();
jt.generateForBiddenTemplate();
}

1
designer-form/src/main/java/com/fr/design/widget/ui/designer/mobile/ScanCodeMobileDefinePane.java

@ -10,6 +10,7 @@ import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.FormDesigner;
import com.fr.design.widget.ui.designer.mobile.component.MobileTextFieldInputSettingPane;
import com.fr.form.ui.TextEditor;
import java.awt.BorderLayout;

87
designer-form/src/main/java/com/fr/design/widget/ui/designer/mobile/component/MobileTextFieldInputSettingPane.java

@ -2,12 +2,16 @@ package com.fr.design.widget.ui.designer.mobile.component;
import com.fr.base.mobile.MobileScanCodeAttr;
import com.fr.design.beans.BasicBeanPane;
import com.fr.design.gui.ibutton.UIRadioButton;
import com.fr.design.gui.icheckbox.UICheckBox;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.VerticalFlowLayout;
import javax.swing.ButtonGroup;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import javax.swing.JPanel;
/**
* @author hades
@ -20,15 +24,28 @@ public class MobileTextFieldInputSettingPane extends BasicBeanPane<MobileScanCod
private final UICheckBox scanCodeCheckBox;
private final UICheckBox nfcInputCheckBox;
/**
* NFC内容类型面板
*/
private final NfcContentTypePane nfcContentTypePane = new NfcContentTypePane();
public MobileTextFieldInputSettingPane() {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
JPanel settingPane = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, FlowLayout.LEADING, 0, 5);
manualInputCheckBox = new UICheckBox(Toolkit.i18nText("Fine-Design_Mobile_Manual_Input"), true);
scanCodeCheckBox = new UICheckBox(Toolkit.i18nText("Fine-Design_Mobile_Scan_Code_Input"), true);
nfcInputCheckBox = new UICheckBox(Toolkit.i18nText("Fine-Design_Mobile_NFC_Input"), false);
nfcInputCheckBox.addChangeListener(e -> {
UICheckBox source = (UICheckBox) e.getSource();
// 更新面板是否可见
updateNfcContentTypePane(source.isSelected(), nfcContentTypePane.getSelectedType());
});
settingPane.add(manualInputCheckBox);
settingPane.add(scanCodeCheckBox);
settingPane.add(nfcInputCheckBox);
settingPane.add(nfcContentTypePane);
// 初始状态,内容类型面板不可见
nfcContentTypePane.setVisible(false);
this.add(settingPane, BorderLayout.NORTH);
}
@ -37,6 +54,7 @@ public class MobileTextFieldInputSettingPane extends BasicBeanPane<MobileScanCod
manualInputCheckBox.setSelected(ob.isSupportManual());
scanCodeCheckBox.setSelected(ob.isSupportScan());
nfcInputCheckBox.setSelected(ob.isSupportNFC());
updateNfcContentTypePane(ob.isSupportNFC(), ob.getNfcContentType());
}
@Override
@ -50,6 +68,18 @@ public class MobileTextFieldInputSettingPane extends BasicBeanPane<MobileScanCod
ob.setSupportManual(manualInputCheckBox.isSelected());
ob.setSupportScan(scanCodeCheckBox.isSelected());
ob.setSupportNFC(nfcInputCheckBox.isSelected());
ob.setNfcContentType(nfcContentTypePane.getSelectedType());
}
/**
* 更新NFC内容类型面板可见选项
*
* @param visible 是否可见
* @param contentType 内容类型
*/
private void updateNfcContentTypePane(boolean visible, MobileScanCodeAttr.NFCContentType contentType) {
nfcContentTypePane.setVisible(visible);
nfcContentTypePane.setSelectedType(contentType);
}
@ -58,4 +88,59 @@ public class MobileTextFieldInputSettingPane extends BasicBeanPane<MobileScanCod
return null;
}
/**
* NFC内容类型面板封装
*/
private class NfcContentTypePane extends JPanel {
/**
* 类型-卡片内容
*/
private UIRadioButton contentTypeButton;
/**
* 类型-UID
*/
private UIRadioButton uidTypeButton;
NfcContentTypePane() {
VerticalFlowLayout layout = new VerticalFlowLayout();
layout.setAlignLeft(true);
this.setLayout(layout);
contentTypeButton = new UIRadioButton(Toolkit.i18nText("Fine-Design_Mobile_NFC_Content_Type_Content"));
uidTypeButton = new UIRadioButton(Toolkit.i18nText("Fine-Design_Mobile_NFC_Content_Type_UID"));
contentTypeButton.setSelected(true);
uidTypeButton.setSelected(false);
ButtonGroup buttonGroup = new ButtonGroup();
buttonGroup.add(contentTypeButton);
buttonGroup.add(uidTypeButton);
this.add(contentTypeButton);
this.add(uidTypeButton);
}
/**
* 根据NFCContentType设置Button的选中状态
*
* @param contentType
*/
void setSelectedType(MobileScanCodeAttr.NFCContentType contentType) {
contentTypeButton.setSelected(contentType == MobileScanCodeAttr.NFCContentType.CONTENT);
uidTypeButton.setSelected(contentType == MobileScanCodeAttr.NFCContentType.UID);
}
/**
* 获取当前选中Button代表的NFCContentType
*
* @return
*/
MobileScanCodeAttr.NFCContentType getSelectedType() {
return uidTypeButton.isSelected() ?
MobileScanCodeAttr.NFCContentType.UID :
MobileScanCodeAttr.NFCContentType.CONTENT;
}
}
}

4
designer-realize/src/main/java/com/fr/design/mainframe/JWorkBook.java

@ -39,7 +39,7 @@ import com.fr.design.designer.TargetComponent;
import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.file.HistoryTemplateListPane;
import com.fr.design.file.MultiTemplateTabPane;
import com.fr.design.file.TemplateTabManager;
import com.fr.design.fun.PreviewProvider;
import com.fr.design.fun.PropertyItemPaneProvider;
import com.fr.design.fun.ReportSupportedFileUIProvider;
@ -1175,7 +1175,7 @@ public class JWorkBook extends JTemplate<WorkBook, WorkBookUndoState> {
public boolean saveShareFile() {
FILE newFile = createNewEmptyFile();
//如果文件已经打开, 那么就覆盖关闭掉他
MultiTemplateTabPane.getInstance().closeFileTemplate(newFile);
TemplateTabManager.getInstance().closeFileTemplate(newFile);
final WorkBook tpl = this.getTarget();
// 弹出输入参数
java.util.Map<String, Object> parameterMap = inputParameters(tpl);

20
designer-realize/src/main/java/com/fr/design/webattr/EventPane.java

@ -5,8 +5,11 @@ import com.fr.design.actions.UpdateAction;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.gui.icontainer.UIScrollPane;
import com.fr.design.gui.itoolbar.UIToolbar;
import com.fr.design.i18n.Toolkit;
import com.fr.design.javascript.ListenerEditPane;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.menu.MenuDef;
import com.fr.design.menu.ToolBarDef;
import com.fr.design.widget.EventCreator;
@ -238,6 +241,23 @@ public class EventPane extends BasicPane {
}
public void actionPerformed(ActionEvent e) {
JTemplate jTemplate = DesignerContext.getDesignerFrame().getSelectedJTemplate();
if (!JTemplate.isValid(jTemplate)) {
//如果当前没打开模板就跳出弹窗
Object[] options = new Object[]{Toolkit.i18nText("Fine-Design_Basic_Button_OK")};
FineJOptionPane.showOptionDialog(
EventPane.this,
Toolkit.i18nText("Fine-Design_Please_Open_Template_First"),
Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"),
JOptionPane.YES_NO_CANCEL_OPTION,
JOptionPane.WARNING_MESSAGE,
null,
options,
options[0]
);
//如果不支持就直接返回,不提供事件功能
return ;
}
String[] def = WebContent.getDefaultArg(menuName[j]);
final ListenerEditPane listenerPane = def == null ? new ListenerEditPane() : new ListenerEditPane(def);
Listener lis = new Listener(menuName[j], new JavaScriptImpl());

1
designer-realize/src/main/java/com/fr/design/widget/ui/mobile/ScanCodeMobilePane.java

@ -8,6 +8,7 @@ import com.fr.design.widget.mobile.WidgetMobilePane;
import com.fr.design.widget.ui.designer.mobile.component.MobileTextFieldInputSettingPane;
import com.fr.form.ui.TextEditor;
import com.fr.form.ui.Widget;
import java.awt.BorderLayout;

4
designer-realize/src/main/java/com/fr/start/MainDesigner.java

@ -17,6 +17,7 @@ import com.fr.design.deeplink.DeepLinkManager;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.file.HistoryTemplateListPane;
import com.fr.design.file.MultiTemplateTabPane;
import com.fr.design.file.TemplateTabManager;
import com.fr.design.fun.MenuHandler;
import com.fr.design.fun.OemProcessor;
import com.fr.design.gui.ibutton.UIButton;
@ -409,8 +410,7 @@ public class MainDesigner extends BaseDesigner {
return;
}
saveButton.setEnabled(!jt.isSaved() && !DesignModeContext.isVcsMode() && jt.checkEnable());
MultiTemplateTabPane.getInstance().refreshOpenedTemplate(HistoryTemplateListCache.getInstance().getHistoryList());
MultiTemplateTabPane.getInstance().repaint();
TemplateTabManager.getInstance().refreshOpenedTemplate(HistoryTemplateListCache.getInstance().getHistoryList());
if (DesignerEnvManager.getEnvManager().isSupportUndo()) {
undo.setEnabled(jt.canUndo());
redo.setEnabled(jt.canRedo());

Loading…
Cancel
Save