diff --git a/designer-base/src/main/java/com/fr/design/EnvChangeEntrance.java b/designer-base/src/main/java/com/fr/design/EnvChangeEntrance.java index 17d7d5883e..0a464aa6d9 100644 --- a/designer-base/src/main/java/com/fr/design/EnvChangeEntrance.java +++ b/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(); diff --git a/designer-base/src/main/java/com/fr/design/actions/file/CloseCurrentTemplateAction.java b/designer-base/src/main/java/com/fr/design/actions/file/CloseCurrentTemplateAction.java index 22263a871e..b2ab237d7d 100644 --- a/designer-base/src/main/java/com/fr/design/actions/file/CloseCurrentTemplateAction.java +++ b/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 diff --git a/designer-base/src/main/java/com/fr/design/actions/file/RenameAction.java b/designer-base/src/main/java/com/fr/design/actions/file/RenameAction.java index 842292ce2a..33f51b77aa 100644 --- a/designer-base/src/main/java/com/fr/design/actions/file/RenameAction.java +++ b/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(); } diff --git a/designer-base/src/main/java/com/fr/design/actions/file/SwitchExistEnv.java b/designer-base/src/main/java/com/fr/design/actions/file/SwitchExistEnv.java index 33761a92e2..e38a39895a 100644 --- a/designer-base/src/main/java/com/fr/design/actions/file/SwitchExistEnv.java +++ b/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); } diff --git a/designer-base/src/main/java/com/fr/design/data/BasicTableDataTreePane.java b/designer-base/src/main/java/com/fr/design/data/BasicTableDataTreePane.java index b3a076a92b..af9850172b 100644 --- a/designer-base/src/main/java/com/fr/design/data/BasicTableDataTreePane.java +++ b/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() { + @Override + protected Boolean doInBackground() throws Exception { + // 获取无权限连接名称集合 + Collection 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) { diff --git a/designer-base/src/main/java/com/fr/design/data/DesignTableDataManager.java b/designer-base/src/main/java/com/fr/design/data/DesignTableDataManager.java index 5134e88c8b..175af0653f 100644 --- a/designer-base/src/main/java/com/fr/design/data/DesignTableDataManager.java +++ b/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); diff --git a/designer-base/src/main/java/com/fr/design/file/CloseOption.java b/designer-base/src/main/java/com/fr/design/file/CloseOption.java new file mode 100644 index 0000000000..ecb70d6a5f --- /dev/null +++ b/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; + } + +} \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/file/HistoryTemplateListCache.java b/designer-base/src/main/java/com/fr/design/file/HistoryTemplateListCache.java index 86820aa227..083aa2ed08 100644 --- a/designer-base/src/main/java/com/fr/design/file/HistoryTemplateListCache.java +++ b/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> iterator = historyList.listIterator(); - + List list = new ArrayList(); + for(JTemplate jTemplate : historyList){ + list.add(jTemplate); + } + ListIterator> 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); } } diff --git a/designer-base/src/main/java/com/fr/design/file/MultiTemplateTabMenuFactory.java b/designer-base/src/main/java/com/fr/design/file/MultiTemplateTabMenuFactory.java new file mode 100644 index 0000000000..3ba3fe79eb --- /dev/null +++ b/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> openedTemplates = new ArrayList<>(); + Map>> map = TemplateTabManager.getInstance().getAllOpenedTemplateMap(); + for (Map.Entry>> 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> 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); + } + + } + +} diff --git a/designer-base/src/main/java/com/fr/design/file/MultiTemplateTabPane.java b/designer-base/src/main/java/com/fr/design/file/MultiTemplateTabPane.java index 8e302fd977..0292bb8f95 100644 --- a/designer-base/src/main/java/com/fr/design/file/MultiTemplateTabPane.java +++ b/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 *

@@ -114,10 +92,6 @@ public class MultiTemplateTabPane extends JComponent { private static MultiTemplateTabPane THIS; - //用于存放工作簿 - private java.util.List> 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> 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); } diff --git a/designer-base/src/main/java/com/fr/design/file/MutilTempalteTabPane.java b/designer-base/src/main/java/com/fr/design/file/MutilTempalteTabPane.java index 36e0b58754..d92533552c 100644 --- a/designer-base/src/main/java/com/fr/design/file/MutilTempalteTabPane.java +++ b/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); } } diff --git a/designer-base/src/main/java/com/fr/design/file/NewTemplatePane.java b/designer-base/src/main/java/com/fr/design/file/NewTemplatePane.java index dae921a1c8..9949888349 100644 --- a/designer-base/src/main/java/com/fr/design/file/NewTemplatePane.java +++ b/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 事件 diff --git a/designer-base/src/main/java/com/fr/design/file/SaveSomeTemplatePane.java b/designer-base/src/main/java/com/fr/design/file/SaveSomeTemplatePane.java index 72945b31c9..c83c5ca800 100644 --- a/designer-base/src/main/java/com/fr/design/file/SaveSomeTemplatePane.java +++ b/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> 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> opendedTemplate = HistoryTemplateListPane.getInstance().getHistoryList(); + populate(HistoryTemplateListPane.getInstance().getHistoryList()); + } + + private void populate(java.util.List> opendedTemplate) { JTemplate currentTemplate = HistoryTemplateListPane.getInstance().getCurrentEditingTemplate(); for (int i = 0; i < opendedTemplate.size(); i++) { if (isneedToAdd(opendedTemplate.get(i), currentTemplate)) { diff --git a/designer-base/src/main/java/com/fr/design/file/TemplateTabManager.java b/designer-base/src/main/java/com/fr/design/file/TemplateTabManager.java new file mode 100644 index 0000000000..fe294f222f --- /dev/null +++ b/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 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> 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>> getAllOpenedTemplateMap() { + Map>> 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(); + } + +} diff --git a/designer-base/src/main/java/com/fr/design/file/TemplateTabOperateProvider.java b/designer-base/src/main/java/com/fr/design/file/TemplateTabOperateProvider.java new file mode 100644 index 0000000000..a9a317a8b4 --- /dev/null +++ b/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> 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> 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(); +} diff --git a/designer-base/src/main/java/com/fr/design/file/impl/AbstractTemplateTabOperate.java b/designer-base/src/main/java/com/fr/design/file/impl/AbstractTemplateTabOperate.java new file mode 100644 index 0000000000..3f67fb69b2 --- /dev/null +++ b/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> 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> list) { + List> result = new ArrayList<>(); + for (JTemplate jTemplate : list) { + if (this.accept(jTemplate.getTemplateTabOperatorType())) { + result.add(jTemplate); + } + } + this.openedTemplate = result; + TemplateTabManager.getInstance().refresh(); + } + + public List> 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; + } + +} diff --git a/designer-base/src/main/java/com/fr/design/file/impl/DefaultTemplateTabOperate.java b/designer-base/src/main/java/com/fr/design/file/impl/DefaultTemplateTabOperate.java new file mode 100644 index 0000000000..90853568dd --- /dev/null +++ b/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; + } + +} diff --git a/designer-base/src/main/java/com/fr/design/file/impl/EmptyTemplateTabOperate.java b/designer-base/src/main/java/com/fr/design/file/impl/EmptyTemplateTabOperate.java new file mode 100644 index 0000000000..c35a4bf655 --- /dev/null +++ b/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> 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> 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() { + + } +} diff --git a/designer-base/src/main/java/com/fr/design/gui/controlpane/UIListGroupControlPane.java b/designer-base/src/main/java/com/fr/design/gui/controlpane/UIListGroupControlPane.java index ed07ecc2d5..47581fb626 100644 --- a/designer-base/src/main/java/com/fr/design/gui/controlpane/UIListGroupControlPane.java +++ b/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> 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 entry = iterator.next(); ListWrapperPane wrapperPane = entry.getValue(); diff --git a/designer-base/src/main/java/com/fr/design/javascript/JSContentWithDescriptionPane.java b/designer-base/src/main/java/com/fr/design/javascript/JSContentWithDescriptionPane.java index e204a3342b..3b8d04ffb3 100644 --- a/designer-base/src/main/java/com/fr/design/javascript/JSContentWithDescriptionPane.java +++ b/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, Void>() { + @Override + protected List doInBackground() { + List helpDocuments = new ArrayList<>(); + updateHelpDocuments(value, helpDocuments); + return helpDocuments; + } + + @Override + protected void done() { + try { + List 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 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); } } diff --git a/designer-base/src/main/java/com/fr/design/locale/impl/VideoMark.java b/designer-base/src/main/java/com/fr/design/locale/impl/VideoMark.java index 2521c82c23..571c5e02e9 100644 --- a/designer-base/src/main/java/com/fr/design/locale/impl/VideoMark.java +++ b/designer-base/src/main/java/com/fr/design/locale/impl/VideoMark.java @@ -16,7 +16,7 @@ public class VideoMark implements LocaleMark { private Map 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() { diff --git a/designer-base/src/main/java/com/fr/design/mainframe/CenterRegionContainerPane.java b/designer-base/src/main/java/com/fr/design/mainframe/CenterRegionContainerPane.java index b18b346525..63c00deaaf 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/CenterRegionContainerPane.java +++ b/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); diff --git a/designer-base/src/main/java/com/fr/design/mainframe/DefaultToolKitConfig.java b/designer-base/src/main/java/com/fr/design/mainframe/DefaultToolKitConfig.java index 305c44aa21..581dc54cb8 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/DefaultToolKitConfig.java +++ b/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; + } } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java b/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java index e88d0c946c..8b63b73e96 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java +++ b/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); diff --git a/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrameFileDealerPane.java b/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrameFileDealerPane.java index 8cfd263421..80fccc95cb 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrameFileDealerPane.java +++ b/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; } } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java b/designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java index 0082e091f3..3ede09d5ec 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java +++ b/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> * @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> if (!editingFILE.exists()) { return saveAs(showLoc); } - - CallbackSaveWorker worker = new CallbackSaveWorker(new Callable() { - @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> } } + + private CallbackSaveWorker saveAs(boolean showLoc) { FILE editingFILE = this.getEditingFILE(); if (editingFILE == null) { @@ -1771,7 +1759,6 @@ public abstract class JTemplate> // 目标文件 editingFILE = fileChooser.getSelectedFILE(); } - FILE finalEditingFILE = editingFILE; CallbackSaveWorker worker = new CallbackSaveWorker(new Callable() { @Override @@ -1872,10 +1859,95 @@ public abstract class JTemplate> return saveAs(true); } + /** + * 获取保存用到的saveWorker + */ + private CallbackSaveWorker getSaveCallBackSaveWorker() { + CallbackSaveWorker worker = new CallbackSaveWorker(new Callable() { + @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 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> public void setDesignerUIMode() { DesignerUIModeConfig.getInstance().setAbsoluteMeasureUIMode(); } - + + public String getTemplateTabOperatorType(){ + return DefaultTemplateTabOperate.OPERATOR_TYPE; + } + /** * 判断当前的模板是否是有效的模板 * @@ -1989,4 +2065,21 @@ public abstract class JTemplate> public static boolean isValid(JTemplate jt) { return jt != null && jt != JNullTemplate.NULL; } + + /** + * 当前模板是否可以被保存 + * @return 是/否 + */ + public boolean canBeSaved(){ + return true; + } + + /** + * 当前的模板是否支持缓存 + * + * @return 是/否 + */ + public boolean supportCache(){ + return true; + } } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/ToolKitConfigStrategy.java b/designer-base/src/main/java/com/fr/design/mainframe/ToolKitConfigStrategy.java index 67b1409b36..f2feff8042 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/ToolKitConfigStrategy.java +++ b/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); } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/toolbar/ToolBarMenuDock.java b/designer-base/src/main/java/com/fr/design/mainframe/toolbar/ToolBarMenuDock.java index 3c75eff39d..37812c106f 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/toolbar/ToolBarMenuDock.java +++ b/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)) { diff --git a/designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/FileVersionCellEditor.java b/designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/FileVersionCellEditor.java index 8cff3ffbb1..6bfc39b78e 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/FileVersionCellEditor.java +++ b/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中的模板 diff --git a/designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/FileVersionsPanel.java b/designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/FileVersionsPanel.java index 4dd14bce6d..47a95f2620 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/FileVersionsPanel.java +++ b/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); diff --git a/designer-base/src/main/java/com/fr/design/worker/open/OpenWorker.java b/designer-base/src/main/java/com/fr/design/worker/open/OpenWorker.java index d9c8568bf9..baa73fc53a 100644 --- a/designer-base/src/main/java/com/fr/design/worker/open/OpenWorker.java +++ b/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 extends SwingWorker { 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); } diff --git a/designer-base/src/main/java/com/fr/design/worker/save/SaveWorker.java b/designer-base/src/main/java/com/fr/design/worker/save/SaveWorker.java index 60d797c3e9..83b7c50d49 100644 --- a/designer-base/src/main/java/com/fr/design/worker/save/SaveWorker.java +++ b/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 { private boolean slowly; + public boolean isSlowly() { + return slowly; + } + + public void setSlowly(boolean slowly) { + this.slowly = slowly; + } + public SaveWorker(Callable callable, JTemplate template) { this.callable = callable; this.template = template; @@ -47,10 +59,11 @@ public class SaveWorker extends SwingWorker { @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 { // 恢复界面 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 { 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; + } + } + }); } } diff --git a/designer-base/src/main/java/com/fr/design/worker/save/type/SaveType.java b/designer-base/src/main/java/com/fr/design/worker/save/type/SaveType.java new file mode 100644 index 0000000000..63cf6c4c7e --- /dev/null +++ b/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; + } + +} diff --git a/designer-base/src/main/java/com/fr/design/worker/save/type/SaveTypeWorker.java b/designer-base/src/main/java/com/fr/design/worker/save/type/SaveTypeWorker.java new file mode 100644 index 0000000000..d415537eb4 --- /dev/null +++ b/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 { + + public static final ExecutorService SAVE_TYPE_POOL = FineExecutors.newSingleThreadExecutor(); + + private final Callable callable; + + private static final int TIME_OUT = 400; + + private final JTemplate template; + + private final SaveType saveType; + + + + public SaveTypeWorker(Callable 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; + } + } + }); + } +} diff --git a/designer-base/src/main/java/com/fr/nx/app/designer/toolbar/TemplateTransformer.java b/designer-base/src/main/java/com/fr/nx/app/designer/toolbar/TemplateTransformer.java index 1a6e2bf1c8..f277320dd0 100644 --- a/designer-base/src/main/java/com/fr/nx/app/designer/toolbar/TemplateTransformer.java +++ b/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); } diff --git a/designer-base/src/main/java/com/fr/start/BaseDesigner.java b/designer-base/src/main/java/com/fr/start/BaseDesigner.java index 44228c2a4a..50f2cd35c0 100644 --- a/designer-base/src/main/java/com/fr/start/BaseDesigner.java +++ b/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; } diff --git a/designer-base/src/main/java/com/fr/start/common/DesignerOpenEmptyPanel.java b/designer-base/src/main/java/com/fr/start/common/DesignerOpenEmptyPanel.java index b42cc4ed8f..5dcaa147ac 100644 --- a/designer-base/src/main/java/com/fr/start/common/DesignerOpenEmptyPanel.java +++ b/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)); diff --git a/designer-chart/src/main/java/com/fr/design/mainframe/ChartPropertyPane.java b/designer-chart/src/main/java/com/fr/design/mainframe/ChartPropertyPane.java index 4efe977ff3..8e6b80c53a 100644 --- a/designer-chart/src/main/java/com/fr/design/mainframe/ChartPropertyPane.java +++ b/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() { + @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(); } /** diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XNumberEditor.java b/designer-form/src/main/java/com/fr/design/designer/creator/XNumberEditor.java index 15cd30c6fd..fc359976e2 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XNumberEditor.java +++ b/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"; + } } diff --git a/designer-form/src/main/java/com/fr/design/fit/common/TemplateTool.java b/designer-form/src/main/java/com/fr/design/fit/common/TemplateTool.java index 04633435be..c362ae76d1 100644 --- a/designer-form/src/main/java/com/fr/design/fit/common/TemplateTool.java +++ b/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; } } diff --git a/designer-form/src/main/java/com/fr/design/preview/DeveloperPreview.java b/designer-form/src/main/java/com/fr/design/preview/DeveloperPreview.java index 4afacee781..03e8e2b445 100644 --- a/designer-form/src/main/java/com/fr/design/preview/DeveloperPreview.java +++ b/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(); } diff --git a/designer-form/src/main/java/com/fr/design/widget/ui/designer/mobile/ScanCodeMobileDefinePane.java b/designer-form/src/main/java/com/fr/design/widget/ui/designer/mobile/ScanCodeMobileDefinePane.java index a9876b7a3d..71c35574a3 100644 --- a/designer-form/src/main/java/com/fr/design/widget/ui/designer/mobile/ScanCodeMobileDefinePane.java +++ b/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; diff --git a/designer-form/src/main/java/com/fr/design/widget/ui/designer/mobile/component/MobileTextFieldInputSettingPane.java b/designer-form/src/main/java/com/fr/design/widget/ui/designer/mobile/component/MobileTextFieldInputSettingPane.java index 75d924e53a..fb9daa30f3 100644 --- a/designer-form/src/main/java/com/fr/design/widget/ui/designer/mobile/component/MobileTextFieldInputSettingPane.java +++ b/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 { + 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 { public boolean saveShareFile() { FILE newFile = createNewEmptyFile(); //如果文件已经打开, 那么就覆盖关闭掉他 - MultiTemplateTabPane.getInstance().closeFileTemplate(newFile); + TemplateTabManager.getInstance().closeFileTemplate(newFile); final WorkBook tpl = this.getTarget(); // 弹出输入参数 java.util.Map parameterMap = inputParameters(tpl); diff --git a/designer-realize/src/main/java/com/fr/design/webattr/EventPane.java b/designer-realize/src/main/java/com/fr/design/webattr/EventPane.java index 8c11bc5929..347d942834 100644 --- a/designer-realize/src/main/java/com/fr/design/webattr/EventPane.java +++ b/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()); diff --git a/designer-realize/src/main/java/com/fr/design/widget/ui/mobile/ScanCodeMobilePane.java b/designer-realize/src/main/java/com/fr/design/widget/ui/mobile/ScanCodeMobilePane.java index 6f9b379067..8dbe096d70 100644 --- a/designer-realize/src/main/java/com/fr/design/widget/ui/mobile/ScanCodeMobilePane.java +++ b/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; diff --git a/designer-realize/src/main/java/com/fr/start/MainDesigner.java b/designer-realize/src/main/java/com/fr/start/MainDesigner.java index 7b974d871c..55b6548ac5 100644 --- a/designer-realize/src/main/java/com/fr/start/MainDesigner.java +++ b/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());