diff --git a/designer-base/src/main/java/com/fr/base/svg/SVGIcon.java b/designer-base/src/main/java/com/fr/base/svg/SVGIcon.java index aebb22ae1..9667895ee 100644 --- a/designer-base/src/main/java/com/fr/base/svg/SVGIcon.java +++ b/designer-base/src/main/java/com/fr/base/svg/SVGIcon.java @@ -7,6 +7,8 @@ import java.awt.Component; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.image.BufferedImage; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; /** * SVG转化而来的Icon @@ -28,6 +30,8 @@ public class SVGIcon implements Icon { this.image = image; } + private static Map iconCache = new ConcurrentHashMap<>(); + @Override public void paintIcon(Component c, Graphics g, int x, int y) { if (HI_DPI_SURPORT) { @@ -58,11 +62,26 @@ public class SVGIcon implements Icon { * @return */ public static Icon readSVGIcon(String url) { - if (!url.startsWith(ICON_PREFIX)) { - url = ICON_PREFIX + url; + return readSVGIconWithCache(url, true); + } + + public static Icon readSVGIconWithCache(String url, boolean cacheRead) { + Icon icon = null; + if (cacheRead) { + icon = iconCache.get(url); } - BufferedImage image = (BufferedImage) SVGLoader.load(url); - return image == null ? IOUtils.readIcon(url) : new SVGIcon(image); + if (icon == null) { + if (!url.startsWith(ICON_PREFIX)) { + url = ICON_PREFIX + url; + } + BufferedImage image = (BufferedImage) SVGLoader.load(url); + icon = image == null ? IOUtils.readIcon(url) : new SVGIcon(image); + //只缓存svg图标 + if (image != null){ + iconCache.put(url, icon); + } + } + return icon; } /** diff --git a/designer-base/src/main/java/com/fr/design/DesignModelAdapter.java b/designer-base/src/main/java/com/fr/design/DesignModelAdapter.java index e5930ee91..ed8f2208e 100644 --- a/designer-base/src/main/java/com/fr/design/DesignModelAdapter.java +++ b/designer-base/src/main/java/com/fr/design/DesignModelAdapter.java @@ -21,6 +21,8 @@ import com.fr.stable.StringUtils; import com.fr.stable.js.WidgetName; import com.fr.util.ParameterApplyHelper; +import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -73,6 +75,12 @@ public abstract class DesignModelAdapter model) { currentModelAdapter = model; } @@ -242,6 +250,16 @@ public abstract class DesignModelAdapter map, Filter filter) { + // 兼容下通过老数据集参数获取 + tableDataParameters = getLatestTableDataParameters(); + + // 处理初始化添加 + if (tableDataParametersMap.isEmpty()) { + addTableDataParameters(map, filter); + return; + } + ParameterProvider[] providers = null; if (!ComparatorUtils.equals(oldName, tdName)) { @@ -303,13 +330,13 @@ public abstract class DesignModelAdapter map, ParameterProvider[] parameterProviders, Filter filter) { + if (filter != null) { + ParameterApplyHelper.addPara2Map(map, parameterProviders, filter); + } else { + ParameterApplyHelper.addPara2Map(map, parameterProviders); + } + } + + public void removeTableDataParameters(String tdName) { + ParameterProvider[] tableDataParameters = tableDataParametersMap.remove(tdName); + List allParameterList = new ArrayList<>(Arrays.asList(parameters)); + List tableDataParameterList = new ArrayList<>(); + for (ParameterProvider parameterProvider : tableDataParameters) { + tableDataParameterList.add((Parameter) parameterProvider); + } + allParameterList.removeAll(tableDataParameterList); + parameters = allParameterList.toArray(new Parameter[0]); + } + + + public void updateAllParameters() { + parameters = getLatestParameters(); + } + protected void addGlobalParameters(Map map) { // 添加全局参数 Parameter[] glbParas = ParameterConfig.getInstance().getGlobalParameters(); diff --git a/designer-base/src/main/java/com/fr/design/DesignerEnvManager.java b/designer-base/src/main/java/com/fr/design/DesignerEnvManager.java index b8951ea8b..011f92140 100644 --- a/designer-base/src/main/java/com/fr/design/DesignerEnvManager.java +++ b/designer-base/src/main/java/com/fr/design/DesignerEnvManager.java @@ -18,6 +18,7 @@ import com.fr.design.file.HistoryTemplateListPane; import com.fr.design.fun.DesignerPortProvider; import com.fr.design.i18n.Toolkit; import com.fr.design.locale.impl.ProductImproveMark; +import com.fr.design.mainframe.reuse.ComponentReuseNotificationInfo; import com.fr.design.mainframe.vcs.VcsConfigManager; import com.fr.design.notification.SnapChatConfig; import com.fr.design.port.DesignerPortContext; @@ -196,6 +197,8 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter { // 开启内嵌web页面的调试窗口 private boolean openDebug = false; + private ComponentReuseNotificationInfo notificationInfo = ComponentReuseNotificationInfo.getInstance(); + /** * DesignerEnvManager. */ @@ -1561,13 +1564,15 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter { readRecentColor(reader); } else if ("OpenDebug".equals(name)) { readOpenDebug(reader); + } else if (name.equals(ComponentReuseNotificationInfo.XML_TAG)) { + readComponentReuseNotificationInfo(reader); } else if (name.equals(DesignerPushUpdateConfigManager.XML_TAG)) { readDesignerPushUpdateAttr(reader); } else if (name.equals(vcsConfigManager.XML_TAG)) { readVcsAttr(reader); } else if (DesignerPort.XML_TAG.equals(name)) { readDesignerPort(reader); - }else if (name.equals(SnapChatConfig.XML_TAG)) { + } else if (name.equals(SnapChatConfig.XML_TAG)) { readSnapChatConfig(reader); } else { readLayout(reader, name); @@ -1575,6 +1580,11 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter { } } + private void readComponentReuseNotificationInfo(XMLableReader reader){ + reader.readXMLObject(this.notificationInfo); + + } + private void readSnapChatConfig(XMLableReader reader) { reader.readXMLObject(this.snapChatConfig = SnapChatConfig.getInstance()); } @@ -1795,9 +1805,16 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter { writeVcsAttr(writer); writeDesignerPort(writer); writeSnapChatConfig(writer); + writeComponentReuseNotificationInfo(writer); writer.end(); } + private void writeComponentReuseNotificationInfo(XMLPrintWriter writer) { + if (this.notificationInfo != null) { + this.notificationInfo.writeXML(writer); + } + } + private void writeSnapChatConfig(XMLPrintWriter writer) { if (this.snapChatConfig != null) { 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 c8078777d..5196c783a 100644 --- a/designer-base/src/main/java/com/fr/design/EnvChangeEntrance.java +++ b/designer-base/src/main/java/com/fr/design/EnvChangeEntrance.java @@ -117,7 +117,7 @@ public class EnvChangeEntrance { @Override public void show() { FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Design_Basic_Switch_Workspace_Failed"), - com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Error"), ERROR_MESSAGE, UIManager.getIcon("OptionPane.errorIcon")); + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"), ERROR_MESSAGE, UIManager.getIcon("OptionPane.errorIcon")); } }); return false; @@ -155,7 +155,7 @@ public class EnvChangeEntrance { public void show() { FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Design_Basic_Switch_Workspace_Failed"), - Toolkit.i18nText("Fine-Design_Basic_Error"), + Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"), ERROR_MESSAGE, UIManager.getIcon("OptionPane.errorIcon")); } @@ -171,7 +171,7 @@ public class EnvChangeEntrance { FineLoggerFactory.getLogger().error(exception.getMessage(), exception); strategy.showTip(() -> FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Design_Basic_Switch_Workspace_Failed"), - Toolkit.i18nText("Fine-Design_Basic_Error"), + Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"), ERROR_MESSAGE, UIManager.getIcon("OptionPane.errorIcon"))); } @@ -191,7 +191,7 @@ public class EnvChangeEntrance { if (ComparatorUtils.equals(result, TestConnectionResult.AUTH_FAILED)) { strategy.showTip(() -> FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Design_Basic_Switch_Workspace_Failed"), - Toolkit.i18nText("Fine-Design_Basic_Error"), + Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"), ERROR_MESSAGE, UIManager.getIcon("OptionPane.errorIcon"))); } else { @@ -553,4 +553,14 @@ public class EnvChangeEntrance { interface PopTip { void show(); } + + private static class SuccessPopTip implements PopTip { + @Override + public void show() { + FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), + Toolkit.i18nText("Fine-Design_Basic_Switch_Workspace_Success"), + Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"), + FineJOptionPane.INFORMATION_MESSAGE); + } + } } diff --git a/designer-base/src/main/java/com/fr/design/actions/ForbiddenUpdateAction.java b/designer-base/src/main/java/com/fr/design/actions/ForbiddenUpdateAction.java new file mode 100644 index 000000000..9b12ba65f --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/actions/ForbiddenUpdateAction.java @@ -0,0 +1,26 @@ +package com.fr.design.actions; + +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.ibutton.UIForbiddenButton; +import javax.swing.AbstractButton; +import javax.swing.JComponent; + +/** + * @author hades + * @version 10.0 + * Created by hades on 2021/4/12 + */ +public abstract class ForbiddenUpdateAction extends UpdateAction { + + @Override + public JComponent createToolBarComponent() { + Object object = this.getValue(UIForbiddenButton.class.getName()); + if (!(object instanceof AbstractButton)) { + UIButton button = null; + button = new UIForbiddenButton(); + object = initButton(button, UIForbiddenButton.class.getName()); + } + + return (JComponent) object; + } +} diff --git a/designer-base/src/main/java/com/fr/design/actions/TableDataSourceAction.java b/designer-base/src/main/java/com/fr/design/actions/TableDataSourceAction.java index 2903b12a1..8a6e7a7df 100644 --- a/designer-base/src/main/java/com/fr/design/actions/TableDataSourceAction.java +++ b/designer-base/src/main/java/com/fr/design/actions/TableDataSourceAction.java @@ -60,6 +60,7 @@ public class TableDataSourceAction extends TemplateComponentAction undoComponent = getEditingComponent(); if (DesignerEnvManager.getEnvManager().isSupportUndo()) { - this.setEnabled(undoComponent != null && undoComponent.canRedo()); + boolean enable = undoComponent != null && undoComponent.canRedo() && undoComponent.checkEnable(); + this.setEnabled(enable); } else { this.setEnabled(false); } diff --git a/designer-base/src/main/java/com/fr/design/actions/edit/UndoAction.java b/designer-base/src/main/java/com/fr/design/actions/edit/UndoAction.java index ff337620c..d8ed5b9da 100644 --- a/designer-base/src/main/java/com/fr/design/actions/edit/UndoAction.java +++ b/designer-base/src/main/java/com/fr/design/actions/edit/UndoAction.java @@ -28,7 +28,7 @@ public class UndoAction extends UpdateAction implements TemplateComponentActionI @Override public JTemplate getEditingComponent() { - return t; + return t; } /** @@ -49,7 +49,8 @@ public class UndoAction extends UpdateAction implements TemplateComponentActionI public void update() { JTemplate undoComponent = getEditingComponent(); if (DesignerEnvManager.getEnvManager().isSupportUndo()) { - this.setEnabled(undoComponent != null && undoComponent.canUndo()); + boolean enable = undoComponent != null && undoComponent.canUndo() && undoComponent.checkEnable(); + this.setEnabled(enable); } else { this.setEnabled(false); } 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 9e8be9f51..58fe5666a 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 @@ -1 +1,44 @@ -package com.fr.design.actions.file; import com.fr.design.actions.UpdateAction; import com.fr.design.file.HistoryTemplateListPane; import com.fr.design.file.MutilTempalteTabPane; import com.fr.design.menu.KeySetUtils; import java.awt.event.ActionEvent; /** * Author : daisy * Date: 13-8-16 * Time: 下午3:23 */ public class CloseCurrentTemplateAction extends UpdateAction { public CloseCurrentTemplateAction() { this.setMenuKeySet(KeySetUtils.CLOSE_CURRENT_TEMPLATE); this.setName(getMenuKeySet().getMenuKeySetName()); this.setMnemonic(getMenuKeySet().getMnemonic()); this.setAccelerator(getMenuKeySet().getKeyStroke()); } /** * 动作 * @param e 事件 */ public void actionPerformed(ActionEvent e) { MutilTempalteTabPane.getInstance().setIsCloseCurrent(true); MutilTempalteTabPane.getInstance().closeFormat(HistoryTemplateListPane.getInstance().getCurrentEditingTemplate()); MutilTempalteTabPane.getInstance().closeSpecifiedTemplate(HistoryTemplateListPane.getInstance().getCurrentEditingTemplate()); } } \ No newline at end of file +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.MutilTempalteTabPane; +import com.fr.design.mainframe.JTemplate; +import com.fr.design.menu.KeySetUtils; + +import java.awt.event.ActionEvent; + +/** + * Author : daisy + * Date: 13-8-16 + * Time: 下午3:23 + */ +public class CloseCurrentTemplateAction extends UpdateAction { + + public CloseCurrentTemplateAction() { + this.setMenuKeySet(KeySetUtils.CLOSE_CURRENT_TEMPLATE); + this.setName(getMenuKeySet().getMenuKeySetName()); + this.setMnemonic(getMenuKeySet().getMnemonic()); + this.setAccelerator(getMenuKeySet().getKeyStroke()); + } + + /** + * 动作 + * @param e 事件 + */ + public void actionPerformed(ActionEvent e) { + MutilTempalteTabPane.getInstance().setIsCloseCurrent(true); + MutilTempalteTabPane.getInstance().closeFormat(HistoryTemplateListPane.getInstance().getCurrentEditingTemplate()); + MutilTempalteTabPane.getInstance().closeSpecifiedTemplate(HistoryTemplateListPane.getInstance().getCurrentEditingTemplate()); + } + + @Override + public void update() { + super.update(); + JTemplate template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + if (template != null) { + this.setEnabled(!template.isSaving()); + } + } +} \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/actions/file/EditEnvAction.java b/designer-base/src/main/java/com/fr/design/actions/file/EditEnvAction.java index a4b7c8803..d007e315f 100644 --- a/designer-base/src/main/java/com/fr/design/actions/file/EditEnvAction.java +++ b/designer-base/src/main/java/com/fr/design/actions/file/EditEnvAction.java @@ -3,6 +3,8 @@ package com.fr.design.actions.file; import com.fr.design.EnvChangeEntrance; import com.fr.design.actions.UpdateAction; +import com.fr.design.file.HistoryTemplateListCache; +import com.fr.design.mainframe.JTemplate; import java.awt.event.ActionEvent; @@ -17,4 +19,13 @@ public class EditEnvAction extends UpdateAction { public void actionPerformed(ActionEvent e) { EnvChangeEntrance.getInstance().chooseEnv(); } + + @Override + public void update() { + super.update(); + JTemplate template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + if (template != null) { + this.setEnabled(!template.isSaving()); + } + } } \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/actions/file/ExitDesignerAction.java b/designer-base/src/main/java/com/fr/design/actions/file/ExitDesignerAction.java index 070b9df22..1ca29a042 100644 --- a/designer-base/src/main/java/com/fr/design/actions/file/ExitDesignerAction.java +++ b/designer-base/src/main/java/com/fr/design/actions/file/ExitDesignerAction.java @@ -3,6 +3,7 @@ */ package com.fr.design.actions.file; +import com.fr.design.mainframe.TemplateSavingChecker; import java.awt.event.ActionEvent; import com.fr.design.actions.UpdateAction; @@ -27,6 +28,9 @@ public class ExitDesignerAction extends UpdateAction { * @param e 事件 */ public void actionPerformed(ActionEvent e) { + if (!TemplateSavingChecker.check()) { + return; + } DesignerContext.getDesignerFrame().exit(); } } \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/actions/file/SaveAsTemplateAction.java b/designer-base/src/main/java/com/fr/design/actions/file/SaveAsTemplateAction.java index a60b39762..b957e1563 100644 --- a/designer-base/src/main/java/com/fr/design/actions/file/SaveAsTemplateAction.java +++ b/designer-base/src/main/java/com/fr/design/actions/file/SaveAsTemplateAction.java @@ -31,7 +31,7 @@ public class SaveAsTemplateAction extends JTemplateAction> { JTemplate jt = this.getEditingComponent(); // kunsnat: 保存前停止编辑状态,保存属性. jt.stopEditing(); - jt.saveAsTemplate(); + jt.saveAsDirectly(); this.setEnabled(true); jt.requestFocus(); @@ -40,9 +40,6 @@ public class SaveAsTemplateAction extends JTemplateAction> { @Override public void update() { super.update(); - -// this.setEnabled(!this.getEditingComponent().isSaved()); -// 另存为按钮应该一直可用使用 - this.setEnabled(true); + this.setEnabled(this.getEditingComponent().checkEnable()); } } diff --git a/designer-base/src/main/java/com/fr/design/actions/file/SaveTemplateAction.java b/designer-base/src/main/java/com/fr/design/actions/file/SaveTemplateAction.java index 920f5b41a..072a127aa 100644 --- a/designer-base/src/main/java/com/fr/design/actions/file/SaveTemplateAction.java +++ b/designer-base/src/main/java/com/fr/design/actions/file/SaveTemplateAction.java @@ -31,14 +31,15 @@ public class SaveTemplateAction extends JTemplateAction> { public void actionPerformed(ActionEvent e) { JTemplate jt = this.getEditingComponent(); jt.stopEditing(); - jt.saveTemplate(); + jt.saveDirectly(); jt.requestFocus(); } @Override public void update() { super.update(); - this.setEnabled(!this.getEditingComponent().isSaved()); + boolean enable = !this.getEditingComponent().isSaved() && this.getEditingComponent().checkEnable(); + this.setEnabled(enable); } } 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 bc88f72fd..c59a92b97 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 @@ -1,10 +1,11 @@ package com.fr.design.actions.file; -import com.fr.base.svg.IconUtils; import com.fr.design.DesignerEnvManager; import com.fr.design.EnvChangeEntrance; import com.fr.design.actions.UpdateAction; import com.fr.design.env.DesignerWorkspaceInfo; +import com.fr.design.file.HistoryTemplateListCache; +import com.fr.design.mainframe.JTemplate; import com.fr.design.menu.KeySetUtils; import com.fr.design.menu.MenuDef; import com.fr.design.menu.SeparatorDef; @@ -68,5 +69,14 @@ public class SwitchExistEnv extends MenuDef { EnvChangeEntrance.getInstance().switch2Env(envName); } } + + @Override + public void update() { + super.update(); + JTemplate template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + if (template != null) { + this.setEnabled(!template.isSaving()); + } + } } } diff --git a/designer-base/src/main/java/com/fr/design/actions/file/WebPreviewUtils.java b/designer-base/src/main/java/com/fr/design/actions/file/WebPreviewUtils.java index 8d1e5828d..8f8d4ae13 100644 --- a/designer-base/src/main/java/com/fr/design/actions/file/WebPreviewUtils.java +++ b/designer-base/src/main/java/com/fr/design/actions/file/WebPreviewUtils.java @@ -6,6 +6,7 @@ import com.fr.design.i18n.Toolkit; import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.JTemplate; import com.fr.design.utils.DesignUtils; +import com.fr.design.worker.save.CallbackSaveWorker; import com.fr.file.FILE; import com.fr.file.FileNodeFILE; import com.fr.general.GeneralUtils; @@ -67,9 +68,21 @@ public final class WebPreviewUtils { * * 如果保存失败,不执行下面的WebPreview */ - if (!jt.isSaved() && !jt.saveTemplate2Env()) { + if (!jt.isSaved()) { + CallbackSaveWorker worker = jt.save2Env(); + worker.addSuccessCallback(new Runnable() { + @Override + public void run() { + browserTemplate(jt, baseRoute, map, actionType); + } + }); + worker.start(jt.getTarget().getTemplateID()); return; } + browserTemplate(jt, baseRoute, map, actionType); + } + + private static void browserTemplate(JTemplate jt, String baseRoute, Map map, String actionType) { FILE currentTemplate = jt.getEditingFILE(); // carl:是否是保存在运行环境下的模板,不是就不能被预览 if (currentTemplate instanceof FileNodeFILE) { @@ -83,13 +96,18 @@ public final class WebPreviewUtils { WARNING_MESSAGE ); if (OK_OPTION == selVal) { - if (!jt.saveAsTemplate()) { - return; - } + CallbackSaveWorker worker = jt.saveAs(); + worker.start(jt.getTarget().getTemplateID()); + worker.addSuccessCallback(new Runnable() { + @Override + public void run() { + browseUrl(jt.getEditingFILE(), baseRoute, map, actionType, jt); + } + }); } - currentTemplate = jt.getEditingFILE(); + return; } - browseUrl(currentTemplate, baseRoute, map, actionType, jt); + browseUrl(jt.getEditingFILE(), baseRoute, map, actionType, jt); } else { // 说明模板没有保存在报表运行环境下面,提示用户 int selVal = showConfirmDialog( @@ -100,11 +118,14 @@ public final class WebPreviewUtils { WARNING_MESSAGE); if (OK_OPTION == selVal) { - if (!jt.saveAsTemplate2Env()) { - return; - } - currentTemplate = jt.getEditingFILE(); - browseUrl(currentTemplate, baseRoute, map, actionType, jt); + CallbackSaveWorker worker = jt.saveAs2Env(); + worker.addSuccessCallback(new Runnable() { + @Override + public void run() { + browseUrl(jt.getEditingFILE(), baseRoute, map, actionType, jt); + } + }); + worker.start(jt.getTarget().getTemplateID()); } } } @@ -148,7 +169,7 @@ public final class WebPreviewUtils { WARNING_MESSAGE ); if (OK_OPTION == selVal) { - jt.saveAsTemplate(); + jt.saveAsDirectly(); } } } diff --git a/designer-base/src/main/java/com/fr/design/actions/file/export/AbstractExportAction.java b/designer-base/src/main/java/com/fr/design/actions/file/export/AbstractExportAction.java index 5277d2ebf..094915a85 100644 --- a/designer-base/src/main/java/com/fr/design/actions/file/export/AbstractExportAction.java +++ b/designer-base/src/main/java/com/fr/design/actions/file/export/AbstractExportAction.java @@ -226,4 +226,10 @@ public abstract class AbstractExportAction> extends JT } } + @Override + public void update() { + super.update(); + this.setEnabled(this.getEditingComponent().checkEnable()); + } + } 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 34482d0d2..b0997b7f6 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 @@ -24,16 +24,20 @@ import com.fr.design.gui.ibutton.UIHeadGroup; import com.fr.design.gui.ibutton.UILockButton; import com.fr.design.gui.itextfield.UITextField; import com.fr.design.gui.itree.refreshabletree.ExpandMutableTreeNode; +import com.fr.design.i18n.Toolkit; import com.fr.design.icon.IconPathConstants; import com.fr.design.mainframe.DockingView; import com.fr.design.menu.LineSeparator; import com.fr.design.menu.MenuDef; +import com.fr.design.menu.ToolBarDef; import com.fr.general.ComparatorUtils; import com.fr.general.NameObject; import com.fr.log.FineLoggerFactory; import com.fr.stable.StringUtils; import com.fr.workspace.WorkContext; +import java.util.HashSet; +import java.util.Set; import javax.swing.AbstractButton; import javax.swing.Action; import javax.swing.DefaultCellEditor; @@ -60,6 +64,16 @@ import java.util.Objects; * Time: 16:23 */ public abstract class BasicTableDataTreePane extends DockingView implements ResponseDataSourceChange { + + private static final Set FORBIDDEN_SET = new HashSet<>(); + + static { + FORBIDDEN_SET.add(Toolkit.i18nText("Fine-Design_Basic_Edit")); + FORBIDDEN_SET.add(Toolkit.i18nText("Fine-Design_Basic_Remove")); + FORBIDDEN_SET.add(Toolkit.i18nText("Fine-Design_Basic_Preview")); + FORBIDDEN_SET.add(Toolkit.i18nText("Fine-Design_Basic_Action_Add")); + } + protected static final int PROCEDURE_NAME_INDEX = 4; protected static final int TEMPLATE_TABLE_DATA = 0; protected static final int SERVER_TABLE_DATA = 1; @@ -68,6 +82,7 @@ public abstract class BasicTableDataTreePane extends DockingView implements Resp protected UIHeadGroup buttonGroup; protected String[] allDSNames; protected ConnectionTableAction connectionTableAction; + protected ToolBarDef toolbarDef; private String type = ""; @@ -481,4 +496,14 @@ public abstract class BasicTableDataTreePane extends DockingView implements Resp } + public void refreshToolBar() { + if (toolbarDef != null) { + toolbarDef.refreshToolBar(FORBIDDEN_SET); + } + } + + public void checkEnable() { + + } + } diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/ChoosePane.java b/designer-base/src/main/java/com/fr/design/data/datapane/ChoosePane.java index fce7832ac..b5bc39e4e 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/ChoosePane.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/ChoosePane.java @@ -1,6 +1,7 @@ package com.fr.design.data.datapane; import com.fr.base.TableData; +import com.fr.concurrent.NamedThreadFactory; import com.fr.data.core.DataCoreUtils; import com.fr.data.core.db.DBUtils; import com.fr.data.core.db.TableProcedure; @@ -17,8 +18,8 @@ import com.fr.design.data.datapane.preview.PreviewLabel.Previewable; import com.fr.design.data.datapane.preview.PreviewTablePane; import com.fr.design.data.tabledata.Prepare4DataSourceChange; import com.fr.design.dialog.FineJOptionPane; -import com.fr.design.gui.icombobox.FRTreeComboBox; import com.fr.design.gui.icombobox.FilterableComboBoxModel; +import com.fr.design.gui.icombobox.SearchPreTaskTreeComboBox; import com.fr.design.gui.icombobox.UIComboBox; import com.fr.design.gui.icombobox.UIComboBoxEditor; import com.fr.design.gui.icombobox.UIComboBoxRenderer; @@ -59,6 +60,10 @@ import java.util.Collection; import java.util.Enumeration; import java.util.List; import java.util.Set; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.FutureTask; /** * @author zhou @@ -80,21 +85,25 @@ public class ChoosePane extends BasicBeanPane implements Refresha /** * 表名 */ - protected FRTreeComboBox tableNameComboBox; + protected SearchPreTaskTreeComboBox tableNameComboBox; - private SwingWorker populateWorker; + private static final ExecutorService SERVICE = Executors.newSingleThreadExecutor(new NamedThreadFactory("ChoosePane")); + private SwingWorker populateWorker; private PopupMenuListener popupMenuListener = new PopupMenuListener() { @Override public void popupMenuWillBecomeVisible(PopupMenuEvent e) { - new Thread() { + FutureTask task = new FutureTask(new Callable() { @Override - public void run() { + public Void call() throws Exception { calculateTableDataNames(); + return null; } - }.start(); + }); + tableNameComboBox.setPreSearchTask(task); + SERVICE.submit(task); } @Override @@ -158,7 +167,7 @@ public class ChoosePane extends BasicBeanPane implements Refresha schemaBox = new StringUIComboBox(); schemaBox.setEditor(new ComboBoxEditor()); - tableNameComboBox = new FRTreeComboBox(new JTree(new DefaultMutableTreeNode()), tableNameTreeRenderer, false); + tableNameComboBox = new SearchPreTaskTreeComboBox(new JTree(new DefaultMutableTreeNode()), tableNameTreeRenderer, false); tableNameComboBox.setEditable(true); tableNameComboBox.setRenderer(listCellRenderer); registerDSChangeListener(); diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/TableDataTreePane.java b/designer-base/src/main/java/com/fr/design/data/datapane/TableDataTreePane.java index 2356de6d4..31630b85c 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/TableDataTreePane.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/TableDataTreePane.java @@ -1,6 +1,5 @@ package com.fr.design.data.datapane; -import com.fr.base.BaseUtils; import com.fr.base.TableData; import com.fr.data.TableDataSource; import com.fr.data.impl.TableDataSourceDependent; @@ -101,7 +100,7 @@ public class TableDataTreePane extends BasicTableDataTreePane { removeAction = new RemoveAction(); previewTableDataAction = new PreviewTableDataAction(dataTree); connectionTableAction = new ConnectionTableAction(); - ToolBarDef toolbarDef = new ToolBarDef(); + toolbarDef = new ToolBarDef(); toolbarDef.addShortCut(addMenuDef, SeparatorDef.DEFAULT, editAction, removeAction, SeparatorDef.DEFAULT, previewTableDataAction, connectionTableAction); UIToolbar toolBar = ToolBarDef.createJToolBar(); toolBar.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, UIConstants.TOOLBAR_BORDER_COLOR)); @@ -288,6 +287,7 @@ public class TableDataTreePane extends BasicTableDataTreePane { fireDSChanged(); checkButtonEnabled(); DesignTableDataManager.removeSelectedColumnNames(selectedNO.getName()); + DesignModelAdapter.getCurrentModelAdapter().removeTableDataParameters(selectedNO.getName()); } } } @@ -341,8 +341,10 @@ public class TableDataTreePane extends BasicTableDataTreePane { dataTree.refresh(); } - - + @Override + public void checkEnable() { + this.checkButtonEnabled(); + } public void addDataPane(final AbstractTableDataPane uPanel, String paneName) { final NamePane nPanel = uPanel.asNamePane(); diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/connect/DBCPAttrPane.java b/designer-base/src/main/java/com/fr/design/data/datapane/connect/DBCPAttrPane.java new file mode 100644 index 000000000..01af97293 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/data/datapane/connect/DBCPAttrPane.java @@ -0,0 +1,118 @@ +package com.fr.design.data.datapane.connect; + +import com.fr.data.impl.JDBCDatabaseConnection; +import com.fr.data.pool.DBCPConnectionPoolAttr; +import com.fr.design.constants.UIConstants; +import com.fr.design.dialog.BasicPane; +import com.fr.design.editor.editor.IntegerEditor; +import com.fr.design.gui.icombobox.UIComboBox; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.gui.itextfield.UITextField; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.layout.TableLayout; +import com.fr.design.layout.TableLayoutHelper; +import java.awt.BorderLayout; +import java.awt.Component; +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.SwingConstants; + +public class DBCPAttrPane extends BasicPane { + public static final int TIME_MULTIPLE = 1000; + // carl:DBCP的一些属性 + private IntegerEditor DBCP_INITIAL_SIZE = new IntegerEditor(); + private IntegerEditor DBCP_MAX_ACTIVE = new IntegerEditor(); + private IntegerEditor DBCP_MAX_IDLE = new IntegerEditor(); + private IntegerEditor DBCP_MIN_IDLE = new IntegerEditor(); + private IntegerEditor DBCP_MAX_WAIT = new IntegerEditor(); + private UITextField DBCP_VALIDATION_QUERY = new UITextField(); + + private UIComboBox DBCP_TESTONBORROW = new UIComboBox(new String[]{Toolkit.i18nText("Fine-Design_Basic_No"), Toolkit.i18nText("Fine-Design_Basic_Yes")}); + private UIComboBox DBCP_TESTONRETURN = new UIComboBox(new String[]{Toolkit.i18nText("Fine-Design_Basic_No"), Toolkit.i18nText("Fine-Design_Basic_Yes")}); + private UIComboBox DBCP_TESTWHILEIDLE = new UIComboBox(new String[]{Toolkit.i18nText("Fine-Design_Basic_No"), Toolkit.i18nText("Fine-Design_Basic_Yes")}); + + private IntegerEditor DBCP_TIMEBETWEENEVICTIONRUNSMILLS = new IntegerEditor(); + private IntegerEditor DBCP_NUMTESTSPEREVICTIONRUN = new IntegerEditor(); + private IntegerEditor DBCP_MINEVICTABLEIDLETIMEMILLIS = new IntegerEditor(); + + public DBCPAttrPane() { + JPanel defaultPane = this; + + // JPanel northFlowPane + JPanel northFlowPane = FRGUIPaneFactory.createY_AXISBoxInnerContainer_L_Pane(); + defaultPane.add(northFlowPane, BorderLayout.NORTH); + + DBCP_VALIDATION_QUERY.setColumns(15); + // ContextPane + + double f = TableLayout.FILL; + // double p = TableLayout.PREFERRED; + double[] rowSize = {f, f, f, f, f, f, f, f, f, f, f, f}; + double[] columnSize = {f, f}; + Component[][] comps = { + {new UILabel(Toolkit.i18nText("Fine-Design_Basic_Dbcp_Initial_Size") + ":", SwingConstants.RIGHT), DBCP_INITIAL_SIZE}, + {new UILabel(Toolkit.i18nText("Fine-Design_Basic_Dbcp_Max_Active") + ":", SwingConstants.RIGHT), DBCP_MAX_ACTIVE}, + {new UILabel(Toolkit.i18nText("Fine-Design_Basic_Dbcp_Max_Idle") + ":", SwingConstants.RIGHT), DBCP_MAX_IDLE}, + {new UILabel(Toolkit.i18nText("Fine-Design_Basic_Dbcp_Min_Idle") + ":", SwingConstants.RIGHT), DBCP_MIN_IDLE}, + {new UILabel(Toolkit.i18nText("Fine-Design_Basic_Connection_Pool_Max_Wait_Time") + ":", SwingConstants.RIGHT), DBCP_MAX_WAIT}, + {new UILabel(Toolkit.i18nText("Fine-Design_Basic_Dbcp_Validation_Query") + ":", SwingConstants.RIGHT), DBCP_VALIDATION_QUERY}, + {new UILabel(Toolkit.i18nText("Fine-Design_Basic_Dbcp_Test_On_Borrow") + ":", SwingConstants.RIGHT), DBCP_TESTONBORROW}, + {new UILabel(Toolkit.i18nText("Fine-Design_Basic_Dbcp_Test_On_Return") + ":", SwingConstants.RIGHT), DBCP_TESTONRETURN}, + {new UILabel(Toolkit.i18nText("Fine-Design_Basic_Dbcp_Test_While_Idle") + ":", SwingConstants.RIGHT), DBCP_TESTWHILEIDLE}, + {new UILabel(Toolkit.i18nText("Fine-Design_Basic_Connection_Pool_Evictionruns_millis") + ":", SwingConstants.RIGHT), + DBCP_TIMEBETWEENEVICTIONRUNSMILLS}, + {new UILabel(Toolkit.i18nText("Fine-Design_Basic_Dbcp_Num_Test_Per_Evction_Run") + ":", SwingConstants.RIGHT), DBCP_NUMTESTSPEREVICTIONRUN}, + {new UILabel(Toolkit.i18nText("Fine-Design_Basic_Connection_Pool_Mix_Evictable_Idle_Time_Millis") + ":", SwingConstants.RIGHT), + DBCP_MINEVICTABLEIDLETIMEMILLIS}}; + + JPanel contextPane = TableLayoutHelper.createGapTableLayoutPane(comps, rowSize, columnSize, 10, 4); + contextPane.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, UIConstants.LINE_COLOR)); + northFlowPane.add(contextPane); + } + + public void populate(JDBCDatabaseConnection jdbcDatabase) { + DBCPConnectionPoolAttr dbcpAttr = jdbcDatabase.getDbcpAttr(); + if (dbcpAttr == null) { + dbcpAttr = new DBCPConnectionPoolAttr(); + jdbcDatabase.setDbcpAttr(dbcpAttr); + } + this.DBCP_INITIAL_SIZE.setValue(dbcpAttr.getInitialSize()); + this.DBCP_MAX_ACTIVE.setValue(dbcpAttr.getMaxActive()); + this.DBCP_MAX_IDLE.setValue(dbcpAttr.getMaxIdle()); + this.DBCP_MAX_WAIT.setValue(dbcpAttr.getMaxWait()); + this.DBCP_MIN_IDLE.setValue(dbcpAttr.getMinIdle()); + this.DBCP_VALIDATION_QUERY.setText(dbcpAttr.getValidationQuery()); + this.DBCP_TESTONBORROW.setSelectedIndex(dbcpAttr.isTestOnBorrow() ? 1 : 0); + this.DBCP_TESTONRETURN.setSelectedIndex(dbcpAttr.isTestOnReturn() ? 1 : 0); + this.DBCP_TESTWHILEIDLE.setSelectedIndex(dbcpAttr.isTestWhileIdle() ? 1 : 0); + this.DBCP_MINEVICTABLEIDLETIMEMILLIS.setValue(dbcpAttr.getMinEvictableIdleTimeMillis() / TIME_MULTIPLE); + this.DBCP_NUMTESTSPEREVICTIONRUN.setValue(dbcpAttr.getNumTestsPerEvictionRun()); + this.DBCP_TIMEBETWEENEVICTIONRUNSMILLS.setValue(dbcpAttr.getTimeBetweenEvictionRunsMillis()); + } + + public void update(JDBCDatabaseConnection jdbcDatabase) { + DBCPConnectionPoolAttr dbcpAttr = jdbcDatabase.getDbcpAttr(); + if (dbcpAttr == null) { + dbcpAttr = new DBCPConnectionPoolAttr(); + jdbcDatabase.setDbcpAttr(dbcpAttr); + } + dbcpAttr.setInitialSize(this.DBCP_INITIAL_SIZE.getValue().intValue()); + dbcpAttr.setMaxActive(this.DBCP_MAX_ACTIVE.getValue().intValue()); + dbcpAttr.setMaxIdle(this.DBCP_MAX_IDLE.getValue().intValue()); + dbcpAttr.setMaxWait(this.DBCP_MAX_WAIT.getValue().intValue()); + dbcpAttr.setMinIdle(this.DBCP_MIN_IDLE.getValue().intValue()); + dbcpAttr.setValidationQuery(this.DBCP_VALIDATION_QUERY.getText()); + dbcpAttr.setTestOnBorrow(this.DBCP_TESTONBORROW.getSelectedIndex() == 0 ? false : true); + dbcpAttr.setTestOnReturn(this.DBCP_TESTONRETURN.getSelectedIndex() == 0 ? false : true); + dbcpAttr.setTestWhileIdle(this.DBCP_TESTWHILEIDLE.getSelectedIndex() == 0 ? false : true); + dbcpAttr.setMinEvictableIdleTimeMillis(((Number) this.DBCP_MINEVICTABLEIDLETIMEMILLIS.getValue()).intValue() * TIME_MULTIPLE); + dbcpAttr.setNumTestsPerEvictionRun(((Number) this.DBCP_NUMTESTSPEREVICTIONRUN.getValue()).intValue()); + dbcpAttr.setTimeBetweenEvictionRunsMillis(((Number) this.DBCP_TIMEBETWEENEVICTIONRUNSMILLS.getValue()).intValue()); + } + + @Override + protected String title4PopupWindow() { + return Toolkit.i18nText("Fine-Design_Basic_ConnectionPool_Attr"); + } +} diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/connect/DatabaseConnectionPane.java b/designer-base/src/main/java/com/fr/design/data/datapane/connect/DatabaseConnectionPane.java index f6bfdd29a..209f4ab7d 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/connect/DatabaseConnectionPane.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/connect/DatabaseConnectionPane.java @@ -7,15 +7,20 @@ import com.fr.data.impl.Connection; import com.fr.data.impl.JDBCDatabaseConnection; import com.fr.data.impl.JNDIDatabaseConnection; import com.fr.data.operator.DataOperator; +import com.fr.data.solution.ExceptionSolutionSelector; +import com.fr.data.solution.entity.DriverPage; +import com.fr.data.solution.processor.ClassNotFoundExceptionSolutionProcessor; +import com.fr.data.solution.processor.SolutionProcessor; import com.fr.design.beans.BasicBeanPane; +import com.fr.design.dialog.BasicPane; import com.fr.design.gui.ibutton.UIButton; import com.fr.design.gui.icombobox.UIComboBox; +import com.fr.design.gui.ilable.ActionLabel; import com.fr.design.gui.ilable.UILabel; import com.fr.design.i18n.Toolkit; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.scrollruler.ModLineBorder; import com.fr.design.utils.gui.GUICoreUtils; - import com.fr.log.FineLoggerFactory; import com.fr.stable.ArrayUtils; import com.fr.stable.EncodeConstants; @@ -25,19 +30,28 @@ import javax.swing.BorderFactory; import javax.swing.BoxLayout; import javax.swing.JDialog; import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; import javax.swing.SwingUtilities; import javax.swing.SwingWorker; import javax.swing.UIManager; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Cursor; +import java.awt.Desktop; import java.awt.Dialog; import java.awt.Dimension; import java.awt.FlowLayout; +import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; -import java.util.HashMap; -import java.util.Map; +import java.net.URI; import java.util.concurrent.ExecutionException; /** @@ -50,45 +64,184 @@ public abstract class DatabaseConnectionPane connectionThread = new SwingWorker() { + @Override + protected Void doInBackground() throws Exception { + Connection database = DatabaseConnectionPane.this.updateBean(); + // 返回连接结果 + DriverPage.updateCache(); + DataOperator.getInstance().testConnectionWithException(database); + return null; + } + + @Override + protected void done() { + try { + get(); + dialog.setSize(new Dimension(380, 125)); + okButton.setEnabled(true); + uiLabel.setIcon(UIManager.getIcon("OptionPane.informationIcon")); + message.setText(Toolkit.i18nText("Fine-Design_Basic_Datasource_Connection_Successfully")); + } catch (InterruptedException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } catch (ExecutionException e) { + dialog.setSize(new Dimension(380, 142)); + midPane.setVisible(true); + hiddenPanel.setVisible(false); + okButton.setEnabled(true); + uiLabel.setIcon(UIManager.getIcon("OptionPane.errorIcon")); + message.setText(Toolkit.i18nText("Fine-Design_Basic_Connection_Failed")); + + SolutionProcessor select = ExceptionSolutionSelector.get().select(e); + if (select instanceof ClassNotFoundExceptionSolutionProcessor) { + JPanel gridJpanel = new JPanel(); + gridJpanel.setLayout(new GridLayout(5, 1, 0, 5)); + UILabel driverTips = new UILabel(); + driverTips.setText(Toolkit.i18nText("Fine_Designer_Not_Found_Driver")); + gridJpanel.add(driverTips); + UILabel deatail = new UILabel(); + String content = Toolkit.i18nText("Fine_Designer_Not_Found") + " " + select.getResultException().getDetailMessage() + " " + Toolkit.i18nText("Fine_Designer_Driver"); + deatail.setText(content); + deatail.setToolTipText(content); + gridJpanel.add(deatail); + String solution = select.getResultException().getSolution(); + UILabel redirect = new UILabel(); + if (solution != null) { + redirect.setText(Toolkit.i18nText("Fine_Designer_Download_Driver")); + redirect.setForeground(Color.BLUE); + redirect.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + try { + Desktop.getDesktop().browse(new URI(solution)); + } catch (Exception clickException) { + FineLoggerFactory.getLogger().warn("can not open browser with {}", solution); + } + } + + @Override + public void mouseEntered(MouseEvent e) { + redirect.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + } + + @Override + public void mouseExited(MouseEvent e) { + redirect.setCursor(Cursor.getDefaultCursor()); + } + }); + } else { + redirect.setText(Toolkit.i18nText("Fine_Designer_Not_Found_Driver_No_Solution")); + } + gridJpanel.add(redirect); + hiddenPanel.add(gridJpanel); + gridJpanel.setBackground(Color.WHITE); + } else { + JPanel borderPanel = new JPanel(); + borderPanel.setLayout(new BorderLayout()); + JTextArea jta = new JTextArea(); + JScrollPane jsp = new JScrollPane(jta); + jsp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); + jsp.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); + jta.append(select.getResultException().getDetailMessage() + "\n"); + jta.append(select.getResultException().getSolution()); + jta.setCaretPosition(0); + jta.setEditable(false); + jta.getCaret().addChangeListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + jta.getCaret().setVisible(true); + } + }); + borderPanel.add(jsp, BorderLayout.CENTER); + hiddenPanel.add(borderPanel); + } + okButton.setEnabled(true); + } + } + }; + midPane.setVisible(false); + hiddenPanel.setVisible(false); + initDialogPane(); + connectionThread.execute(); + // 老bug,initDialogPane 中的 dialog每次都是new的,所以可以重新添加 listener,但是其他的对象不行,会多次添加listener + if (firstCreate) { + okButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + hiddenPanel.removeAll(); + dialog.dispose(); + } + }); + cancelButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + hiddenPanel.removeAll(); + dialog.dispose(); + connectionThread.cancel(true); + } + }); + detailLabel.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + if (hiddenPanel.isVisible()) { + hiddenPanel.setVisible(false); + dialog.setSize(new Dimension(380, 142)); + detailLabel.setText(Toolkit.i18nText("Fine_Designer_Look_Detail")); + directUiLabel.setIcon(UIManager.getIcon("OptionPane.narrow.right")); + } else { + dialog.setSize(new Dimension(380, 270)); + hiddenPanel.setVisible(true); + detailLabel.setText(Toolkit.i18nText("Fine_Designer_Hide_Detail")); + directUiLabel.setIcon(UIManager.getIcon("OptionPane.narrow.down")); + } + } + + @Override + public void mouseEntered(MouseEvent e) { + detailLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + } + + @Override + public void mouseExited(MouseEvent e) { + detailLabel.setCursor(Cursor.getDefaultCursor()); + } + }); + firstCreate = false; + } + dialog.addWindowListener(new WindowAdapter() { + @Override + public void windowClosed(WindowEvent e) { + connectionThread.cancel(true); + } + }); + dialog.setVisible(true); + hiddenPanel.removeAll(); + dialog.dispose(); + } + }; protected abstract JPanel mainPanel(); @@ -96,14 +249,16 @@ public abstract class DatabaseConnectionPane connectionThread = new SwingWorker() { - @Override - protected Boolean doInBackground() throws Exception { - Connection database = DatabaseConnectionPane.this.updateBean(); - // 返回连接结果 - return DataOperator.getInstance().testConnection(database); - } + // 按钮. + JPanel testPane = FRGUIPaneFactory.createNormalFlowInnerContainer_M_Pane(); + northPane.add(testPane, BorderLayout.NORTH); + UIButton testButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Datasource_Test_Connection")); + testPane.add(testButton); + testButton.addActionListener(testConnectionActionListener); + testPane.setBorder(BorderFactory.createEmptyBorder(0, 0, 3, 4)); - @Override - protected void done() { - try { - boolean connect = get(); - okButton.setEnabled(true); - if (connect) { - uiLabel.setIcon(UIManager.getIcon("OptionPane.informationIcon")); - message.setText(Toolkit.i18nText("Fine-Design_Basic_Datasource_Connection_Successfully")); - }else{ - uiLabel.setIcon(UIManager.getIcon("OptionPane.errorIcon")); - message.setText(Toolkit.i18nText("Fine-Design_Basic_Connection_Failed")); - } - } catch (InterruptedException | ExecutionException e) { - FineLoggerFactory.getLogger().error(e.getMessage(), e); + // Center + mainPanel = mainPanel(); + northPane.add(mainPanel, BorderLayout.CENTER); + JPanel advancedPanel = FRGUIPaneFactory.createBorderLayout_L_Pane(); + advancedPanel.setBorder(BorderFactory.createTitledBorder( + new ModLineBorder(ModLineBorder.TOP), + Toolkit.i18nText("Fine-Design_Basic_Advanced") + )); + if (mainPanel instanceof JDBCDefPane) { + ActionLabel actionLabel = new ActionLabel(Toolkit.i18nText("Fine-Design_Basic_ConnectionPool_Attr")); + actionLabel.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt) { + JDialog wDialog = createJDialog(); + if (wDialog != null) { + wDialog.setVisible(true); } } - }; - - connectionThread.execute(); - initDialogPane(); - okButton.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - dialog.dispose(); - } - }); - cancelButton.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - dialog.dispose(); - connectionThread.cancel(true); - } }); + JPanel actionLabelPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + actionLabelPanel.setBorder(BorderFactory.createEmptyBorder(2, 4, 4, 20)); + actionLabelPanel.add(actionLabel, BorderLayout.WEST); + advancedPanel.add(actionLabelPanel); - dialog.addWindowListener(new WindowAdapter() { - public void windowClosed(WindowEvent e) { - connectionThread.cancel(true); - } - }); - - dialog.setVisible(true); - dialog.dispose(); + } else { + //非jdbc配置布局保持不变 + // ChartSet + String[] defaultEncode = new String[]{Toolkit.i18nText("Fine-Design_Encode_Auto")}; + charSetComboBox = new UIComboBox(ArrayUtils.addAll(defaultEncode, EncodeConstants.ENCODING_ARRAY)); + JPanel chartSetPane = FRGUIPaneFactory.createNColumnGridInnerContainer_S_Pane(2); + chartSetPane.add(GUICoreUtils.createNamedPane(charSetComboBox, Toolkit.i18nText("Fine-Design_Basic_Datasource_Charset") + ":")); + advancedPanel.add(chartSetPane); } - }; + northPane.add(advancedPanel); + } + + private JDialog createJDialog() { + return JDBC.getAdvancedAttrPane() != null ? JDBC.getAdvancedAttrPane().showWindow(SwingUtilities.getWindowAncestor(mainPanel)) : null; + } private void initDialogPane() { message.setText(Toolkit.i18nText("Fine-Design_Basic_Datasource_Test_Connection") + "..."); message.setBorder(BorderFactory.createEmptyBorder(8, 5, 0, 0)); okButton.setEnabled(false); - dialog = new JDialog((Dialog) SwingUtilities.getWindowAncestor(DatabaseConnectionPane.this), Toolkit.i18nText("Fine-Design_Basic_Datasource_Test_Connection"), true); - dialog.setSize(new Dimension(268, 118)); + dialog.setSize(new Dimension(380, 125)); okButton.setEnabled(false); JPanel jp = new JPanel(); JPanel upPane = new JPanel(); JPanel downPane = new JPanel(); uiLabel = new UILabel(UIManager.getIcon("OptionPane.informationIcon")); - upPane.setLayout(new FlowLayout(FlowLayout.LEFT, 10, 10)); upPane.add(uiLabel); upPane.add(message); - downPane.setLayout(new FlowLayout(FlowLayout.CENTER, 6, 0)); + midPane.setLayout(new FlowLayout(FlowLayout.LEFT, 10, 0)); + directUiLabel.setIcon(UIManager.getIcon("OptionPane.narrow.right")); + detailLabel.setText(Toolkit.i18nText("Fine_Designer_Look_Detail")); + detailLabel.setForeground(Color.BLUE); + hiddenPanel.setLayout(new BorderLayout(2, 0)); + hiddenPanel.add(new JPanel(), BorderLayout.WEST); + hiddenPanel.add(new JPanel(), BorderLayout.EAST); + downPane.setLayout(new FlowLayout(FlowLayout.RIGHT, 15, 9)); downPane.add(okButton); downPane.add(cancelButton); jp.setLayout(new BoxLayout(jp, BoxLayout.Y_AXIS)); jp.add(upPane); + jp.add(midPane); + jp.add(hiddenPanel); jp.add(downPane); dialog.add(jp); dialog.setResizable(false); @@ -213,6 +384,7 @@ public abstract class DatabaseConnectionPane { private static JDBCDefPane jdbcDefPane = new JDBCDefPane(); + private static DBCPAttrPane dbcpAttrPane = new DBCPAttrPane(); @Override protected JPanel mainPanel() { @@ -224,14 +396,21 @@ public abstract class DatabaseConnectionPane jdbcMap = new HashMap(); static { @@ -59,45 +65,41 @@ public class JDBCDefPane extends JPanel { new DriverURLName("COM.cloudscape.JDBCDriver", "jdbc:cloudscape:/cloudscape/"), new DriverURLName("com.internetcds.jdbc.tds.Driver", "jdbc:freetds:sqlserver://localhost/"), new DriverURLName("com.fr.swift.jdbc.Driver", "jdbc:swift:emb://default")}); - jdbcMap.put("Inceptor", new DriverURLName[]{new DriverURLName("org.apache.hive.jdbc.HiveDriver", "jdbc:inceptor2://localhost:10000/default"), - new DriverURLName("org.apache.hadoop.hive.jdbc.HiveDriver", "jdbc:inceptor://localhost:10000/default")}); - jdbcMap.put("Oracle", new DriverURLName[]{new DriverURLName("oracle.jdbc.driver.OracleDriver", "jdbc:oracle:thin:@localhost:1521:databaseName")}); - jdbcMap.put("DB2", new DriverURLName[]{new DriverURLName("com.ibm.db2.jcc.DB2Driver", "jdbc:db2://localhost:50000/")}); - jdbcMap.put("SQL Server", new DriverURLName[]{new DriverURLName("com.microsoft.sqlserver.jdbc.SQLServerDriver", "jdbc:sqlserver://localhost:1433;" + "databaseName=")}); - jdbcMap.put("MySQL", new DriverURLName[]{new DriverURLName("com.mysql.jdbc.Driver", "jdbc:mysql://localhost/"), - new DriverURLName("org.gjt.mm.mysql.Driver", "jdbc:mysql://localhost/")}); - jdbcMap.put("Sybase", new DriverURLName[]{new DriverURLName("com.sybase.jdbc2.jdbc.SybDriver", "jdbc:sybase:Tds:localhost:5000/")}); + jdbcMap.put("Inceptor", new DriverURLName[]{new DriverURLName("org.apache.hive.jdbc.HiveDriver", "jdbc:inceptor2://localhost:port/databaseName"), + new DriverURLName("org.apache.hadoop.hive.jdbc.HiveDriver", "jdbc:inceptor://localhost:port/databaseName")}); + jdbcMap.put("Oracle", new DriverURLName[]{new DriverURLName("oracle.jdbc.driver.OracleDriver", "jdbc:oracle:thin:@localhost:port:databaseName")}); + jdbcMap.put("DB2", new DriverURLName[]{new DriverURLName("com.ibm.db2.jcc.DB2Driver", "jdbc:db2://localhost:port/databaseName")}); + jdbcMap.put("SQL Server", new DriverURLName[]{new DriverURLName("com.microsoft.sqlserver.jdbc.SQLServerDriver", "jdbc:sqlserver://localhost:port;databaseName=databaseName")}); + jdbcMap.put("MySQL", new DriverURLName[]{new DriverURLName("com.mysql.jdbc.Driver", "jdbc:mysql://localhost:port/databaseName"), + new DriverURLName("org.gjt.mm.mysql.Driver", "jdbc:mysql://localhost:port/databaseName")}); + jdbcMap.put("Sybase", new DriverURLName[]{new DriverURLName("com.sybase.jdbc2.jdbc.SybDriver", "jdbc:sybase:Tds:localhost:port/databaseName")}); + jdbcMap.put("Derby", new DriverURLName[]{new DriverURLName("org.apache.derby.jdbc.ClientDriver", "jdbc:derby://localhost:port/databaseName")}); + jdbcMap.put("Postgre", new DriverURLName[]{new DriverURLName("org.postgresql.Driver", "jdbc:postgresql://localhost:port/databaseName")}); + jdbcMap.put("Access", new DriverURLName[]{new DriverURLName("sun.jdbc.odbc.JdbcOdbcDriver", "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=")}); - jdbcMap.put("Derby", new DriverURLName[]{new DriverURLName("org.apache.derby.jdbc.ClientDriver", "jdbc:derby://localhost:1527/")}); - jdbcMap.put("Postgre", new DriverURLName[]{new DriverURLName("org.postgresql.Driver", "jdbc:postgresql://localhost:5432/")}); jdbcMap.put("SQLite", new DriverURLName[]{new DriverURLName("org.sqlite.JDBC", "jdbc:sqlite://${ENV_HOME}/../help/FRDemo.db")}); } private UIButton dbtypeButton; private UIComboBox dbtypeComboBox; private UIComboBox driverComboBox; + private UITextField dbNameTextField; + private UITextField hostTextField; + private UITextField portTextField; private UITextField urlTextField; private UITextField userNameTextField; private JPasswordField passwordTextField; + private UIComboBox charSetComboBox; private ActionLabel odbcTipsLink; + private JPanel centerPanel; + private Component[][] allComponents; + private Component[][] partComponents; // 请不要改动dbtype,只应该最后添加 private final String[] dbtype = {"Oracle", "DB2", "SQL Server", "MySQL", "Sybase", "Access", "Derby", "Postgre", "SQLite", "Inceptor", OTHER_DB}; - // carl:DBCP的一些属性 - private IntegerEditor DBCP_INITIAL_SIZE = new IntegerEditor(); - private IntegerEditor DBCP_MAX_ACTIVE = new IntegerEditor(); - private IntegerEditor DBCP_MAX_IDLE = new IntegerEditor(); - private IntegerEditor DBCP_MIN_IDLE = new IntegerEditor(); - private IntegerEditor DBCP_MAX_WAIT = new IntegerEditor(); - private UITextField DBCP_VALIDATION_QUERY = new UITextField(); - - private UIComboBox DBCP_TESTONBORROW = new UIComboBox(new String[]{Toolkit.i18nText("Fine-Design_Basic_No"), Toolkit.i18nText("Fine-Design_Basic_Yes")}); - private UIComboBox DBCP_TESTONRETURN = new UIComboBox(new String[]{Toolkit.i18nText("Fine-Design_Basic_No"), Toolkit.i18nText("Fine-Design_Basic_Yes")}); - private UIComboBox DBCP_TESTWHILEIDLE = new UIComboBox(new String[]{Toolkit.i18nText("Fine-Design_Basic_No"), Toolkit.i18nText("Fine-Design_Basic_Yes")}); - private IntegerEditor DBCP_TIMEBETWEENEVICTIONRUNSMILLS = new IntegerEditor(); - private IntegerEditor DBCP_NUMTESTSPEREVICTIONRUN = new IntegerEditor(); - private IntegerEditor DBCP_MINEVICTABLEIDLETIMEMILLIS = new IntegerEditor(); + private JDBCDatabaseConnection jdbcDatabase; + private boolean needRefresh = true; public JDBCDefPane() { this.setBorder(UITitledBorder.createBorderWithTitle("JDBC" + ":")); @@ -116,7 +118,14 @@ public class JDBCDefPane extends JPanel { driverComboBox = new UIComboBox(); driverComboBox.setEditable(true); driverComboBox.addActionListener(driverListener); + dbNameTextField = new UITextField(15); + hostTextField = new UITextField(15); + portTextField = new UITextField(15); + portTextField.addInputMethodListener(portInputMethodListener); + portTextField.addKeyListener(portKeyListener); urlTextField = new UITextField(15); + urlTextField.getDocument().addDocumentListener(updateParaListener); + enableSubDocListener(); userNameTextField = new UITextField(15); userNameTextField.setName(USER_NAME); passwordTextField = new UIPasswordFieldWithFixedLength(15); @@ -128,11 +137,10 @@ public class JDBCDefPane extends JPanel { double f = TableLayout.FILL; JPanel dbtypePane = FRGUIPaneFactory.createRightFlowInnerContainer_S_Pane(); dbtypePane.add(new UILabel((Toolkit.i18nText("Fine-Design_Basic_Database") + ":"))); - JPanel dbtypeComPane = FRGUIPaneFactory.createNormalFlowInnerContainer_S_Pane(); Component[][] dbtypeComComponents = {{dbtypeComboBox}}; double[] dbtypeRowSize = {p}; double[] dbtypeColumnSize = {p}; - dbtypeComPane = TableLayoutHelper.createTableLayoutPane(dbtypeComComponents, dbtypeRowSize, dbtypeColumnSize); + JPanel dbtypeComPane = TableLayoutHelper.createTableLayoutPane(dbtypeComComponents, dbtypeRowSize, dbtypeColumnSize); JPanel driverPane = FRGUIPaneFactory.createRightFlowInnerContainer_S_Pane(); driverPane.add(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Driver") + ":")); @@ -159,49 +167,69 @@ public class JDBCDefPane extends JPanel { driverComboBoxAndTips.add(driverComboBox, BorderLayout.WEST); driverComboBoxAndTips.add(odbcTipsPane, BorderLayout.CENTER); + JPanel hostPane = FRGUIPaneFactory.createRightFlowInnerContainer_S_Pane(); + hostPane.add(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Host") + ":")); + Component[][] hostComComponents = {{hostTextField}}; + double[] hostRowSize = {p}; + double[] hostColumnSize = {p}; + JPanel hostComPane = TableLayoutHelper.createTableLayoutPane(hostComComponents, hostRowSize, hostColumnSize); + + JPanel portPane = FRGUIPaneFactory.createRightFlowInnerContainer_S_Pane(); + portPane.add(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Port") + ":")); + Component[][] portComComponents = {{portTextField}}; + double[] portRowSize = {p}; + double[] portColumnSize = {p}; + JPanel portComPane = TableLayoutHelper.createTableLayoutPane(portComComponents, portRowSize, portColumnSize); + + JPanel dbNamePane = FRGUIPaneFactory.createRightFlowInnerContainer_S_Pane(); + dbNamePane.add(new UILabel(Toolkit.i18nText("Fine-Design_Basic_DatabaseName") + ":")); + Component[][] dbNameComComponents = {{dbNameTextField}}; + double[] dbNameRowSize = {p}; + double[] dbNameColumnSize = {p}; + JPanel dbNameComPane = TableLayoutHelper.createTableLayoutPane(dbNameComComponents, dbNameRowSize, dbNameColumnSize); + JPanel urlPane = FRGUIPaneFactory.createRightFlowInnerContainer_S_Pane(); urlPane.add(new UILabel("URL:")); - JPanel urlComPane = FRGUIPaneFactory.createNormalFlowInnerContainer_S_Pane(); Component[][] urlComComponents = {{urlTextField, dbtypeButton}}; double[] urlRowSize = {p}; double[] urlColumnSize = {f, 21}; - urlComPane = TableLayoutHelper.createCommonTableLayoutPane(urlComComponents, urlRowSize, urlColumnSize, 4); + JPanel urlComPane = TableLayoutHelper.createCommonTableLayoutPane(urlComComponents, urlRowSize, urlColumnSize, 4); JPanel userPane = FRGUIPaneFactory.createRightFlowInnerContainer_S_Pane(); userPane.add(new UILabel(Toolkit.i18nText("Fine-Design_Report_UserName") + ":")); - JPanel userComPane = FRGUIPaneFactory.createNormalFlowInnerContainer_S_Pane(); Component[][] userComComponents = {{userNameTextField, new UILabel(Toolkit.i18nText("Fine-Design_Basic_Password") + ":"), passwordTextField}}; double[] userRowSize = {p}; double[] userColumnSize = {f, p, f}; - userComPane = TableLayoutHelper.createCommonTableLayoutPane(userComComponents, userRowSize, userColumnSize, 4); - - JPanel passwordPane = FRGUIPaneFactory.createRightFlowInnerContainer_S_Pane(); - passwordPane.add(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Password") + ":")); - - Component[][] components = {{dbtypePane, dbtypeComPane}, {driverPane, driverComboBoxAndTips}, {urlPane, urlComPane}, {userPane, userComPane},}; - - double[] rowSize = {p, p, p, p}; + JPanel userComPane = TableLayoutHelper.createCommonTableLayoutPane(userComComponents, userRowSize, userColumnSize, 4); + + String[] defaultEncode = new String[]{Toolkit.i18nText("Fine-Design_Encode_Auto")}; + charSetComboBox = new UIComboBox(ArrayUtils.addAll(defaultEncode, EncodeConstants.ENCODING_ARRAY)); + JPanel chartSetPane = FRGUIPaneFactory.createRightFlowInnerContainer_S_Pane(); + chartSetPane.add(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Datasource_Charset") + ":")); + Component[][] charSetComComponents = {{charSetComboBox}}; + double[] charSetRowSize = {p}; + double[] charSetColumnSize = {f}; + JPanel charSetComPane = TableLayoutHelper.createTableLayoutPane(charSetComComponents, charSetRowSize, charSetColumnSize); + + //这边调整的话注意下面的changePane + allComponents = new Component[][]{{dbtypePane, dbtypeComPane}, {driverPane, driverComboBoxAndTips}, {hostPane, hostComPane}, + {portPane, portComPane}, {dbNamePane, dbNameComPane}, {userPane, userComPane}, + {chartSetPane, charSetComPane}, {urlPane, urlComPane}}; + partComponents = new Component[][]{{dbtypePane, dbtypeComPane}, {driverPane, driverComboBoxAndTips}, {urlPane, urlComPane}, + {userPane, userComPane}, {chartSetPane, charSetComPane}}; + double[] rowSize = {p, p, p, p, p, p, p, p}; double[] columnSize = {p, f, 22}; // REPORT-41450 Windows环境的jdk11下dpi为125%时会因为缩放导致显示问题,因此加个水平gap值 - JPanel centerPanel = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, 6, 6); + centerPanel = TableLayoutHelper.createGapTableLayoutPane(allComponents, rowSize, columnSize, 6, 6); innerthis.add(centerPanel); - JPanel southPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); - innerthis.add(southPanel); - southPanel.setBorder(BorderFactory.createEmptyBorder(10, 0, 4, 20)); - ActionLabel actionLabel = new ActionLabel(Toolkit.i18nText("Fine-Design_Basic_ConnectionPool_Attr")); - southPanel.add(actionLabel, BorderLayout.EAST); - actionLabel.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent evt) { - JDialog wDialog = createJDialog(); - wDialog.setVisible(true); - } - }); } public void populate(JDBCDatabaseConnection jdbcDatabase) { + needRefresh = false; if (jdbcDatabase == null) { jdbcDatabase = new JDBCDatabaseConnection(); } + this.jdbcDatabase = jdbcDatabase; if (ComparatorUtils.equals(jdbcDatabase.getDriver(), "sun.jdbc.odbc.JdbcOdbcDriver") && jdbcDatabase.getURL().startsWith("jdbc:odbc:Driver={Microsoft")) { this.dbtypeComboBox.setSelectedItem("Access"); @@ -230,52 +258,51 @@ public class JDBCDefPane extends JPanel { this.urlTextField.setText(jdbcDatabase.getURL()); this.userNameTextField.setText(jdbcDatabase.getUser()); this.passwordTextField.setText(jdbcDatabase.getPassword()); + this.originalCharSet = jdbcDatabase.getOriginalCharsetName(); + if (StringUtils.isBlank(originalCharSet)) { + this.charSetComboBox.setSelectedItem(Toolkit.i18nText("Fine-Design_Encode_Auto")); + } else { + this.charSetComboBox.setSelectedItem(jdbcDatabase.getOriginalCharsetName()); + } + needRefresh = false; + } + + protected JDBCDatabaseConnection getJDBCDatabase() { + return this.jdbcDatabase; + } - DBCPConnectionPoolAttr dbcpAttr = jdbcDatabase.getDbcpAttr(); - if (dbcpAttr == null) { - dbcpAttr = new DBCPConnectionPoolAttr(); - jdbcDatabase.setDbcpAttr(dbcpAttr); + private void changePane(Object dbType) { + double p = TableLayout.PREFERRED; + double f = TableLayout.FILL; + double[] columnSize = {p, f, 22}; + if (ComparatorUtils.equals(dbType, OTHER_DB) || ComparatorUtils.equals(dbType, "Access") || ComparatorUtils.equals(dbType, "SQLite")) { + if (this.centerPanel.getComponentCount() != partComponents.length * 2) { + centerPanel.removeAll(); + TableLayoutHelper.addComponent2ResultPane(partComponents, new double[]{p, p, p, p, p}, columnSize, centerPanel); + } + } else if (this.centerPanel.getComponentCount() != allComponents.length * 2) { + centerPanel.removeAll(); + TableLayoutHelper.addComponent2ResultPane(allComponents, new double[]{p, p, p, p, p, p, p, p}, columnSize, centerPanel); } - this.DBCP_INITIAL_SIZE.setValue(dbcpAttr.getInitialSize()); - this.DBCP_MAX_ACTIVE.setValue(dbcpAttr.getMaxActive()); - this.DBCP_MAX_IDLE.setValue(dbcpAttr.getMaxIdle()); - this.DBCP_MAX_WAIT.setValue(dbcpAttr.getMaxWait()); - this.DBCP_MIN_IDLE.setValue(dbcpAttr.getMinIdle()); - this.DBCP_VALIDATION_QUERY.setText(dbcpAttr.getValidationQuery()); - this.DBCP_TESTONBORROW.setSelectedIndex(dbcpAttr.isTestOnBorrow() ? 1 : 0); - this.DBCP_TESTONRETURN.setSelectedIndex(dbcpAttr.isTestOnReturn() ? 1 : 0); - this.DBCP_TESTWHILEIDLE.setSelectedIndex(dbcpAttr.isTestWhileIdle() ? 1 : 0); - this.DBCP_MINEVICTABLEIDLETIMEMILLIS.setValue(dbcpAttr.getMinEvictableIdleTimeMillis() / TIME_MULTIPLE); - this.DBCP_NUMTESTSPEREVICTIONRUN.setValue(dbcpAttr.getNumTestsPerEvictionRun()); - this.DBCP_TIMEBETWEENEVICTIONRUNSMILLS.setValue(dbcpAttr.getTimeBetweenEvictionRunsMillis()); } public JDBCDatabaseConnection update() { - JDBCDatabaseConnection jdbcDatabase = new JDBCDatabaseConnection(); + if (jdbcDatabase == null) { + jdbcDatabase = new JDBCDatabaseConnection(); + } Object driveItem = this.driverComboBox.getSelectedItem(); jdbcDatabase.setDriver(driveItem == null ? null : driveItem.toString()); jdbcDatabase.setURL(this.urlTextField.getText().trim()); jdbcDatabase.setUser(this.userNameTextField.getText().trim()); jdbcDatabase.setPassword(new String(this.passwordTextField.getPassword()).trim()); - - DBCPConnectionPoolAttr dbcpAttr = jdbcDatabase.getDbcpAttr(); - if (dbcpAttr == null) { - dbcpAttr = new DBCPConnectionPoolAttr(); - jdbcDatabase.setDbcpAttr(dbcpAttr); + jdbcDatabase.setOriginalCharsetName(this.originalCharSet); + if (this.charSetComboBox.getSelectedIndex() == 0) { + jdbcDatabase.setNewCharsetName(null); + jdbcDatabase.setOriginalCharsetName(null); + } else { + jdbcDatabase.setNewCharsetName(EncodeConstants.ENCODING_GBK); + jdbcDatabase.setOriginalCharsetName(((String) this.charSetComboBox.getSelectedItem())); } - dbcpAttr.setInitialSize(this.DBCP_INITIAL_SIZE.getValue().intValue()); - dbcpAttr.setMaxActive(this.DBCP_MAX_ACTIVE.getValue().intValue()); - dbcpAttr.setMaxIdle(this.DBCP_MAX_IDLE.getValue().intValue()); - dbcpAttr.setMaxWait(this.DBCP_MAX_WAIT.getValue().intValue()); - dbcpAttr.setMinIdle(this.DBCP_MIN_IDLE.getValue().intValue()); - dbcpAttr.setValidationQuery(this.DBCP_VALIDATION_QUERY.getText()); - dbcpAttr.setTestOnBorrow(this.DBCP_TESTONBORROW.getSelectedIndex() == 0 ? false : true); - dbcpAttr.setTestOnReturn(this.DBCP_TESTONRETURN.getSelectedIndex() == 0 ? false : true); - dbcpAttr.setTestWhileIdle(this.DBCP_TESTWHILEIDLE.getSelectedIndex() == 0 ? false : true); - dbcpAttr.setMinEvictableIdleTimeMillis(((Number) this.DBCP_MINEVICTABLEIDLETIMEMILLIS.getValue()).intValue() * TIME_MULTIPLE); - dbcpAttr.setNumTestsPerEvictionRun(((Number) this.DBCP_NUMTESTSPEREVICTIONRUN.getValue()).intValue()); - dbcpAttr.setTimeBetweenEvictionRunsMillis(((Number) this.DBCP_TIMEBETWEENEVICTIONRUNSMILLS.getValue()).intValue()); - return jdbcDatabase; } @@ -297,6 +324,11 @@ public class JDBCDefPane extends JPanel { urlTextField.setText(dus[i].getURL()); } } + // 更改数据库类型后 数据库名称置空和之前逻辑保持一致 + if (needRefresh) { + jdbcDatabase.setDatabase(StringUtils.EMPTY); + } + changePane(dbtypeComboBox.getSelectedItem()); } }; @@ -355,49 +387,175 @@ public class JDBCDefPane extends JPanel { } }; - private JDialog createJDialog() { - return new DBCPAttrPane().showWindow(SwingUtilities.getWindowAncestor(JDBCDefPane.this)); + InputMethodListener portInputMethodListener = new InputMethodListener() { + @Override + public void inputMethodTextChanged(InputMethodEvent event) { + if (null == event.getText()) { + return; + } + char ch = event.getText().current(); + if (!(ch >= '0' && ch <= '9')) { + event.consume(); + } + } + + @Override + public void caretPositionChanged(InputMethodEvent event) { + + } + }; + + DocumentListener updateParaListener = new DocumentListener() { + @Override + public void insertUpdate(DocumentEvent e) { + updatePara(); + } + + @Override + public void removeUpdate(DocumentEvent e) { + updatePara(); + } + + @Override + public void changedUpdate(DocumentEvent e) { + updatePara(); + } + }; + + private void updatePara() { + String dbType = dbtypeComboBox.getSelectedItem().toString(); + if (ComparatorUtils.equals(dbType, OTHER_DB) || ComparatorUtils.equals(dbType, "Access") || ComparatorUtils.equals(dbType, "SQLite")) { + return; + } + disableSubDocListener(); + String url = urlTextField.getText().trim(); + Matcher matcher = ORACLE_URL.matcher(url); + if (matcher.find()) { + if (matcher.group(1) != null) { + hostTextField.setText(matcher.group(1)); + } else { + hostTextField.setText(StringUtils.EMPTY); + } + if (matcher.group(3) != null) { + portTextField.setText(matcher.group(3)); + } else { + portTextField.setText(StringUtils.EMPTY); + } + if (matcher.group(5) != null) { + dbNameTextField.setText(matcher.group(5)); + } else { + dbNameTextField.setText(StringUtils.EMPTY); + } + enableSubDocListener(); + return; + } + matcher = GENERAL_URL.matcher(url); + if (matcher.find()) { + if (matcher.group(2) != null) { + hostTextField.setText(matcher.group(2)); + } else { + hostTextField.setText(StringUtils.EMPTY); + } + if (matcher.group(4) != null) { + portTextField.setText(matcher.group(4)); + } else { + portTextField.setText(StringUtils.EMPTY); + } + if (matcher.group(7) != null) { + dbNameTextField.setText(matcher.group(7)); + } else { + dbNameTextField.setText(StringUtils.EMPTY); + } + enableSubDocListener(); + return; + } + hostTextField.setText(StringUtils.EMPTY); + portTextField.setText(StringUtils.EMPTY); + dbNameTextField.setText(StringUtils.EMPTY); + enableSubDocListener(); + } + + private void enableSubDocListener() { + this.dbNameTextField.getDocument().addDocumentListener(updateURLListener); + this.hostTextField.getDocument().addDocumentListener(updateURLListener); + } + + private void disableSubDocListener() { + this.dbNameTextField.getDocument().removeDocumentListener(updateURLListener); + this.hostTextField.getDocument().removeDocumentListener(updateURLListener); + } + + KeyListener portKeyListener = new KeyAdapter() { + @Override + public void keyReleased(KeyEvent e) { + String port = portTextField.getText(); + if (isPortValid(port)) { + updateURL(); + } else { + portTextField.setText(port.replaceAll(getCharNeedReplace(e.getKeyChar()) , "")); + if (!isPortValid(portTextField.getText())) { + portTextField.setText(StringUtils.EMPTY); + updateURL(); + } + } + } + }; + + private boolean isPortValid(String port) { + return PORT.matcher(port).find(); } - class DBCPAttrPane extends BasicPane { - public DBCPAttrPane() { - JPanel defaultPane = this; - - // JPanel northFlowPane - JPanel northFlowPane = FRGUIPaneFactory.createY_AXISBoxInnerContainer_L_Pane(); - defaultPane.add(northFlowPane, BorderLayout.NORTH); - - DBCP_VALIDATION_QUERY.setColumns(15); - // ContextPane - - double f = TableLayout.FILL; - // double p = TableLayout.PREFERRED; - double[] rowSize = {f, f, f, f, f, f, f, f, f, f, f, f}; - double[] columnSize = {f, f}; - Component[][] comps = { - {new UILabel(Toolkit.i18nText("Fine-Design_Basic_Dbcp_Initial_Size") + ":", SwingConstants.RIGHT), DBCP_INITIAL_SIZE}, - {new UILabel(Toolkit.i18nText("Fine-Design_Basic_Dbcp_Max_Active") + ":", SwingConstants.RIGHT), DBCP_MAX_ACTIVE}, - {new UILabel(Toolkit.i18nText("Fine-Design_Basic_Dbcp_Max_Idle") + ":", SwingConstants.RIGHT), DBCP_MAX_IDLE}, - {new UILabel(Toolkit.i18nText("Fine-Design_Basic_Dbcp_Min_Idle") + ":", SwingConstants.RIGHT), DBCP_MIN_IDLE}, - {new UILabel(Toolkit.i18nText("Fine-Design_Basic_Connection_Pool_Max_Wait_Time") + ":", SwingConstants.RIGHT), DBCP_MAX_WAIT}, - {new UILabel(Toolkit.i18nText("Fine-Design_Basic_Dbcp_Validation_Query") + ":", SwingConstants.RIGHT), DBCP_VALIDATION_QUERY}, - {new UILabel(Toolkit.i18nText("Fine-Design_Basic_Dbcp_Test_On_Borrow") + ":", SwingConstants.RIGHT), DBCP_TESTONBORROW}, - {new UILabel(Toolkit.i18nText("Fine-Design_Basic_Dbcp_Test_On_Return") + ":", SwingConstants.RIGHT), DBCP_TESTONRETURN}, - {new UILabel(Toolkit.i18nText("Fine-Design_Basic_Dbcp_Test_While_Idle") + ":", SwingConstants.RIGHT), DBCP_TESTWHILEIDLE}, - {new UILabel(Toolkit.i18nText("Fine-Design_Basic_Connection_Pool_Evictionruns_millis") + ":", SwingConstants.RIGHT), - DBCP_TIMEBETWEENEVICTIONRUNSMILLS}, - {new UILabel(Toolkit.i18nText("Fine-Design_Basic_Dbcp_Num_Test_Per_Evction_Run") + ":", SwingConstants.RIGHT), DBCP_NUMTESTSPEREVICTIONRUN}, - {new UILabel(Toolkit.i18nText("Fine-Design_Basic_Connection_Pool_Mix_Evictable_Idle_Time_Millis") + ":", SwingConstants.RIGHT), - DBCP_MINEVICTABLEIDLETIMEMILLIS}}; - - JPanel contextPane = TableLayoutHelper.createGapTableLayoutPane(comps, rowSize, columnSize, 10, 4); - contextPane.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, UIConstants.LINE_COLOR)); - northFlowPane.add(contextPane); + private String getCharNeedReplace(char c) { + String charNeedReplace = c + ""; + Matcher matcher = CHAR_NEED_ESCAPE.matcher(charNeedReplace); + if (matcher.find()) { + charNeedReplace = "\\" + charNeedReplace; + } + return charNeedReplace; + } + + DocumentListener updateURLListener = new DocumentListener() { + + @Override + public void insertUpdate(DocumentEvent e) { + updateURL(); } @Override - protected String title4PopupWindow() { - return Toolkit.i18nText("Fine-Design_Basic_ConnectionPool_Attr"); + public void removeUpdate(DocumentEvent e) { + updateURL(); + } + + @Override + public void changedUpdate(DocumentEvent e) { + updateURL(); + } + }; + + private void updateURL() { + String dbType = dbtypeComboBox.getSelectedItem().toString(); + if (!ComparatorUtils.equals(dbType, OTHER_DB) && !ComparatorUtils.equals(dbType, "Access") && !ComparatorUtils.equals(dbType, "SQLite")) { + urlTextField.getDocument().removeDocumentListener(updateParaListener); + DriverURLName[] driverURLNames = jdbcMap.get(dbType); + String defaultURL = null; + for (DriverURLName driverURLName : driverURLNames) { + if (ComparatorUtils.equals(driverURLName.getDriver(), driverComboBox.getSelectedItem().toString())) { + defaultURL = driverURLName.getURL(); + } + } + if (defaultURL != null) { + String host = hostTextField.getText().trim(); + String port = portTextField.getText().trim(); + String dbName = dbNameTextField.getText().trim(); + defaultURL = defaultURL.replace("localhost", host).replace(":port", ComparatorUtils.equals(port, "") ? "" : ":" + port); + if (defaultURL.startsWith("jdbc:sqlserver")) { + defaultURL = defaultURL.replace("=databaseName", "=" + dbName); + } else { + defaultURL = defaultURL.replace("databaseName", dbName); + } + } + urlTextField.setText(defaultURL); + urlTextField.getDocument().addDocumentListener(updateParaListener); } } diff --git a/designer-base/src/main/java/com/fr/design/dialog/link/MessageWithLink.java b/designer-base/src/main/java/com/fr/design/dialog/link/MessageWithLink.java index 8a1f55cbd..889a0c3c9 100644 --- a/designer-base/src/main/java/com/fr/design/dialog/link/MessageWithLink.java +++ b/designer-base/src/main/java/com/fr/design/dialog/link/MessageWithLink.java @@ -9,6 +9,7 @@ import java.awt.Font; import java.net.URI; import javax.swing.JEditorPane; import javax.swing.event.HyperlinkEvent; +import javax.swing.event.HyperlinkListener; /** * 用来构建JOptionPane带超链的消息提示 @@ -19,31 +20,45 @@ import javax.swing.event.HyperlinkEvent; */ public class MessageWithLink extends JEditorPane { + private static final UILabel LABEL = new UILabel(); + + public MessageWithLink(String message, String linkName, String link) { - super("text/html", "" + message + "" + linkName + "" + ""); - addHyperlinkListener(e -> { - if (e.getEventType().equals(HyperlinkEvent.EventType.ACTIVATED)) { - try { - Desktop.getDesktop().browse(URI.create(link)); - } catch (Exception exception) { - FineLoggerFactory.getLogger().error(exception.getMessage(), exception); - } - } - }); - setEditable(false); - setBorder(null); + this(message, linkName, link, LABEL.getBackground(), LABEL.getFont()); } public MessageWithLink(String linkName, String link ) { this(StringUtils.EMPTY, linkName, link); } - private static StringBuilder getStyle() { - // 构建和相同风格样式 - UILabel label = new UILabel(); - Font font = label.getFont(); - Color color = label.getBackground(); + public MessageWithLink(String message, String linkName, String link, Color color) { + this(message, linkName, link, color, LABEL.getFont()); + } + + public MessageWithLink(String message, String linkName, String link, Color color, Font font) { + super("text/html", "" + message + "" + linkName + "" + ""); + initListener(link); + setEditable(false); + setBorder(null); + } + + protected void initListener(String link) { + addHyperlinkListener(new HyperlinkListener() { + @Override + public void hyperlinkUpdate(HyperlinkEvent e) { + if (e.getEventType().equals(HyperlinkEvent.EventType.ACTIVATED)) { + try { + Desktop.getDesktop().browse(URI.create(link)); + } catch (Exception exception) { + FineLoggerFactory.getLogger().error(exception.getMessage(), exception); + } + } + } + }); + } + private static StringBuilder generateStyle(Color color, Font font) { + // 构建相同风格样式 StringBuilder style = new StringBuilder("font-family:" + font.getFamily() + ";"); style.append("font-weight:").append(font.isBold() ? "bold" : "normal").append(";"); style.append("font-size:").append(font.getSize()).append("pt;"); diff --git a/designer-base/src/main/java/com/fr/design/env/DesignerWorkspaceLoader.java b/designer-base/src/main/java/com/fr/design/env/DesignerWorkspaceLoader.java new file mode 100644 index 000000000..c910c7db4 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/env/DesignerWorkspaceLoader.java @@ -0,0 +1,21 @@ +package com.fr.design.env; + +import com.fr.workspace.WorkContext; +import com.fr.workspace.Workspace; + +/** + * @author hades + * @version 10.0 + * Created by hades on 2021/4/11 + */ +public class DesignerWorkspaceLoader { + + public static void init() { + Workspace workspace = WorkContext.getCurrent(); + if (workspace.isLocal()) { + return; + } + workspace.isWarDeploy(); + workspace.isCluster(); + } +} diff --git a/designer-base/src/main/java/com/fr/design/env/RemoteWorkspace.java b/designer-base/src/main/java/com/fr/design/env/RemoteWorkspace.java index 6d1685e74..f31954964 100644 --- a/designer-base/src/main/java/com/fr/design/env/RemoteWorkspace.java +++ b/designer-base/src/main/java/com/fr/design/env/RemoteWorkspace.java @@ -14,6 +14,7 @@ import com.fr.workspace.connect.WorkspaceConnectionInfo; import com.fr.workspace.server.authority.decision.DecisionOperator; import com.fr.workspace.engine.rpc.WorkspaceProxyPool; import com.fr.workspace.pool.WorkObjectPool; +import javax.swing.SwingWorker; /** * Created by juhaoyu on 2018/6/14. @@ -29,6 +30,10 @@ public class RemoteWorkspace implements Workspace { private volatile Boolean isRoot = null; + private volatile Boolean cluster; + + private volatile Boolean warDeploy; + RemoteWorkspace(WorkspaceClient client, WorkspaceConnectionInfo connection) { this.client = client; @@ -50,12 +55,15 @@ public class RemoteWorkspace implements Workspace { @Override public boolean isWarDeploy() { - return WorkContext.getCurrent().get(CommonOperator.class, new ExceptionHandler() { - @Override - public Boolean callHandler(RPCInvokerExceptionInfo rpcInvokerExceptionInfo) { - return false; - } - }).isWarDeploy(); + if (warDeploy == null) { + warDeploy = WorkContext.getCurrent().get(CommonOperator.class, new ExceptionHandler() { + @Override + public Boolean callHandler(RPCInvokerExceptionInfo rpcInvokerExceptionInfo) { + return false; + } + }).isWarDeploy(); + } + return warDeploy; } @Override @@ -79,12 +87,15 @@ public class RemoteWorkspace implements Workspace { @Override public boolean isCluster() { - return WorkContext.getCurrent().get(ClusterOperator.class, new ExceptionHandler() { - @Override - public Boolean callHandler(RPCInvokerExceptionInfo rpcInvokerExceptionInfo) { - return false; - } - }).isCluster(); + if (cluster == null) { + cluster = WorkContext.getCurrent().get(ClusterOperator.class, new ExceptionHandler() { + @Override + public Boolean callHandler(RPCInvokerExceptionInfo rpcInvokerExceptionInfo) { + return false; + } + }).isCluster(); + } + return cluster; } @Override @@ -114,8 +125,13 @@ public class RemoteWorkspace implements Workspace { @Override public void close() { - - client.close(); + new SwingWorker() { + @Override + protected Void doInBackground() throws Exception { + client.close(); + return null; + } + }.execute(); } @Override @@ -127,7 +143,9 @@ public class RemoteWorkspace implements Workspace { @Override public boolean equals(Object obj) { - return obj instanceof RemoteWorkspace && AssistUtils.equals(((RemoteWorkspace) obj).connection, this.connection); + return obj instanceof RemoteWorkspace + && AssistUtils.equals(((RemoteWorkspace) obj).connection, this.connection) + && AssistUtils.equals(((RemoteWorkspace) obj).client.getConnection(), this.client.getConnection()); } public WorkspaceClient getClient(){ diff --git a/designer-base/src/main/java/com/fr/design/env/WorkspaceChangeLoadingDialog.java b/designer-base/src/main/java/com/fr/design/env/WorkspaceChangeLoadingDialog.java new file mode 100644 index 000000000..91dc3fcd7 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/env/WorkspaceChangeLoadingDialog.java @@ -0,0 +1,47 @@ +package com.fr.design.env; + +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.utils.gui.GUICoreUtils; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import javax.swing.ImageIcon; +import javax.swing.JDialog; + +/** + * @author hades + * @version 10.0 + * Created by hades on 2021/4/10 + */ +public class WorkspaceChangeLoadingDialog extends JDialog { + + private static final ImageIcon LOADING_ICON = new ImageIcon(WorkspaceChangeLoadingDialog.class.getResource("/com/fr/web/images/loading-local.gif")); + + private static WorkspaceChangeLoadingDialog dialog; + + public WorkspaceChangeLoadingDialog() { + super(DesignerContext.getDesignerFrame()); + setLayout(new BorderLayout()); + this.getContentPane().setBackground(Color.WHITE); + this.setResizable(false); + this.setUndecorated(true); + this.setAlwaysOnTop(true); + this.setModal(false); + this.setSize(new Dimension(400, 100)); + this.add(new UILabel(LOADING_ICON, UILabel.CENTER), BorderLayout.NORTH); + this.add(new UILabel(Toolkit.i18nText("Fine-Design_Change_Workspace_Tip"), UILabel.CENTER), BorderLayout.CENTER); + GUICoreUtils.centerWindow(this); + } + + + public static void showDialog() { + dialog = new WorkspaceChangeLoadingDialog(); + dialog.setVisible(true); + } + + public static void hideDialog() { + dialog.dispose(); + } +} 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 f6b8f07d5..f7d4d1f57 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 @@ -33,6 +33,7 @@ import java.util.List; import java.util.ListIterator; import java.util.Map; import java.util.Set; +import javax.swing.SwingWorker; /** * 历史模板缓存 @@ -45,6 +46,7 @@ public class HistoryTemplateListCache implements CallbackEvent { private static final int DEAD_LINE = DesignerEnvManager.getEnvManager().getCachingTemplateLimit(); private List> historyList; private JTemplate editingTemplate; + private SwingWorker stashWorker; public static HistoryTemplateListCache getInstance() { return Holder.INSTANCE; @@ -64,7 +66,6 @@ public class HistoryTemplateListCache implements CallbackEvent { * @param selected 选择的 */ public void closeSelectedReport(JTemplate selected) { - DesignModuleFactory.clearChartPropertyPane(); DesignTableDataManager.closeTemplate(selected); //直接关闭模板的时候(当且仅当设计器tab上只剩一个模板)退出权限编辑 if (DesignModeContext.isAuthorityEditing() && historyList.size() <= 1) { @@ -92,7 +93,6 @@ public class HistoryTemplateListCache implements CallbackEvent { * @param selected 选择的 */ public void closeVirtualSelectedReport(JTemplate selected) { - DesignModuleFactory.clearChartPropertyPane(); DesignTableDataManager.closeTemplate(selected); if (contains(selected) == -1) { return; @@ -340,6 +340,17 @@ public class HistoryTemplateListCache implements CallbackEvent { * @see HistoryTemplateListCache#load() */ public void stash() { + stashWorker = new SwingWorker() { + @Override + protected Boolean doInBackground() throws Exception { + _stash(); + return true; + } + }; + stashWorker.execute(); + + } + private void _stash() { FineLoggerFactory.getLogger().info("Env Change Template Stashing..."); if (stashFILEMap == null) { stashFILEMap = new HashMap(); @@ -365,6 +376,15 @@ public class HistoryTemplateListCache implements CallbackEvent { FineLoggerFactory.getLogger().info("Env Change Template Stashed."); } + private boolean checkStash() { + try { + return stashWorker.get(); + } catch (Exception e) { + FineLoggerFactory.getLogger().debug(e.getMessage(), e); + return false; + } + } + /** * 切换环境前将正在编辑的模板暂存起来后,在新环境重新读取一遍 *

@@ -373,6 +393,9 @@ public class HistoryTemplateListCache implements CallbackEvent { * @see HistoryTemplateListCache#stash() */ public void load() { + if (!checkStash()) { + return; + } FineLoggerFactory.getLogger().info("Env Change Template Loading..."); if (stashFILEMap != null && stashFILEMap.size() != 0) { int size = historyList.size(); @@ -490,4 +513,11 @@ public class HistoryTemplateListCache implements CallbackEvent { return false; } + public void replaceCurrentEditingTemplate(JTemplate jt) { + int index = contains(this.editingTemplate); + this.editingTemplate = jt; + historyList.set(index, jt); + MutilTempalteTabPane.getInstance().refreshOpenedTemplate(historyList); + MutilTempalteTabPane.getInstance().setSelectedIndex(contains(jt)); + } } 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 99cd17916..9fa676f94 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 @@ -11,11 +11,15 @@ import com.fr.design.gui.imenu.UIScrollPopUpMenu; 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.utils.DesignUtils; 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.general.ComparatorUtils; +import com.fr.general.IOUtils; import com.fr.log.FineLoggerFactory; import com.fr.stable.Constants; import com.fr.third.javax.annotation.Nonnull; @@ -23,6 +27,7 @@ import com.fr.third.javax.annotation.Nonnull; import javax.swing.BorderFactory; import javax.swing.ButtonModel; import javax.swing.Icon; +import javax.swing.ImageIcon; import javax.swing.JComponent; import javax.swing.JMenu; import javax.swing.JMenuItem; @@ -66,6 +71,8 @@ public class MutilTempalteTabPane extends JComponent { private static Icon CLOSE = BaseUtils.readIcon("/com/fr/design/images/buttonicon/close_icon.png"); private static Icon MOUSE_OVER_CLOSE = BaseUtils.readIcon("/com/fr/design/images/buttonicon/mouseoverclose icon.png"); private static Icon MOUSE_PRESS_CLOSE = BaseUtils.readIcon("/com/fr/design/images/buttonicon/pressclose icon.png"); + private static final Icon WHITE_SAVING_CLOSE_ICON = new ImageIcon(IOUtils.readImage("/com/fr/design/images/file/white_saving_close.gif")); + private static final Icon GREY_SAVING_CLOSE_ICON = new ImageIcon(IOUtils.readImage("/com/fr/design/images/file/grey_saving_close.gif")); private static final String ELLIPSIS = "..."; private static final int GAP = 5; private static final int SMALLGAP = 3; @@ -195,6 +202,9 @@ public class MutilTempalteTabPane extends JComponent { if (openedTemplate.size() == 1) { return; } + if (!TemplateSavingChecker.check()) { + return; + } SaveSomeTemplatePane saveSomeTempaltePane = new SaveSomeTemplatePane(false); //点击关闭其他模板,并且点击确定保存 if (saveSomeTempaltePane.showSavePane()) { @@ -380,8 +390,14 @@ public class MutilTempalteTabPane extends JComponent { selectedIcon = CLOSE; } if (i == selectedIndex) { + if (template.isSaving()) { + selectedIcon = WHITE_SAVING_CLOSE_ICON; + } startX[i - minPaintIndex] = paintSelectedTab(g2d, icon, templateStartX, name, selectedIcon); } else { + if (template.isSaving()) { + selectedIcon = GREY_SAVING_CLOSE_ICON; + } boolean isLeft = i < selectedIndex; startX[i - minPaintIndex] = paintUnSelectedTab(g2d, icon, templateStartX, name, selectedIcon, isLeft, mouseOveredIndex, i); } @@ -682,9 +698,15 @@ public class MutilTempalteTabPane extends JComponent { 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) { - specifiedTemplate.saveTemplate(); - FineLoggerFactory.getLogger().info(Toolkit.i18nText("Fine-Design_Basic_Template_Already_Saved", specifiedTemplate.getEditingFILE().getName())); - closeTpl(specifiedTemplate); + 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.getTarget().getTemplateID()); } else if (returnVal == JOptionPane.NO_OPTION) { closeTpl(specifiedTemplate); } @@ -919,8 +941,19 @@ public class MutilTempalteTabPane extends JComponent { closeIconIndex = getTemplateIndex(evtX); clodeMode = MOUSE_PRESS_CLOSE; //关闭close图标所在的模板{ - closeFormat(openedTemplate.get(closeIconIndex)); - closeSpecifiedTemplate(openedTemplate.get(closeIconIndex)); + 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; + } + } + closeFormat(template); + closeSpecifiedTemplate(template); DesignerContext.getDesignerFrame().getContentFrame().repaint(); isShowList = false; } else { @@ -934,7 +967,7 @@ public class MutilTempalteTabPane extends JComponent { //如果在权限编辑情况下,不允许切换到表单类型的工作簿 if (DesignerMode.isAuthorityEditing() && !openedTemplate.get(selectedIndex).isJWorkBook()) { DesignerContext.getDesignerFrame().addAndActivateJTemplate(openedTemplate.get(tempSelectedIndex)); - FineJOptionPane.showMessageDialog(MutilTempalteTabPane.this, Toolkit.i18nText("Fine-Design_Basic_Form_Authority_Edited_Cannot_Be_Supported") + FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Design_Basic_Form_Authority_Edited_Cannot_Be_Supported") + "!", Toolkit.i18nText("Fine-Design_Basic_Alert"), JOptionPane.WARNING_MESSAGE); MutilTempalteTabPane.this.repaint(); return; 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 e331d296e..7fef2e379 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 @@ -195,7 +195,7 @@ public class SaveSomeTemplatePane extends BasicPane { specifiedTemplate.stopEditing(); int returnVal = FineJOptionPane.showConfirmDialog(DesignerContext.getDesignerFrame(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Utils_Would_You_Like_To_Save") + " \"" + specifiedTemplate.getEditingFILE() + "\" ?", com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Confirm"), JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE); - if (returnVal == JOptionPane.YES_OPTION && specifiedTemplate.saveTemplate()) { + if (returnVal == JOptionPane.YES_OPTION) { specifiedTemplate.saveTemplate(); FineLoggerFactory.getLogger().info(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Template_Already_Saved", specifiedTemplate.getEditingFILE().getName())); } diff --git a/designer-base/src/main/java/com/fr/design/file/filter/ClassFilter.java b/designer-base/src/main/java/com/fr/design/file/filter/ClassFilter.java index d89c546a9..c04d80634 100644 --- a/designer-base/src/main/java/com/fr/design/file/filter/ClassFilter.java +++ b/designer-base/src/main/java/com/fr/design/file/filter/ClassFilter.java @@ -25,6 +25,7 @@ public class ClassFilter implements Filter { static { FILTER_SET.add("java.awt.image.BufferedImage"); FILTER_SET.add("sun.awt.AppContext"); + FILTER_SET.add("com.fr.poly.creator.ECBlockCreator"); } @Override diff --git a/designer-base/src/main/java/com/fr/design/gui/UILookAndFeel.java b/designer-base/src/main/java/com/fr/design/gui/UILookAndFeel.java index dc9cea2bd..4dbbc1af3 100644 --- a/designer-base/src/main/java/com/fr/design/gui/UILookAndFeel.java +++ b/designer-base/src/main/java/com/fr/design/gui/UILookAndFeel.java @@ -30,10 +30,12 @@ import com.fr.design.gui.itoolbar.UIToolBarSeparatorUI; import com.fr.design.gui.itooltip.UIToolTipBorder; import com.fr.design.gui.itree.UITreeUI; import com.fr.design.i18n.Toolkit; -import com.fr.log.FineLoggerFactory; import com.fr.general.IOUtils; +import com.fr.log.FineLoggerFactory; -import javax.swing.*; +import javax.swing.ImageIcon; +import javax.swing.UIDefaults; +import javax.swing.UIManager; import javax.swing.border.Border; import javax.swing.border.EmptyBorder; import javax.swing.plaf.BorderUIResource; @@ -171,6 +173,8 @@ public class UILookAndFeel extends MetalLookAndFeel { table.put("FileChooser.upFolderIcon", loadIcon("ParentDirectoryIcon.png", this)); table.put("OptionPane.errorIcon", loadIcon("Information_Icon_Error_32x32.png", this)); table.put("OptionPane.informationIcon", loadIcon("Information_Icon_OK_32x32.png", this)); + table.put("OptionPane.narrow.right", loadIcon("Icon_Narrow_Right_16x16.png", this)); + table.put("OptionPane.narrow.down", loadIcon("Icon_Narrow_Down_16x16.png", this)); table.put("OptionPane.warningIcon", loadIcon("WarningIcon.png", this)); table.put("OptionPane.questionIcon", loadIcon("QuestionIcon.png", this)); table.put("ScrollPane.border", new UIScrollPaneBorder()); @@ -201,7 +205,7 @@ public class UILookAndFeel extends MetalLookAndFeel { "com/fr/design/images/lookandfeel/" + fileName, UILookAndFeel.class); if (url == null) { - FineLoggerFactory.getLogger().error("Icon directory could not be resolved."); + FineLoggerFactory.getLogger().error(fileName + " :Icon directory could not be resolved."); return null; } } diff --git a/designer-base/src/main/java/com/fr/design/gui/chart/BaseChartPropertyPane.java b/designer-base/src/main/java/com/fr/design/gui/chart/BaseChartPropertyPane.java index 503b9472c..d4be14dcd 100644 --- a/designer-base/src/main/java/com/fr/design/gui/chart/BaseChartPropertyPane.java +++ b/designer-base/src/main/java/com/fr/design/gui/chart/BaseChartPropertyPane.java @@ -10,9 +10,6 @@ import com.fr.design.mainframe.DockingView; * @version 创建时间:2013-7-10 上午09:12:11 */ public abstract class BaseChartPropertyPane extends DockingView { - - public abstract void setSureProperty(); - /** * 设置是否支持单元格数据. */ @@ -22,7 +19,5 @@ public abstract class BaseChartPropertyPane extends DockingView { public abstract ChartEditPaneProvider getChartEditPane(); - public abstract void addChartEditPane(String plotID); - - //public abstract void clear(); + public abstract void updateChartEditPane(String plotID); } \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/gui/controlpane/CommonShortCutHandlers.java b/designer-base/src/main/java/com/fr/design/gui/controlpane/CommonShortCutHandlers.java index c5d2a51dd..094ef1c22 100644 --- a/designer-base/src/main/java/com/fr/design/gui/controlpane/CommonShortCutHandlers.java +++ b/designer-base/src/main/java/com/fr/design/gui/controlpane/CommonShortCutHandlers.java @@ -21,11 +21,9 @@ import java.util.Comparator; */ public class CommonShortCutHandlers { ListControlPaneProvider listControlPane; - JNameEdList nameableList; private CommonShortCutHandlers(ListControlPaneProvider listControlPane) { this.listControlPane = listControlPane; - this.nameableList = listControlPane.getNameableList(); } public static CommonShortCutHandlers newInstance(ListControlPaneProvider listControlPane) { @@ -43,19 +41,19 @@ public class CommonShortCutHandlers { public void onRemoveItem() { try { - nameableList.getCellEditor() + listControlPane.getNameableList().getCellEditor() .stopCellEditing(); } catch (Exception ignored) { } if (GUICoreUtils.removeJListSelectedNodes(SwingUtilities - .getWindowAncestor((Component) listControlPane), nameableList)) { + .getWindowAncestor((Component) listControlPane), listControlPane.getNameableList())) { listControlPane.checkButtonEnabled(); } } public void onCopyItem() { // p:选中的值. - ListModelElement selectedValue = (ListModelElement) nameableList.getSelectedValue(); + ListModelElement selectedValue = (ListModelElement) listControlPane.getNameableList().getSelectedValue(); if (selectedValue == null) { return; } @@ -76,47 +74,51 @@ public class CommonShortCutHandlers { } public void onMoveUpItem() { - int selectedIndex = nameableList.getSelectedIndex(); + int selectedIndex = listControlPane.getNameableList().getSelectedIndex(); if (selectedIndex == -1) { return; } // 上移 if (selectedIndex > 0) { - DefaultListModel listModel = (DefaultListModel) nameableList.getModel(); + DefaultListModel listModel = (DefaultListModel) listControlPane.getNameableList().getModel(); Object selecteObj1 = listModel.get(selectedIndex - 1); listModel.set(selectedIndex - 1, listModel.get(selectedIndex)); listModel.set(selectedIndex, selecteObj1); - nameableList.setSelectedIndex(selectedIndex - 1); - nameableList.ensureIndexIsVisible(selectedIndex - 1); + listControlPane.getNameableList().setSelectedIndex(selectedIndex - 1); + listControlPane.getNameableList().ensureIndexIsVisible(selectedIndex - 1); } } public void onMoveDownItem() { - int selectedIndex = nameableList.getSelectedIndex(); + int selectedIndex = listControlPane.getNameableList().getSelectedIndex(); if (selectedIndex == -1) { return; } - if (selectedIndex < nameableList.getModel().getSize() - 1) { - DefaultListModel listModel = (DefaultListModel) nameableList + if (selectedIndex < listControlPane.getNameableList().getModel().getSize() - 1) { + DefaultListModel listModel = (DefaultListModel) listControlPane.getNameableList() .getModel(); Object selecteObj1 = listModel.get(selectedIndex + 1); listModel.set(selectedIndex + 1, listModel.get(selectedIndex)); listModel.set(selectedIndex, selecteObj1); - nameableList.setSelectedIndex(selectedIndex + 1); - nameableList.ensureIndexIsVisible(selectedIndex + 1); + listControlPane.getNameableList().setSelectedIndex(selectedIndex + 1); + listControlPane.getNameableList().ensureIndexIsVisible(selectedIndex + 1); } } public void onSortItem(boolean isAtoZ) { + onSortItem(isAtoZ, listControlPane.getNameableList()); + } + + public void onSortItem(boolean isAtoZ, JNameEdList nameEdList) { // p:选中的值. - Object selectedValue = nameableList.getSelectedValue(); + Object selectedValue = nameEdList.getSelectedValue(); - DefaultListModel listModel = (DefaultListModel) nameableList + DefaultListModel listModel = (DefaultListModel) nameEdList .getModel(); Nameable[] nameableArray = new Nameable[listModel.getSize()]; if (nameableArray.length <= 0) { @@ -156,12 +158,12 @@ public class CommonShortCutHandlers { // p:需要选中以前的那个值. if (selectedValue != null) { - nameableList.setSelectedValue(selectedValue, true); + nameEdList.setSelectedValue(selectedValue, true); } listControlPane.checkButtonEnabled(); // p:需要repaint. - nameableList.repaint(); + nameEdList.repaint(); } private String createUnrepeatedCopyName(String suffix) { diff --git a/designer-base/src/main/java/com/fr/design/gui/controlpane/ListControlPaneHelper.java b/designer-base/src/main/java/com/fr/design/gui/controlpane/ListControlPaneHelper.java index 76255d96b..7fe1a27ef 100644 --- a/designer-base/src/main/java/com/fr/design/gui/controlpane/ListControlPaneHelper.java +++ b/designer-base/src/main/java/com/fr/design/gui/controlpane/ListControlPaneHelper.java @@ -4,18 +4,41 @@ import com.fr.design.beans.BasicBeanPane; import com.fr.design.dialog.FineJOptionPane; import com.fr.design.gui.ilist.JNameEdList; import com.fr.design.gui.ilist.ListModelElement; +import com.fr.design.gui.ilist.UINameEdList; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.os.impl.PopupDialogSaveAction; +import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.form.event.Listener; +import com.fr.general.NameObject; import com.fr.stable.Nameable; import com.fr.stable.StringUtils; +import com.fr.stable.os.support.OSSupportCenter; import javax.swing.DefaultListModel; -import javax.swing.JOptionPane; +import javax.swing.JList; +import javax.swing.JPopupMenu; +import javax.swing.SwingUtilities; import java.awt.Component; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Toolkit; +import java.awt.Window; +import java.awt.event.InputEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; /** * 存放一些公用的方法 * Created by plough on 2018/8/13. */ class ListControlPaneHelper { + private static final int EDIT_RANGE = 25; // 编辑按钮的x坐标范围 + private ListControlPaneProvider listControlPane; private ListControlPaneHelper(ListControlPaneProvider listControlPane) { @@ -110,4 +133,123 @@ class ListControlPaneHelper { } + protected void popupEditDialog(Point mousePos, UINameEdList nameableList, UIControlPane controlPane) { + int editingIndex = nameableList.getSelectedIndex(); + Rectangle currentCellBounds = nameableList.getCellBounds(editingIndex, editingIndex); + if (editingIndex < 0 || (mousePos != null && !currentCellBounds.contains(mousePos))) { + return; + } + Window popupEditDialog = controlPane.getPopupEditDialog(); + popupEditDialog.setLocation(getPopupDialogLocation(nameableList, popupEditDialog)); + if (popupEditDialog instanceof UIControlPane.PopupEditDialog) { + ((UIControlPane.PopupEditDialog) popupEditDialog).setTitle(getSelectedName()); + } + popupEditDialog.setVisible(true); + PopupDialogSaveAction osBasedAction = OSSupportCenter.getAction(PopupDialogSaveAction.class); + osBasedAction.register(controlPane, popupEditDialog); + } + + private Point getPopupDialogLocation(UINameEdList nameableList, Window popupEditDialog) { + Point resultPos = new Point(0, 0); + Point listPos = nameableList.getLocationOnScreen(); + resultPos.x = listPos.x - popupEditDialog.getWidth(); + resultPos.y = listPos.y + (nameableList.getSelectedIndex() - 1) * EDIT_RANGE; + + // 当对象在屏幕上的位置比较靠下时,往下移动弹窗至与属性面板平齐 + Window frame = DesignerContext.getDesignerFrame(); + // 不能太低 + int maxY = frame.getLocationOnScreen().y + frame.getHeight() - popupEditDialog.getHeight(); + if (resultPos.y > maxY) { + resultPos.y = maxY; + } + // 也不能太高 + int minY = frame.getLocationOnScreen().y + EDIT_RANGE; + if (resultPos.y < minY) { + resultPos.y = minY; + } + + // 当在左侧显示不下时,在右侧弹出弹窗 + if (resultPos.x < 0) { + resultPos.x = listPos.x + nameableList.getParent().getWidth(); + } + // 如果右侧显示不下,可以向左移动 + int maxX = frame.getLocationOnScreen().x + frame.getWidth() - popupEditDialog.getWidth() - EDIT_RANGE; + if (resultPos.x > maxX) { + resultPos.x = maxX; + } + + return resultPos; + } + + /* + * UINameEdList的鼠标事件 + */ + protected MouseListener getListMouseListener(UINameEdList nameableList, UIControlPane controlPane) { + return new MouseAdapter() { + @Override + public void mouseReleased(MouseEvent evt) { + nameableList.stopEditing(); + if (evt.getClickCount() >= 2 + && SwingUtilities.isLeftMouseButton(evt) && evt.getX() > EDIT_RANGE) { + nameableList.editItemAt(nameableList.getSelectedIndex()); + } else if (SwingUtilities.isLeftMouseButton(evt) && evt.getX() <= EDIT_RANGE) { + popupEditDialog(evt.getPoint(), nameableList, controlPane); + } + + // peter:处理右键的弹出菜单 + if (!SwingUtilities.isRightMouseButton(evt)) { + return; + } + + // peter: 注意,在checkButtonEnabled()方法里面,设置了所有的Action的Enabled. + checkButtonEnabled(); + + // p:右键菜单. + JPopupMenu popupMenu = new JPopupMenu(); + + for (ShortCut4JControlPane sj : listControlPane.getShorts()) { + sj.getShortCut().intoJPopupMenu(popupMenu); + } + + // peter: 只有弹出菜单有子菜单的时候,才需要弹出来. + GUICoreUtils.showPopupMenu(popupMenu, nameableList, evt.getX() - 1, + evt.getY() - 1); + } + + @Override + public void mouseClicked(MouseEvent e) { + JList list = (JList) e.getSource(); + if (list.locationToIndex(e.getPoint()) == -1 && !e.isShiftDown() + && !isMenuShortcutKeyDown(e)) { + list.clearSelection(); + } + } + + private boolean isMenuShortcutKeyDown(InputEvent event) { + return (event.getModifiers() & Toolkit.getDefaultToolkit() + .getMenuShortcutKeyMask()) != 0; + } + + @Override + public void mouseMoved(MouseEvent e) { + + } + }; + } + + public Map> processCatalog(List nameObjectList) { + Map> map = new HashMap<>(); + for (NameObject nameObject : nameObjectList) { + Listener listener = (Listener) nameObject.getObject(); + if (StringUtils.isNotEmpty(listener.getName())) { + nameObject.setName(listener.getName()); + } + List list = map.computeIfAbsent(listener.getEventName(), k -> new ArrayList<>()); + list.add(nameObject); + } + return map; + } + + + } diff --git a/designer-base/src/main/java/com/fr/design/gui/controlpane/UIControlPane.java b/designer-base/src/main/java/com/fr/design/gui/controlpane/UIControlPane.java index 04427b337..b15b9eab9 100644 --- a/designer-base/src/main/java/com/fr/design/gui/controlpane/UIControlPane.java +++ b/designer-base/src/main/java/com/fr/design/gui/controlpane/UIControlPane.java @@ -49,7 +49,7 @@ import java.awt.event.WindowEvent; /** * Created by plough on 2017/7/21. */ -abstract class UIControlPane extends JControlPane { +public abstract class UIControlPane extends JControlPane { private UIToolbar topToolBar; protected Window popupEditDialog; private static final int TOP_TOOLBAR_HEIGHT = 20; @@ -78,7 +78,7 @@ abstract class UIControlPane extends JControlPane { initCardPane(); if (isNewStyle()) { - getPopupEditDialog(cardPane); + createPopupEditDialog(cardPane); this.add(getLeftPane(), BorderLayout.CENTER); this.setBorder(BorderFactory.createEmptyBorder(10, 10, 15, 10)); } else { @@ -100,7 +100,11 @@ abstract class UIControlPane extends JControlPane { this.checkButtonEnabled(); } - private void getPopupEditDialog(JPanel cardPane) { + protected Window getPopupEditDialog(){ + return this.popupEditDialog; + } + + private void createPopupEditDialog(JPanel cardPane) { popupEditDialog = new PopupEditDialog(cardPane); } @@ -400,4 +404,4 @@ abstract class UIControlPane extends JControlPane { return new Dimension(super.getPreferredSize().width, 28); } } -} \ No newline at end of file +} diff --git a/designer-base/src/main/java/com/fr/design/gui/controlpane/UIListControlPane.java b/designer-base/src/main/java/com/fr/design/gui/controlpane/UIListControlPane.java index ec76f5bf7..b7b8674be 100644 --- a/designer-base/src/main/java/com/fr/design/gui/controlpane/UIListControlPane.java +++ b/designer-base/src/main/java/com/fr/design/gui/controlpane/UIListControlPane.java @@ -6,32 +6,18 @@ import com.fr.design.gui.icontainer.UIScrollPane; import com.fr.design.gui.ilist.JNameEdList; import com.fr.design.gui.ilist.ListModelElement; import com.fr.design.gui.ilist.UINameEdList; -import com.fr.design.mainframe.DesignerContext; -import com.fr.design.os.impl.PopupDialogSaveAction; -import com.fr.design.utils.gui.GUICoreUtils; import com.fr.stable.ArrayUtils; import com.fr.stable.Nameable; -import com.fr.stable.os.support.OSSupportCenter; import javax.swing.DefaultListModel; -import javax.swing.JList; import javax.swing.JPanel; -import javax.swing.JPopupMenu; import javax.swing.ListSelectionModel; -import javax.swing.SwingUtilities; import javax.swing.event.ListDataEvent; import javax.swing.event.ListDataListener; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import java.awt.BorderLayout; import java.awt.Point; -import java.awt.Rectangle; -import java.awt.Toolkit; -import java.awt.Window; -import java.awt.event.InputEvent; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; @@ -41,11 +27,8 @@ import java.lang.reflect.InvocationTargetException; public abstract class UIListControlPane extends UIControlPane implements ListControlPaneProvider { private static final String LIST_NAME = "UIControl_List"; - private static final int EDIT_RANGE = 25; // 编辑按钮的x坐标范围 protected UINameEdList nameableList; - private int editingIndex; - protected String selectedName; protected boolean isPopulating = false; private CommonShortCutHandlers commonHandlers; private ListControlPaneHelper helper; @@ -93,7 +76,7 @@ public abstract class UIListControlPane extends UIControlPane implements ListCon nameableList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); - nameableList.addMouseListener(getListMouseListener()); + nameableList.addMouseListener(getHelper().getListMouseListener(nameableList, this)); nameableList.addListSelectionListener(new ListSelectionListener() { public void valueChanged(ListSelectionEvent evt) { // richie:避免多次update和populate大大降低效率 @@ -139,7 +122,7 @@ public abstract class UIListControlPane extends UIControlPane implements ListCon saveSettings(); } }; - nameEdList.setCellRenderer(new UINameableListCellRenderer(this)); + nameEdList.setCellRenderer(new UINameableListCellRenderer(this.isNewStyle(), this.creators)); return nameEdList; } @@ -181,13 +164,6 @@ public abstract class UIListControlPane extends UIControlPane implements ListCon } - /** - * 获取选中的名字 - */ - public String getSelectedName() { - return getHelper().getSelectedName(); - } - /** * 添加 Nameable * @@ -209,51 +185,10 @@ public abstract class UIListControlPane extends UIControlPane implements ListCon protected void popupEditDialog(Point mousePos) { if (isNewStyle()) { - Rectangle currentCellBounds = nameableList.getCellBounds(editingIndex, editingIndex); - if (editingIndex < 0 || (mousePos != null && !currentCellBounds.contains(mousePos))) { - return; - } - popupEditDialog.setLocation(getPopupDialogLocation()); - if (popupEditDialog instanceof PopupEditDialog) { - ((PopupEditDialog)popupEditDialog).setTitle(getSelectedName()); - } - popupEditDialog.setVisible(true); - PopupDialogSaveAction osBasedAction = OSSupportCenter.getAction(PopupDialogSaveAction.class); - osBasedAction.register(this, popupEditDialog); + getHelper().popupEditDialog(mousePos, nameableList, this); } } - private Point getPopupDialogLocation() { - Point resultPos = new Point(0, 0); - Point listPos = nameableList.getLocationOnScreen(); - resultPos.x = listPos.x - popupEditDialog.getWidth(); - resultPos.y = listPos.y + (nameableList.getSelectedIndex() - 1) * EDIT_RANGE; - - // 当对象在屏幕上的位置比较靠下时,往下移动弹窗至与属性面板平齐 - Window frame = DesignerContext.getDesignerFrame(); - // 不能太低 - int maxY = frame.getLocationOnScreen().y + frame.getHeight() - popupEditDialog.getHeight(); - if (resultPos.y > maxY) { - resultPos.y = maxY; - } - // 也不能太高 - int minY = frame.getLocationOnScreen().y + EDIT_RANGE; - if (resultPos.y < minY) { - resultPos.y = minY; - } - - // 当在左侧显示不下时,在右侧弹出弹窗 - if (resultPos.x < 0) { - resultPos.x = listPos.x + nameableList.getParent().getWidth(); - } - // 如果右侧显示不下,可以向左移动 - int maxX = frame.getLocationOnScreen().x + frame.getWidth() - popupEditDialog.getWidth() - EDIT_RANGE; - if (resultPos.x > maxX) { - resultPos.x = maxX; - } - - return resultPos; - } /** * 生成不重复的名字 @@ -301,65 +236,6 @@ public abstract class UIListControlPane extends UIControlPane implements ListCon return getModel().getSize() > 0 && nameableList.getSelectedIndex() != -1; } - /* - * UINameEdList的鼠标事件 - */ - private MouseListener getListMouseListener() { - return new MouseAdapter() { - @Override - public void mouseReleased(MouseEvent evt) { - nameableList.stopEditing(); - if (evt.getClickCount() >= 2 - && SwingUtilities.isLeftMouseButton(evt) && evt.getX() > EDIT_RANGE) { - editingIndex = nameableList.getSelectedIndex(); - selectedName = nameableList.getNameAt(editingIndex); - nameableList.editItemAt(nameableList.getSelectedIndex()); - } else if (SwingUtilities.isLeftMouseButton(evt) && evt.getX() <= EDIT_RANGE) { - editingIndex = nameableList.getSelectedIndex(); - selectedName = nameableList.getNameAt(editingIndex); - popupEditDialog(evt.getPoint()); - } - - // peter:处理右键的弹出菜单 - if (!SwingUtilities.isRightMouseButton(evt)) { - return; - } - - // peter: 注意,在checkButtonEnabled()方法里面,设置了所有的Action的Enabled. - checkButtonEnabled(); - - // p:右键菜单. - JPopupMenu popupMenu = new JPopupMenu(); - - for (ShortCut4JControlPane sj : getShorts()) { - sj.getShortCut().intoJPopupMenu(popupMenu); - } - - // peter: 只有弹出菜单有子菜单的时候,才需要弹出来. - GUICoreUtils.showPopupMenu(popupMenu, nameableList, evt.getX() - 1, - evt.getY() - 1); - } - - @Override - public void mouseClicked(MouseEvent e) { - JList list = (JList) e.getSource(); - if (list.locationToIndex(e.getPoint()) == -1 && !e.isShiftDown() - && !isMenuShortcutKeyDown(e)) { - list.clearSelection(); - } - } - - private boolean isMenuShortcutKeyDown(InputEvent event) { - return (event.getModifiers() & Toolkit.getDefaultToolkit() - .getMenuShortcutKeyMask()) != 0; - } - - @Override - public void mouseMoved(MouseEvent e) { - - } - }; - } /** * 检查按钮可用状态 Check button enabled. diff --git a/designer-base/src/main/java/com/fr/design/gui/controlpane/UINameableListCellRenderer.java b/designer-base/src/main/java/com/fr/design/gui/controlpane/UINameableListCellRenderer.java index b66ee1ef2..40d8d98fa 100644 --- a/designer-base/src/main/java/com/fr/design/gui/controlpane/UINameableListCellRenderer.java +++ b/designer-base/src/main/java/com/fr/design/gui/controlpane/UINameableListCellRenderer.java @@ -1,12 +1,8 @@ package com.fr.design.gui.controlpane; -import com.fr.base.BaseUtils; import com.fr.design.constants.UIConstants; -import com.fr.design.gui.ibutton.UIButton; import com.fr.design.gui.ilable.UILabel; import com.fr.design.gui.ilist.ListModelElement; -import com.fr.design.gui.itextfield.UITextField; -import com.fr.design.utils.gui.GUICoreUtils; import com.fr.stable.Nameable; import sun.swing.DefaultLookup; @@ -14,8 +10,6 @@ import javax.swing.*; import javax.swing.border.Border; import javax.swing.border.EmptyBorder; import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; /** * Nameable的ListCellRenerer @@ -32,12 +26,14 @@ public class UINameableListCellRenderer extends private static final int BUTTON_WIDTH = 25; private UILabel editButton; // "编辑按钮",实际上是一个 UILabel,由列表项(UIListControlPane)统一处理点击事件 private UILabel label; - private UIListControlPane listControlPane; + private boolean isNewStyle; + private NameableCreator[] creators; private Color initialLabelForeground; - public UINameableListCellRenderer(UIListControlPane listControlPane) { + public UINameableListCellRenderer( boolean isNewStyle, NameableCreator[] creators) { super(); - this.listControlPane = listControlPane; + this.isNewStyle = isNewStyle; + this.creators = creators; initComponents(); setOpaque(true); setBorder(getNoFocusBorder()); @@ -50,7 +46,7 @@ public class UINameableListCellRenderer extends return new Dimension(BUTTON_WIDTH, BUTTON_WIDTH); } }; - editButton.setIcon(listControlPane.isNewStyle() ? UIConstants.LIST_EDIT_ICON : UIConstants.CPT_ICON); + editButton.setIcon(isNewStyle ? UIConstants.LIST_EDIT_ICON : UIConstants.CPT_ICON); editButton.setBorder(BorderFactory.createMatteBorder(0, 0, 0, 1, UIConstants.LIST_ITEM_SPLIT_LINE)); editButton.setHorizontalAlignment(SwingConstants.CENTER); label = new UILabel(); @@ -92,7 +88,7 @@ public class UINameableListCellRenderer extends setBackground(bg == null ? list.getSelectionBackground() : bg); setForeground(fg == null ? list.getSelectionForeground() : fg); label.setForeground(Color.WHITE); - if (listControlPane.isNewStyle()) { + if (isNewStyle) { editButton.setIcon(UIConstants.LIST_EDIT_WHITE_ICON); } } @@ -100,7 +96,7 @@ public class UINameableListCellRenderer extends setBackground(list.getBackground()); setForeground(list.getForeground()); label.setForeground(initialLabelForeground); - if (listControlPane.isNewStyle()) { + if (isNewStyle) { editButton.setIcon(UIConstants.LIST_EDIT_ICON); } } @@ -114,7 +110,7 @@ public class UINameableListCellRenderer extends Nameable wrappee = ((ListModelElement) value).wrapper; this.setText(((ListModelElement) value).wrapper.getName()); - for (NameableCreator creator : listControlPane.creators()) { + for (NameableCreator creator : creators) { if (creator.menuIcon() != null && creator.acceptObject2Populate(wrappee) != null) { this.setToolTipText(creator.createTooltip()); break; @@ -124,4 +120,4 @@ public class UINameableListCellRenderer extends return this; } -} \ No newline at end of file +} diff --git a/designer-base/src/main/java/com/fr/design/gui/ibutton/UIForbiddenButton.java b/designer-base/src/main/java/com/fr/design/gui/ibutton/UIForbiddenButton.java new file mode 100644 index 000000000..d7173d5f4 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/gui/ibutton/UIForbiddenButton.java @@ -0,0 +1,64 @@ +package com.fr.design.gui.ibutton; + +import com.fr.base.CellBorderStyle; +import com.fr.design.file.HistoryTemplateListCache; +import com.fr.design.mainframe.JTemplate; +import javax.swing.Action; +import javax.swing.Icon; +import javax.swing.plaf.ButtonUI; + +/** + * @author hades + * @version 10.0 + * Created by hades on 2021/4/9 + */ +public class UIForbiddenButton extends UIButton { + + public UIForbiddenButton() { + super(); + } + + public UIForbiddenButton(String string) { + super(string); + } + + public UIForbiddenButton(Icon icon) { + super(icon); + } + + public UIForbiddenButton(Action action) { + super(action); + } + + public UIForbiddenButton(String text, Icon icon) { + super(text, icon); + } + + public UIForbiddenButton(Icon normal, Icon rollOver, Icon pressed) { + super(normal, rollOver, pressed); + } + + public UIForbiddenButton(String resource, boolean needSetDisabledIcon) { + super(resource, needSetDisabledIcon); + } + + @Override + public CellBorderStyle getBorderStyle() { + return super.getBorderStyle(); + } + + @Override + public boolean isEnabled() { + JTemplate template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + boolean enabled = true; + if (template != null) { + enabled = super.isEnabled() && template.checkEnable(); + } + return enabled; + } + + @Override + public ButtonUI getUI() { + return new UIForbiddenButtonUI(); + } +} diff --git a/designer-base/src/main/java/com/fr/design/gui/ibutton/UIForbiddenButtonUI.java b/designer-base/src/main/java/com/fr/design/gui/ibutton/UIForbiddenButtonUI.java new file mode 100644 index 000000000..d8f51f62b --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/gui/ibutton/UIForbiddenButtonUI.java @@ -0,0 +1,18 @@ +package com.fr.design.gui.ibutton; + +import java.awt.Graphics; +import javax.swing.JComponent; + +/** + * @author hades + * @version 10.0 + * Created by hades on 2021/4/11 + */ +public class UIForbiddenButtonUI extends UIButtonUI { + + @Override + public void paint(Graphics g, JComponent c) { + super.paint(g, c); + c.setEnabled(c.isEnabled()); + } +} diff --git a/designer-base/src/main/java/com/fr/design/gui/ibutton/UISaveForbiddenButton.java b/designer-base/src/main/java/com/fr/design/gui/ibutton/UISaveForbiddenButton.java new file mode 100644 index 000000000..7d65df421 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/gui/ibutton/UISaveForbiddenButton.java @@ -0,0 +1,56 @@ +package com.fr.design.gui.ibutton; + +import com.fr.design.file.HistoryTemplateListCache; +import com.fr.design.mainframe.JTemplate; +import javax.swing.Action; +import javax.swing.Icon; +import javax.swing.plaf.ButtonUI; + +/** + * @author hades + * @version 10.0 + * Created by hades on 2021/4/10 + */ +public class UISaveForbiddenButton extends UIButton { + public UISaveForbiddenButton() { + } + + public UISaveForbiddenButton(String string) { + super(string); + } + + public UISaveForbiddenButton(Icon icon) { + super(icon); + } + + public UISaveForbiddenButton(Action action) { + super(action); + } + + public UISaveForbiddenButton(String text, Icon icon) { + super(text, icon); + } + + public UISaveForbiddenButton(Icon normal, Icon rollOver, Icon pressed) { + super(normal, rollOver, pressed); + } + + public UISaveForbiddenButton(String resource, boolean needSetDisabledIcon) { + super(resource, needSetDisabledIcon); + } + + @Override + public boolean isEnabled() { + JTemplate template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + boolean enabled = true; + if (template != null) { + enabled = !template.isSaving(); + } + return enabled; + } + + @Override + public ButtonUI getUI() { + return new UISaveForbiddenButtonUI(); + } +} diff --git a/designer-base/src/main/java/com/fr/design/gui/ibutton/UISaveForbiddenButtonUI.java b/designer-base/src/main/java/com/fr/design/gui/ibutton/UISaveForbiddenButtonUI.java new file mode 100644 index 000000000..47be05124 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/gui/ibutton/UISaveForbiddenButtonUI.java @@ -0,0 +1,18 @@ +package com.fr.design.gui.ibutton; + +import java.awt.Graphics; +import javax.swing.JComponent; + +/** + * @author hades + * @version 10.0 + * Created by hades on 2021/4/14 + */ +public class UISaveForbiddenButtonUI extends UIButtonUI { + + @Override + public void paint(Graphics g, JComponent c) { + super.paint(g, c); + c.setEnabled(c.isEnabled()); + } +} diff --git a/designer-base/src/main/java/com/fr/design/gui/icombobox/FRTreeComboBox.java b/designer-base/src/main/java/com/fr/design/gui/icombobox/FRTreeComboBox.java index a7a913335..8fe79d41e 100644 --- a/designer-base/src/main/java/com/fr/design/gui/icombobox/FRTreeComboBox.java +++ b/designer-base/src/main/java/com/fr/design/gui/icombobox/FRTreeComboBox.java @@ -597,6 +597,10 @@ public class FRTreeComboBox extends UIComboBox { return this.item; } + public boolean isSetting() { + return setting; + } + public void insertUpdate(DocumentEvent e) { changeHandler(); } @@ -614,11 +618,19 @@ public class FRTreeComboBox extends UIComboBox { return; } setPopupVisible(true); + search(); + } + + /** + * 模糊搜索,选中首个匹配项 + */ + protected void search() { this.item = textField.getText(); + tree.updateUI(); TreeNode root = (TreeNode) tree.getModel().getRoot(); TreePath parent = new TreePath(root); TreeNode node = (TreeNode) parent.getLastPathComponent(); - dealSamePath(parent,node,textField); + dealSamePath(parent, node, textField); this.getEditorComponent().requestFocus(); } diff --git a/designer-base/src/main/java/com/fr/design/gui/icombobox/LazyComboBox.java b/designer-base/src/main/java/com/fr/design/gui/icombobox/LazyComboBox.java index 300790457..61df2c9c6 100644 --- a/designer-base/src/main/java/com/fr/design/gui/icombobox/LazyComboBox.java +++ b/designer-base/src/main/java/com/fr/design/gui/icombobox/LazyComboBox.java @@ -62,6 +62,12 @@ public abstract class LazyComboBox extends UIComboBox implements PopupMenuListen this.setModel(new DefaultComboBoxModel<>(new Object[]{anObject})); super.setSelectedItem(anObject); } + + } + + private void setSelectedItemWithDocumentChange(Object anObject) { + initialSelected = anObject; + super.setSelectedItem(anObject); } @Override @@ -183,7 +189,7 @@ public abstract class LazyComboBox extends UIComboBox implements PopupMenuListen } filtering = true; String xx = textField.getText(); - LazyComboBox.this.setSelectedItem(xx); + LazyComboBox.this.setSelectedItemWithDocumentChange(xx); this.item = textField.getText(); setPopupVisible(true); diff --git a/designer-base/src/main/java/com/fr/design/gui/icombobox/SearchPreTaskTreeComboBox.java b/designer-base/src/main/java/com/fr/design/gui/icombobox/SearchPreTaskTreeComboBox.java new file mode 100644 index 000000000..2d936d896 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/gui/icombobox/SearchPreTaskTreeComboBox.java @@ -0,0 +1,77 @@ +package com.fr.design.gui.icombobox; + +import com.fr.log.FineLoggerFactory; + +import javax.swing.JTree; +import javax.swing.SwingWorker; +import javax.swing.tree.TreeCellRenderer; +import java.util.concurrent.FutureTask; + +/** + * 模糊搜索前需执行完前置任务的TreeComboBox + * @author Lucian.Chen + * @version 10.0 + * Created by Lucian.Chen on 2021/4/14 + */ +public class SearchPreTaskTreeComboBox extends FRTreeComboBox { + + /** + * 模糊搜索前任务 + */ + private FutureTask preSearchTask; + + public SearchPreTaskTreeComboBox(JTree tree, TreeCellRenderer renderer, boolean editable) { + super(tree, renderer, editable); + } + + public FutureTask getPreSearchTask() { + return preSearchTask; + } + + public void setPreSearchTask(FutureTask preSearchTask) { + this.preSearchTask = preSearchTask; + } + + protected UIComboBoxEditor createEditor() { + return new SearchPreTaskComboBoxEditor(this); + } + + private class SearchPreTaskComboBoxEditor extends FrTreeSearchComboBoxEditor { + + public SearchPreTaskComboBoxEditor(FRTreeComboBox comboBox) { + super(comboBox); + } + + protected void changeHandler() { + if (isSetting()) { + return; + } + setPopupVisible(true); + new SwingWorker() { + @Override + protected Void doInBackground() { + FutureTask task = getPreSearchTask(); + try { + // 确保模糊搜索前任务执行完成后,再进行模糊搜索 + if (task != null) { + task.get(); + } + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + if (task != null) { + // 任务执行后置空,否则会被别的操作重复触发 + setPreSearchTask(null); + } + return null; + } + + @Override + protected void done() { + // 模糊搜索 + search(); + } + }.execute(); + } + } +} diff --git a/designer-base/src/main/java/com/fr/design/gui/itextfield/UINumberField.java b/designer-base/src/main/java/com/fr/design/gui/itextfield/UINumberField.java index f4437a9c4..0d1287d8c 100644 --- a/designer-base/src/main/java/com/fr/design/gui/itextfield/UINumberField.java +++ b/designer-base/src/main/java/com/fr/design/gui/itextfield/UINumberField.java @@ -4,7 +4,6 @@ import com.fr.base.Utils; import com.fr.general.ComparatorUtils; import com.fr.stable.CoreConstants; import com.fr.stable.StringUtils; - import javax.swing.text.AttributeSet; import javax.swing.text.BadLocationException; import javax.swing.text.PlainDocument; diff --git a/designer-base/src/main/java/com/fr/design/gui/itoolbar/UIToolbar.java b/designer-base/src/main/java/com/fr/design/gui/itoolbar/UIToolbar.java index d2cca4b48..347dd768f 100644 --- a/designer-base/src/main/java/com/fr/design/gui/itoolbar/UIToolbar.java +++ b/designer-base/src/main/java/com/fr/design/gui/itoolbar/UIToolbar.java @@ -1,8 +1,11 @@ package com.fr.design.gui.itoolbar; -import javax.swing.*; -import java.awt.*; +import com.fr.design.file.HistoryTemplateListCache; +import com.fr.design.mainframe.JTemplate; +import java.awt.Component; +import java.awt.FlowLayout; import java.util.ArrayList; +import javax.swing.JToolBar; public class UIToolbar extends JToolBar { @@ -31,4 +34,14 @@ public class UIToolbar extends JToolBar { } } } + + public void refreshUIToolBar() { + JTemplate template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + if (template != null) { + for (int i = 0; i < getComponentCount(); i++) { + Component component = getComponents()[i]; + component.setEnabled(template.checkEnable()); + } + } + } } \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/layout/TableLayoutHelper.java b/designer-base/src/main/java/com/fr/design/layout/TableLayoutHelper.java index d394f43ee..e66452402 100644 --- a/designer-base/src/main/java/com/fr/design/layout/TableLayoutHelper.java +++ b/designer-base/src/main/java/com/fr/design/layout/TableLayoutHelper.java @@ -233,7 +233,7 @@ public class TableLayoutHelper { container.repaint(); } - private static void addComponent2ResultPane(Component[][] components, double[] rowSize, double[] columnSize, JPanel resultPane) { + public static void addComponent2ResultPane(Component[][] components, double[] rowSize, double[] columnSize, JPanel resultPane) { for (int i = 0; i < components.length; i++) { if (i >= rowSize.length) { 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 cb04a942e..d610b9862 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 @@ -133,6 +133,8 @@ public class CenterRegionContainerPane extends JPanel { combineUp.add(jComponent); } } + //添加检测按钮 + addCheckButton(); } //添加分享按钮 addShareButton(); @@ -158,6 +160,18 @@ public class CenterRegionContainerPane extends JPanel { } } + private void addCheckButton() { + JTemplate jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + if (jt == null) { + return; + } + combineUp.addSeparator(new Dimension(2, 16)); + UIButton[] checkButtons = jt.createCheckButton(); + for (UIButton checkButton : checkButtons) { + combineUp.add(checkButton); + } + } + private void addShareButton() { JTemplate jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); @@ -227,4 +241,11 @@ public class CenterRegionContainerPane extends JPanel { return centerTemplateCardPane; } + protected void refreshUIToolBar() { + if (toolbarComponent instanceof UIToolbar) { + ((UIToolbar ) toolbarComponent).refreshUIToolBar(); + } + combineUp.refreshUIToolBar(); + } + } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/ComponentReuseNotifyUtil.java b/designer-base/src/main/java/com/fr/design/mainframe/ComponentReuseNotifyUtil.java new file mode 100644 index 000000000..4ab10194c --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/ComponentReuseNotifyUtil.java @@ -0,0 +1,39 @@ +package com.fr.design.mainframe; + +import com.fr.design.DesignerEnvManager; +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.reuse.ComponentReuseNotificationInfo; +import com.fr.design.mainframe.toast.DesignerToastMsgUtil; +import com.fr.design.notification.SnapChat; +import com.fr.design.notification.SnapChatFactory; +import com.fr.design.notification.SnapChatKey; + +/** + * Created by kerry on 5/8/21 + */ +public class ComponentReuseNotifyUtil { + private static final String COMPONENT_SNAP_CHAT_KEY = "com.fr.component.share-components"; + + private ComponentReuseNotifyUtil() { + + } + + public static void enterWidgetLibExtraAction(boolean needValidRead) { + if (ComponentReuseNotificationInfo.getInstance().isClickedWidgetLib()) { + return; + } + SnapChat snapChat = SnapChatFactory.createSnapChat(false, new SnapChatKey() { + @Override + public String calc() { + return COMPONENT_SNAP_CHAT_KEY; + } + }); + if (snapChat.hasRead() && needValidRead) { + DesignerToastMsgUtil.toastPrompt(Toolkit.i18nText("Fine-Design_Component_Reuse_Merge_Prompt")); + } + ComponentReuseNotificationInfo.getInstance().setClickedWidgetLib(true); + DesignerEnvManager.getEnvManager().saveXMLFile(); + } + + +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/DesignOperationEvent.java b/designer-base/src/main/java/com/fr/design/mainframe/DesignOperationEvent.java new file mode 100644 index 000000000..5357cefbd --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/DesignOperationEvent.java @@ -0,0 +1,15 @@ +package com.fr.design.mainframe; + +import com.fr.event.Event; +import com.fr.event.Null; + +/** + * Created by kerry on 4/28/21 + */ +public enum DesignOperationEvent implements Event { + + CELL_STYLE_MODIFY, + + CELL_IMAGE_VALUE_MODIFY + +} 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 0c6d0d7cf..8c46a1bbf 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 @@ -4,6 +4,7 @@ package com.fr.design.mainframe; import com.fr.base.BaseUtils; +import com.fr.base.chart.exception.ChartNotFoundException; import com.fr.design.DesignModelAdapter; import com.fr.design.DesignerEnvManager; import com.fr.design.ExtraDesignClassManager; @@ -64,6 +65,7 @@ import javax.swing.JPanel; import javax.swing.UIManager; import javax.swing.WindowConstants; import java.awt.BorderLayout; +import java.awt.Component; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Point; @@ -144,6 +146,10 @@ public class DesignerFrame extends JFrame implements JTemplateActionListener, Ta @Override public void windowClosing(WindowEvent e) { + // 关闭前check + if (!TemplateSavingChecker.check()) { + return; + } //关闭前当前模板 停止编辑 HistoryTemplateListCache.getInstance().getCurrentEditingTemplate().stopEditing(); SaveSomeTemplatePane saveSomeTempaltePane = new SaveSomeTemplatePane(true); @@ -334,7 +340,7 @@ public class DesignerFrame extends JFrame implements JTemplateActionListener, Ta designerOpenedListenerList.clear(); } - protected DesktopCardPane getCenterTemplateCardPane() { + public DesktopCardPane getCenterTemplateCardPane() { return CenterRegionContainerPane.getInstance().getCenterTemplateCardPane(); } @@ -567,6 +573,11 @@ public class DesignerFrame extends JFrame implements JTemplateActionListener, Ta layeredPane.repaint(); } + public void refreshUIToolBar() { + CenterRegionContainerPane.getInstance().refreshUIToolBar(); + this.ad.updateEnable(); + } + public JComponent getToolbarComponent() { return CenterRegionContainerPane.getInstance().getToolbarComponent(); @@ -696,42 +707,6 @@ public class DesignerFrame extends JFrame implements JTemplateActionListener, Ta return getCenterTemplateCardPane().getSelectedJTemplate(); } - /** - * 保存当前编辑的模板 - */ - - public void saveCurrentEditingTemplate() { - - JTemplate editingTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); - if (editingTemplate == null) { - return; - } - if (editingTemplate.isSaved()) {// isSaved == true表示已经保存过,或者新建的一张模板 - if (editingTemplate.getEditingFILE().exists()) {// 表示磁盘上的某一张已经保存过的模板,要添加到历史中 - // HistoryTemplateListPane.getInstance().addHistory(); - } - } else { - editingTemplate.stopEditing(); - if (!editingTemplate.getEditingFILE().exists()) { - int returnVal = FineJOptionPane.showConfirmDialog(DesignerContext.getDesignerFrame(), - Toolkit.i18nText("Fine-Design_Basic_Utils_Would_You_Like_To_Save") + " \"" + editingTemplate.getEditingFILE() - + "\" ?", Toolkit.i18nText("Fine-Design_Basic_Confirm"), JOptionPane.YES_NO_OPTION, - JOptionPane.QUESTION_MESSAGE); - if (returnVal == JOptionPane.YES_OPTION && editingTemplate.saveTemplate()) { - editingTemplate.saveTemplate(); - FineLoggerFactory.getLogger().info(Toolkit.i18nText("Fine-Design_Basic_Template_Already_Saved", - editingTemplate.getEditingFILE().getName())); - } - } else { - if (editingTemplate.saveTemplate()) { - editingTemplate.saveTemplate(); - FineLoggerFactory.getLogger().info(Toolkit.i18nText("Fine-Design_Basic_Template_Already_Saved", - editingTemplate.getEditingFILE().getName())); - } - } - } - } - /** * 添加新建模板, 并激活. */ @@ -905,6 +880,16 @@ public class DesignerFrame extends JFrame implements JTemplateActionListener, Ta JOptionPane.WARNING_MESSAGE, UIManager.getIcon("OptionPane.errorIcon") ); + if (this.getSelectedJTemplate() == null) { + addAndActivateJTemplate(); + } + } catch (ChartNotFoundException e) { + FineJOptionPane.showMessageDialog(this, + Toolkit.i18nText("Fine-Design_Chart_Not_Found_Exception"), + Toolkit.i18nText("Fine-Design_Basic_Error"), + JOptionPane.ERROR_MESSAGE, + UIManager.getIcon("OptionPane.errorIcon")); + if (this.getSelectedJTemplate() == null) { addAndActivateJTemplate(); } 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 fb8f9a2da..fe2589028 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 @@ -181,9 +181,12 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt jt.requestFocus(); jt.revert(); - FineLoggerFactory.getLogger().info( - "\"" + jt.getEditingFILE().getName() + "\"" - + Toolkit.i18nText("Fine-Design_Basic_LOG_Has_Been_Openned") + "!"); + // 打开为空占位模板时不输出 + if (!jt.isOpening()) { + FineLoggerFactory.getLogger().info( + "\"" + jt.getEditingFILE().getName() + "\"" + + Toolkit.i18nText("Fine-Design_Basic_LOG_Has_Been_Openned") + "!"); + } } /** @@ -289,16 +292,18 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt // 新建文件夹,重命名操作,在explorer中打开三个操作在选中单个文件夹或者文件时可用,其他情况不可用 boolean singleSelected = selectedPathNum == 1; + // 打开和保存中 需要禁用相关操作 + boolean enable = isEnable(); newFolderAction.setEnabled(singleSelected); - renameAction.setEnabled(singleSelected); + renameAction.setEnabled(singleSelected && enable); showInExplorerAction.setEnabled(singleSelected); // 删除操作在至少选中一个时可用 boolean selected = selectedPathNum > 0; - delFileAction.setEnabled(selected); + delFileAction.setEnabled(selected && enable); // 刷新操作始终可用 refreshTreeAction.setEnabled(true); //触发vcsAction变化 - vcsAction.fireVcsActionChange(); + vcsAction.fireVcsActionChange(enable); // 其他状态 otherStateChange(); @@ -363,7 +368,7 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt /** * 版本管理可用状态的监控 */ - private void fireVcsActionChange() { + private void fireVcsActionChange(boolean enable) { if (!DesignerEnvManager.getEnvManager().getVcsConfigManager().isVcsEnable() || VcsHelper.getInstance().isUnSelectedTemplate() || WorkContext.getCurrent().isCluster()) { @@ -381,14 +386,14 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt if (node.getLock() != null && !ComparatorUtils.equals(node.getUserID(), node.getLock())) { setEnabled(false); } else { - setEnabled(true); + setEnabled(enable); } } else { setEnabled(false); } } else { //当前环境为本地环境时 - setEnabled(pathSupportVcsAction); + setEnabled(pathSupportVcsAction && enable); } } } @@ -915,5 +920,18 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt } } + private boolean isEnable() { + List> templates = HistoryTemplateListCache.getInstance().getHistoryList(); + for (JTemplate template : templates) { + if (template.isSaving() || template.isOpening()) { + FileNode node = TemplateTreePane.getInstance().getFileNode(); + if (node != null && ComparatorUtils.equals(template.getEditingFILE().getPath(), node.getEnvPath())) { + return false; + } + } + } + return true; + } + } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/DesktopCardPane.java b/designer-base/src/main/java/com/fr/design/mainframe/DesktopCardPane.java index 8b32d1427..8361016ca 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/DesktopCardPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/DesktopCardPane.java @@ -6,11 +6,15 @@ package com.fr.design.mainframe; import com.fr.base.iofile.attr.DesignBanCopyAttrMark; import com.fr.design.base.mode.DesignModeContext; import com.fr.design.base.mode.DesignerMode; +import com.fr.design.data.BasicTableDataTreePane; import com.fr.design.dialog.BasicPane; import com.fr.design.event.TargetModifiedEvent; import com.fr.design.event.TargetModifiedListener; import java.awt.BorderLayout; +import java.awt.Component; +import javax.swing.JComponent; +import javax.swing.JLayeredPane; /** @@ -19,11 +23,30 @@ import java.awt.BorderLayout; */ public class DesktopCardPane extends BasicPane implements TargetModifiedListener { + private static final int CONTENT_LAYER = 0; + private static final int TRANSPARENT_LAYER = 1; + private static final int LOADING_LAYER = 2; + private static final int FAILED_LAYER = 3; + private static final long serialVersionUID = 1L; private JTemplate component; + private TransparentPane transparentPane = new TransparentPane(); + private OpenLoadingPane loadingPane = new OpenLoadingPane(); + private OpenFailedPane failedPane = new OpenFailedPane(); + private JLayeredPane layeredPane = new JLayeredPane() { + @Override + public void doLayout() { + for (Component comp : getComponents()) { + comp.setBounds(0, 0, getWidth(), getHeight()); + } + } + }; protected DesktopCardPane() { setLayout(new BorderLayout()); + layeredPane.add(transparentPane, TRANSPARENT_LAYER); + layeredPane.add(failedPane, FAILED_LAYER); + add(layeredPane, BorderLayout.CENTER); } protected void showJTemplate(final JTemplate jt) { @@ -36,10 +59,12 @@ public class DesktopCardPane extends BasicPane implements TargetModifiedListener DesignerFrameFileDealerPane.getInstance().setCurrentEditingTemplate(jt); if (component != null) { component.onLostFocus(); - remove(component); + layeredPane.remove(component); } component = jt; - add(component, BorderLayout.CENTER); + layeredPane.add(component, CONTENT_LAYER); + checkSavingAndOpening(jt); + add(layeredPane, BorderLayout.CENTER); validate(); repaint(); revalidate(); @@ -47,6 +72,69 @@ public class DesktopCardPane extends BasicPane implements TargetModifiedListener component.onGetFocus(); } + + private void checkSavingAndOpening(JTemplate jt) { + if (jt.isSaving()) { + showCover(); + } else if (jt.isOpening()) { + showOpenStatus(); + } else if (jt.isOpenFailed()) { + showOpenFailedCover(); + } else { + hideCover(); + } + } + + /** + * 让loadingPane懒加载 + */ + private void checkLoadingPane() { + if (layeredPane.getComponent(LOADING_LAYER) != loadingPane) { + layeredPane.add(loadingPane, LOADING_LAYER); + component.setVisible(false); + } + } + + private void showOpenStatus() { + DesignerContext.getDesignerFrame().refreshUIToolBar(); + DesignerFrameFileDealerPane.getInstance().stateChange(); + EastRegionContainerPane.getInstance().updateAllPropertyPane(); + JComponent downPane = WestRegionContainerPane.getInstance().getDownPane(); + if (downPane instanceof BasicTableDataTreePane) { + BasicTableDataTreePane dataTreePane = (BasicTableDataTreePane) downPane; + dataTreePane.refreshToolBar(); + } + checkLoadingPane(); + layeredPane.moveToFront(loadingPane); + } + + public void showOpenFailedCover() { + layeredPane.moveToFront(failedPane); + } + + public void showCover() { + transparentPane.start(); + layeredPane.moveToFront(transparentPane); + DesignerContext.getDesignerFrame().refreshUIToolBar(); + EastRegionContainerPane.getInstance().updateAllPropertyPane(); + JComponent downPane = WestRegionContainerPane.getInstance().getDownPane(); + if (downPane instanceof BasicTableDataTreePane) { + BasicTableDataTreePane dataTreePane = (BasicTableDataTreePane) downPane; + dataTreePane.refreshToolBar(); + } + } + + public void hideCover() { + transparentPane.stop(); + layeredPane.moveToFront(component); + EastRegionContainerPane.getInstance().updateAllPropertyPane(); + JComponent downPane = WestRegionContainerPane.getInstance().getDownPane(); + if (downPane instanceof BasicTableDataTreePane) { + BasicTableDataTreePane dataTreePane = (BasicTableDataTreePane) downPane; + dataTreePane.checkEnable(); + } + } + protected JTemplate getSelectedJTemplate() { return component; } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/EastRegionContainerPane.java b/designer-base/src/main/java/com/fr/design/mainframe/EastRegionContainerPane.java index 8827d6a85..1bffe0842 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/EastRegionContainerPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/EastRegionContainerPane.java @@ -6,14 +6,18 @@ import com.fr.base.vcs.DesignerMode; import com.fr.design.DesignerEnvManager; import com.fr.design.ExtraDesignClassManager; import com.fr.design.constants.UIConstants; +import com.fr.design.file.HistoryTemplateListCache; import com.fr.design.fun.PropertyItemPaneProvider; import com.fr.design.gui.ibutton.UIButton; import com.fr.design.gui.ibutton.UIButtonUI; import com.fr.design.gui.icontainer.UIEastResizableContainer; import com.fr.design.gui.ilable.UILabel; import com.fr.design.layout.VerticalFlowLayout; +import com.fr.design.mainframe.reuse.ReuseGuideDialog; +import com.fr.design.mainframe.reuse.SnapChatKeys; import com.fr.design.menu.SnapChatUtil; import com.fr.design.notification.SnapChat; +import com.fr.design.notification.SnapChatFactory; import com.fr.design.ui.util.UIUtil; import com.fr.design.utils.DesignUtils; import com.fr.design.utils.gui.GUICoreUtils; @@ -96,6 +100,7 @@ public class EastRegionContainerPane extends UIEastResizableContainer { private JPanel defaultPane; // "无可用配置项"面板 private JPanel defaultAuthorityPane; // "该元素不支持权限编辑" private PropertyItem selectedItem; // 当前被选中的属性配置项 + private SnapChat widgetLibSnapChat; public enum PropertyMode { REPORT, // 报表 @@ -296,9 +301,21 @@ public class EastRegionContainerPane extends UIEastResizableContainer { "hyperlink", new PropertyMode[]{PropertyMode.REPORT, PropertyMode.REPORT_PARA, PropertyMode.REPORT_PARA_WIDGET, PropertyMode.REPORT_FLOAT, PropertyMode.POLY, PropertyMode.POLY_CHART}, new PropertyMode[]{PropertyMode.REPORT, PropertyMode.REPORT_FLOAT, PropertyMode.FORM_REPORT, PropertyMode.POLY_REPORT}); // 组件库 - PropertyItem widgetLib = new PropertyItem(KEY_WIDGET_LIB, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Widget_Library"), - "widgetlib", new PropertyMode[]{PropertyMode.FORM}, - new PropertyMode[]{PropertyMode.FORM}); + widgetLibSnapChat = SnapChatFactory.createSnapChat(false, SnapChatKeys.COMPONENT); + PropertyItem widgetLib = new PropertyItem( + KEY_WIDGET_LIB, + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Widget_Library"), + "widgetlib", + new PropertyMode[]{PropertyMode.FORM}, + new PropertyMode[]{PropertyMode.FORM}, + getWidgetLibSnapChat(), + getWidgetLibPromptWindow(), + new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + ComponentReuseNotifyUtil.enterWidgetLibExtraAction(true); + } + }); // 权限编辑 PropertyItem authorityEdition = new PropertyItem(KEY_AUTHORITY_EDITION, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Permissions_Edition"), "authorityedit", new PropertyMode[]{PropertyMode.AUTHORITY_EDITION_DISABLED}, @@ -513,6 +530,17 @@ public class EastRegionContainerPane extends UIEastResizableContainer { propertyItemMap.get(KEY_WIDGET_LIB).replaceContentPane(pane); } + public SnapChat getWidgetLibSnapChat() { + return widgetLibSnapChat; + } + + public PromptWindow getWidgetLibPromptWindow() { + if (!getWidgetLibSnapChat().hasRead()) { + return new ReuseGuideDialog(DesignerContext.getDesignerFrame()); + } + return null; + } + public JComponent getWidgetLibPane() { return propertyItemMap.get(KEY_WIDGET_LIB).getContentPane(); } @@ -594,6 +622,7 @@ public class EastRegionContainerPane extends UIEastResizableContainer { if (propertyItem.isVisible() && propertyItem.isEnabled() && !propertyItem.isPoppedOut()) { propertyCard.show(rightPane, tabName); propertyItem.setTabButtonSelected(); + propertyItem.processSnapChat(); //从单元格菜单过来也要关闭弹出窗 hideCurrentPopupPane(); } @@ -712,19 +741,33 @@ public class EastRegionContainerPane extends UIEastResizableContainer { private String iconSuffix = ICON_SUFFIX_NORMAL; // normal, diabled, selected, 三者之一 private final Color selectedBtnBackground = new Color(0xF5F5F7); private Color originBtnBackground; + private ActionListener actionListener; public PropertyItem(String name, String title, String btnIconName, PropertyMode[] visibleModes, PropertyMode[] enableModes) { this(name, title, btnIconName, ICON_BASE_DIR, visibleModes, enableModes, null, null); } + public PropertyItem(String name, String title, String btnIconName, PropertyMode[] visibleModes, PropertyMode[] enableModes, SnapChat snapChat, PromptWindow promptWindow, ActionListener actionListener) { + this(name, title, btnIconName, ICON_BASE_DIR, visibleModes, enableModes, snapChat, promptWindow, actionListener); + } + + public PropertyItem(String name, String title, String btnIconName, PropertyMode[] visibleModes, PropertyMode[] enableModes, ActionListener actionListener) { + this(name, title, btnIconName, ICON_BASE_DIR, visibleModes, enableModes, null, null, actionListener); + } + public PropertyItem(String name, String title, String btnIconName, String iconBaseDir, PropertyMode[] visibleModes, PropertyMode[] enableModes, SnapChat snapChat, PromptWindow promptWindow) { + this(name, title, btnIconName, iconBaseDir, visibleModes, enableModes, snapChat, promptWindow, null); + } + + public PropertyItem(String name, String title, String btnIconName, String iconBaseDir, PropertyMode[] visibleModes, PropertyMode[] enableModes, SnapChat snapChat, PromptWindow promptWindow, ActionListener actionListener) { this.name = name; this.title = title; this.btnIconName = btnIconName; this.iconBaseDir = iconBaseDir; this.snapChat = snapChat; this.promptWindow = promptWindow; + this.actionListener = actionListener; initButton(); initPropertyPanel(); initModes(visibleModes, enableModes); @@ -791,8 +834,13 @@ public class EastRegionContainerPane extends UIEastResizableContainer { // 选项不可用 public void setEnabled(boolean isEnabled) { - this.isEnabled = isEnabled; - button.setEnabled(isEnabled); + JTemplate template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + if (template != null) { + this.isEnabled = isEnabled && template.checkEnable(); + } else { + this.isEnabled = isEnabled; + } + button.setEnabled(this.isEnabled); } public void setIconBaseDir(String iconBaseDir) { @@ -919,9 +967,6 @@ public class EastRegionContainerPane extends UIEastResizableContainer { @Override public void paintComponent(Graphics g) { super.paintComponent(g); - if (snapChat != null && !snapChat.hasRead()) { - SnapChatUtil.paintPropertyItemPoint(g, getBounds()); - } } }; button.setDisabledIcon(IconUtils.readIcon(getIconBaseDir() + btnIconName + ICON_SUFFIX_DISABLED)); @@ -950,17 +995,25 @@ public class EastRegionContainerPane extends UIEastResizableContainer { popupFixedPane(); } setTabButtonSelected(); - if (snapChat != null && !snapChat.hasRead()) { - snapChat.markRead(); - if (promptWindow != null) { - promptWindow.showWindow(); - } - } + processSnapChat(); } }); + if (actionListener != null) { + button.addActionListener(actionListener); + } button.setToolTipText(title); } + public void processSnapChat(){ + if (snapChat != null && !snapChat.hasRead()) { + snapChat.markRead(); + if (promptWindow != null) { + promptWindow.showWindow(); + } + } + } + + public UIButton getButton() { return button; } 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 f9e75528c..dd7eb1aec 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 @@ -1,7 +1,6 @@ package com.fr.design.mainframe; import com.fr.base.BaseUtils; -import com.fr.base.FRContext; import com.fr.base.Parameter; import com.fr.base.io.BaseBook; import com.fr.base.iofile.attr.DesignBanCopyAttrMark; @@ -22,6 +21,7 @@ import com.fr.design.designer.DesignerProxy; import com.fr.design.designer.TargetComponent; import com.fr.design.dialog.FineJOptionPane; 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.fun.DesignerFrameUpButtonProvider; @@ -36,6 +36,7 @@ import com.fr.design.gui.imenu.UIMenuItem; import com.fr.design.i18n.Toolkit; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.mainframe.chart.info.ChartInfoCollector; +import com.fr.design.mainframe.check.CheckButton; import com.fr.design.mainframe.template.info.TemplateInfoCollector; import com.fr.design.mainframe.template.info.TemplateProcessInfo; import com.fr.design.mainframe.template.info.TimeConsumeTimer; @@ -46,6 +47,8 @@ import com.fr.design.menu.NameSeparator; import com.fr.design.menu.ShortCut; import com.fr.design.preview.PagePreview; import com.fr.design.ui.util.UIUtil; +import com.fr.design.worker.save.CallbackSaveWorker; +import com.fr.design.worker.save.EmptyCallBackSaveWorker; import com.fr.design.write.submit.DBManipulationInWidgetEventPane; import com.fr.design.write.submit.DBManipulationPane; import com.fr.event.EventDispatcher; @@ -81,13 +84,16 @@ import javax.swing.JOptionPane; import javax.swing.undo.UndoManager; import java.awt.BorderLayout; import java.util.Set; +import java.util.concurrent.Callable; /** * 报表设计和表单设计的编辑区域(设计器编辑的IO文件) */ -public abstract class JTemplate> extends TargetComponent implements ToolBarMenuDockPlus, DesignerProxy { +public abstract class JTemplate> extends TargetComponent implements ToolBarMenuDockPlus, DesignerProxy, JTemplateSave { // TODO ALEX_SEP editingFILE这个属性一定要吗?如果非要不可,有没有可能保证不为null - private FILE editingFILE = null; + + private static final int PREFIX_NUM = 3000; + protected FILE editingFILE = null; // alex:初始状态为saved,这样不管是新建模板,还是打开模板,如果未做任何操作直接关闭,不提示保存 private boolean saved = true; private boolean authoritySaved = true; @@ -101,6 +107,9 @@ public abstract class JTemplate> private DesignModelAdapter designModel; private PreviewProvider previewType; protected TimeConsumeTimer consumeTimer = new TimeConsumeTimer(); + private volatile boolean saving = false; + private volatile boolean opening = false; + private volatile boolean openFailed = false; private PluginEventListener pluginListener; @@ -116,7 +125,15 @@ public abstract class JTemplate> this(t, file, false); } + public JTemplate(T t, FILE file, Parameter[] parameters) { + this(t, file, false, parameters); + } + public JTemplate(T t, FILE file, boolean isNewFile) { + this(t, file, isNewFile, null); + } + + public JTemplate(T t, FILE file, boolean isNewFile, Parameter[] parameters) { super(t); beforeInit(); // 判断是否切换设计器状态到禁止拷贝剪切 @@ -130,7 +147,11 @@ public abstract class JTemplate> this.editingFILE = file; this.setLayout(FRGUIPaneFactory.createBorderLayout()); this.setBorder(BorderFactory.createEmptyBorder()); - designModel = createDesignModel(); + if (parameters == null) { + designModel = createDesignModel(); + } else { + designModel = createDesignModel(parameters); + } addCenterPane(); this.undoState = createUndoState(); @@ -388,6 +409,12 @@ public abstract class JTemplate> protected abstract DesignModelAdapter createDesignModel(); + protected DesignModelAdapter createDesignModel(Parameter[] parameters) { + // 空实现 兼容下 + return null; + } + + /** * 创建菜单项Preview * @@ -605,6 +632,7 @@ public abstract class JTemplate> * * @return 保存模板 */ + @Deprecated public boolean saveTemplate() { return this.saveTemplate(true); } @@ -614,6 +642,7 @@ public abstract class JTemplate> * * @return 保存成功返回true */ + @Deprecated public boolean saveTemplate2Env() { return this.saveTemplate(false); } @@ -623,6 +652,7 @@ public abstract class JTemplate> * * @return 保存成功返回true */ + @Deprecated public boolean saveAsTemplate() { return this.saveAsTemplate(true); } @@ -632,6 +662,7 @@ public abstract class JTemplate> * * @return 保存成功返回true */ + @Deprecated public boolean saveAsTemplate2Env() { return this.saveAsTemplate(false); } @@ -642,6 +673,7 @@ public abstract class JTemplate> * @param isShowLoc 是否本地 * @return 保存成功返回true */ + @Deprecated public boolean saveTemplate(boolean isShowLoc) { FILE editingFILE = this.getEditingFILE(); // carl:editingFILE没有,当然不存了,虽然不会有这种情况 @@ -653,17 +685,6 @@ public abstract class JTemplate> if (!editingFILE.exists()) { return saveAsTemplate(isShowLoc); } - boolean access = false; - - try { - access = FRContext.getOrganizationOperator().canAccess(this.getEditingFILE().getPath()); - } catch (Exception e) { - FineLoggerFactory.getLogger().error(e.getMessage(), e); - } - if (!access) { - FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Template_Permission_Denied") + "!", com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Alert"), JOptionPane.WARNING_MESSAGE); - return false; - } collectInfo(); return this.saveFile(); } @@ -693,6 +714,7 @@ public abstract class JTemplate> * @param fileName 保存文件名 * @return */ + @Deprecated public boolean saveAsTemplate(boolean isShowLoc, String fileName) { String oldName = this.getPath(); // alex:如果是SaveAs的话需要让用户来选择路径了 @@ -708,20 +730,6 @@ public abstract class JTemplate> FILE sourceFile = editingFILE; if (isOkOperation(chooseResult)) { - boolean access = false; - try { - access = FRContext.getOrganizationOperator().canAccess(fileChooser.getSelectedFILE().getPath()); - } catch (Exception e) { - FineLoggerFactory.getLogger().error(e.getMessage(), e); - } - if (!access) { - FineJOptionPane.showMessageDialog( - DesignerContext.getDesignerFrame(), - Toolkit.i18nText("Fine-Design_Basic_Template_Permission_Denied") + "!", - com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Alert"), - JOptionPane.WARNING_MESSAGE); - return false; - } // 目标文件 editingFILE = fileChooser.getSelectedFILE(); } @@ -836,6 +844,43 @@ public abstract class JTemplate> return this.getTarget().export(TemplateResourceManager.getResource().saveTemplate(editingFILE)); } + /** + * @Description 返回文件名中的index + * @param: prefix 前缀 + * @param: fileName 文件名称全名 + * @return java.lang.Integer WorkBook11.cpt则返回11,如果没有找到index返回null + * @Author Henry.Wang + * @Date 2021/4/9 11:13 + **/ + private static Integer getFileNameIndex(String prefix, String fileName) { + char[] chars = new char[fileName.length()]; + int i = 0; + for (; i < fileName.length(); i++) { + char c = fileName.charAt(i); + //匹配前缀 + if (i < prefix.length()) { + if (c != prefix.charAt(i)) { + return null; + } + } else { + if (c == '.') { + break; + } else { + //匹配0~9 + if (c < 48 || c > 57) { + return null; + } + chars[i - prefix.length()] = c; + } + } + } + String s = new String(chars).substring(0, i - prefix.length()); + if (StringUtils.isBlank(s)) { + return null; + } + return Integer.valueOf(s); + } + // /////////////////////////////toolbarMenuDock////////////////////////////////// /** @@ -1296,6 +1341,10 @@ public abstract class JTemplate> return uiButtons; } + public UIButton[] createCheckButton() { + return new UIButton[]{new CheckButton()}; + } + /** * 由于老版本的模板没有模板ID,当勾选使用参数模板时候,就加一个模板ID attr * @@ -1319,7 +1368,7 @@ public abstract class JTemplate> return getEditingFILE().getName(); } - public String getTemplatePredefinedStyle(){ + public String getTemplatePredefinedStyle() { return StringUtils.EMPTY; } @@ -1363,4 +1412,203 @@ public abstract class JTemplate> return EastRegionContainerPane.getInstance(); } + private CallbackSaveWorker save(boolean showLoc) { + FILE editingFILE = this.getEditingFILE(); + // carl:editingFILE没有,当然不存了,虽然不会有这种情况 + if (editingFILE == null) { + return new EmptyCallBackSaveWorker(); + } + // 检查一下editingFILE是不是已存在的文件,如果不存在则用saveAs + if (!editingFILE.exists()) { + return saveAs(showLoc); + } + + CallbackSaveWorker worker = new CallbackSaveWorker(new Callable() { + @Override + public Boolean call() throws Exception { + collectInfo(); + return JTemplate.this.saveRealFile(); + } + }, this); + + worker.addSuccessCallback(new Runnable() { + @Override + public void run() { + callBackForSave(); + } + }); + + return worker; + } + + private void callBackForSave() { + JTemplate.this.saved = true; + JTemplate.this.authoritySaved = true; + DesignerContext.getDesignerFrame().setTitle(); + JTemplate.this.fireJTemplateSaved(); + } + + private boolean saveRealFile() throws Exception { + FILE editingFILE = this.getEditingFILE(); + if (editingFILE == null || editingFILE instanceof MemFILE) { + return false; + } + this.getTarget().export(TemplateResourceManager.getResource().saveTemplate(editingFILE)); + this.editingFILE = editingFILE; + return true; + } + + private CallbackSaveWorker saveAs(boolean showLoc) { + FILE editingFILE = this.getEditingFILE(); + if (editingFILE == null) { + return new EmptyCallBackSaveWorker(); + } + String oldName = this.getPath(); + // alex:如果是SaveAs的话需要让用户来选择路径了 + FILEChooserPane fileChooser = getFILEChooserPane(showLoc); + addChooseFILEFilter(fileChooser); + fileChooser.setFileNameTextField(editingFILE.getName(), this.suffix()); + int chooseResult = fileChooser.showSaveDialog(DesignerContext.getDesignerFrame(), this.suffix()); + if (isCancelOperation(chooseResult)) { + return new EmptyCallBackSaveWorker(); + } + // 源文件 + FILE sourceFile = editingFILE; + + if (isOkOperation(chooseResult)) { + // 目标文件 + editingFILE = fileChooser.getSelectedFILE(); + } + + //收集和生成templateID 因为是另存为操作 无论怎么样都需要重新生成templateID + initForCollect(); + + FILE finalEditingFILE = editingFILE; + CallbackSaveWorker worker = new CallbackSaveWorker(new Callable() { + @Override + public Boolean call() throws Exception { + return saveAs(finalEditingFILE, sourceFile, oldName); + } + }, this); + + worker.addSuccessCallback(new Runnable() { + @Override + public void run() { + callBackForSave(); + // 当前打开的是正在保存的模板才刷新 + if (ComparatorUtils.equals(JTemplate.this.template.getTemplateID(), + HistoryTemplateListCache.getInstance().getCurrentEditingTemplate().template.getTemplateID())) { + refreshToolArea(); + } + DesignerFrameFileDealerPane.getInstance().refresh(); + } + }); + + return worker; + + } + + private boolean saveAs(FILE editingFILE, FILE sourceFile, String oldName) throws Exception { + boolean lockedTarget = + // 目标本地文件 + !editingFILE.isEnvFile() || + // 目标远程文件 + WorkContext.getCurrent().get(TplOperator.class).saveAs(editingFILE.getPath()); + if (lockedTarget) { + boolean saved = saveNewRealFile(editingFILE, oldName); + // 目标文件保存成功并且源文件不一致的情况下,把源文件锁释放掉 + if (saved && !ComparatorUtils.equals(editingFILE.getPath(), sourceFile.getPath())) { + WorkContext.getCurrent().get(TplOperator.class).closeAndFreeFile(sourceFile.getPath()); + } + return saved; + } else { + return false; + } + } + + private boolean saveNewRealFile(FILE editingFILE, String oldName) throws Exception { + consumeTimer.setEnabled(true); + consumeTimer.start(); + this.editingFILE = editingFILE; + boolean result = this.saveToNewRealFile(oldName); + if (result) { + collectInfo(this.template.getTemplateID()); + } + return result; + } + + private boolean saveToNewRealFile(String oldName) throws Exception { + boolean result = false; + Set providers = ExtraDesignClassManager.getInstance().getArray(ReportSupportedFileUIProvider.XML_TAG); + for (ReportSupportedFileUIProvider provider : providers) { + result = result || provider.saveToNewFile(this.editingFILE.getPath(), this); + } + if (!result) { + result = this.saveRealFile(); + // 更换最近打开 + DesignerEnvManager.getEnvManager().replaceRecentOpenedFilePath(oldName, this.getPath()); + } + return result; + } + + @Override + public CallbackSaveWorker save() { + return save(true); + } + + @Override + public CallbackSaveWorker saveAs() { + return saveAs(true); + } + + @Override + public void saveDirectly() { + CallbackSaveWorker worker = save(); + worker.start(this.template.getTemplateID()); + } + + @Override + public void saveAsDirectly() { + CallbackSaveWorker worker = saveAs(); + worker.start(this.template.getTemplateID()); + } + + @Override + public CallbackSaveWorker save2Env() { + return save(false); + } + + @Override + public CallbackSaveWorker saveAs2Env() { + return saveAs(false); + } + + public boolean isSaving() { + return saving; + } + + public void setSaving(boolean saving) { + this.saving = saving; + } + + public boolean isOpening() { + return opening; + } + + public void setOpening(boolean opening) { + this.opening = opening; + } + + public boolean isOpenFailed() { + return openFailed; + } + + public void setOpenFailed(boolean openFailed) { + this.openFailed = openFailed; + } + + public boolean checkEnable() { + return !isSaving() && !isOpening() && !isOpenFailed(); + } + } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/JTemplateSave.java b/designer-base/src/main/java/com/fr/design/mainframe/JTemplateSave.java new file mode 100644 index 000000000..005dadac2 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/JTemplateSave.java @@ -0,0 +1,57 @@ +package com.fr.design.mainframe; + +import com.fr.design.worker.save.CallbackSaveWorker; + +/** + * 模板保存接口 + * + * @author hades + * @version 10.0 + * Created by hades on 2021/4/9 + */ +public interface JTemplateSave { + + /** + * 保存后需要根据是否成功做外部回调,可选保存位置 + * + * @return + */ + CallbackSaveWorker save(); + + + /** + * 另存为后需要根据是否成功做外部回调,可选保存位置 + * + * @return + */ + CallbackSaveWorker saveAs(); + + + /** + * 保存到当前工作目录(reportlets)后需要根据是否成功做外部回调 + * + * + * @return + */ + CallbackSaveWorker save2Env(); + + + /** + * 另存为到当前工作目录(reportlets)后需要根据是否成功做外部回调 + * + * @return + */ + CallbackSaveWorker saveAs2Env(); + + /**D + * 直接保存 + */ + void saveDirectly(); + + + /** + * 直接另存为 + */ + void saveAsDirectly(); + +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/OpenFailedPane.java b/designer-base/src/main/java/com/fr/design/mainframe/OpenFailedPane.java new file mode 100644 index 000000000..132569c23 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/OpenFailedPane.java @@ -0,0 +1,93 @@ +package com.fr.design.mainframe; + +import com.fr.design.dialog.link.MessageWithLink; +import com.fr.design.file.HistoryTemplateListCache; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.general.IOUtils; +import com.fr.stable.StringUtils; +import java.awt.Color; +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.LayoutManager; +import javax.swing.JPanel; +import javax.swing.event.HyperlinkEvent; +import javax.swing.event.HyperlinkListener; + +/** + * @author hades + * @version 10.0 + * Created by hades on 2021/4/20 + */ +public class OpenFailedPane extends JPanel { + + private UILabel label; + private MessageWithLink link; + + public OpenFailedPane() { + this.setLayout(new LayoutManager() { + @Override + public void addLayoutComponent(String name, Component comp) { + + } + + @Override + public void removeLayoutComponent(Component comp) { + + } + + @Override + public Dimension preferredLayoutSize(Container parent) { + return parent.getPreferredSize(); + } + + @Override + public Dimension minimumLayoutSize(Container parent) { + return null; + } + + @Override + public void layoutContainer(Container parent) { + int width = parent.getParent().getWidth(); + int height = parent.getParent().getHeight(); + int labelWidth = label.getPreferredSize().width; + int labelHeight = label.getPreferredSize().height; + int labelX = (width - labelWidth) / 2; + int labelY = (height - labelHeight) / 2; + int linkWidth = link.getPreferredSize().width; + int linkHeight = link.getPreferredSize().height; + int linkX = (width - linkWidth) / 2; + int linkY = (height - labelHeight) / 2 + labelHeight; + label.setBounds(labelX, labelY, labelWidth, labelHeight); + link.setBounds(linkX, linkY, linkWidth, linkHeight); + } + }); + this.setBackground(Color.WHITE); + label = new UILabel(IOUtils.readIcon("/com/fr/design/images/mainframe/open_failed.png"), UILabel.CENTER); + link = new MessageWithLink(Toolkit.i18nText("Fine-Design_Open_Failed_Tip"), Toolkit.i18nText("Fine-Design_Open_Failed_Retry"), StringUtils.EMPTY, Color.WHITE) { + @Override + protected void initListener(String link) { + addHyperlinkListener(new HyperlinkListener() { + @Override + public void hyperlinkUpdate(HyperlinkEvent e) { + if (e.getEventType().equals(HyperlinkEvent.EventType.ACTIVATED)) { + // 重试 + JTemplate template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + template.whenClose(); + template = JTemplateFactory.createJTemplate(template.getEditingFILE()); + HistoryTemplateListCache.getInstance().replaceCurrentEditingTemplate(template); + DesignerContext.getDesignerFrame().addAndActivateJTemplate(template); + } + } + }); + } + }; + link.setBackground(Color.WHITE); + this.add(label); + this.add(link); + } + + + +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/OpenLoadingPane.java b/designer-base/src/main/java/com/fr/design/mainframe/OpenLoadingPane.java new file mode 100644 index 000000000..624f280a7 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/OpenLoadingPane.java @@ -0,0 +1,62 @@ +package com.fr.design.mainframe; + +import com.fr.design.gui.ilable.UILabel; +import com.fr.general.IOUtils; +import java.awt.Color; +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.LayoutManager; +import javax.swing.ImageIcon; +import javax.swing.JPanel; + +/** + * @author hades + * @version 10.0 + * Created by hades on 2021/4/9 + */ +public class OpenLoadingPane extends JPanel { + + private static final ImageIcon LOADING_ICON = new ImageIcon(IOUtils.readImage("/com/fr/design/images/mainframe/loading.gif")); + + private UILabel loadingLabel; + + public OpenLoadingPane() { + + setLayout(new LayoutManager() { + + @Override + public void removeLayoutComponent(Component comp) { + } + + @Override + public Dimension preferredLayoutSize(Container parent) { + return parent.getPreferredSize(); + } + + @Override + public Dimension minimumLayoutSize(Container parent) { + return null; + } + + @Override + public void layoutContainer(Container parent) { + int width = parent.getParent().getWidth(); + int height = parent.getParent().getHeight(); + int loadingLabelWidth = loadingLabel.getPreferredSize().width; + int loadingLabelHeight = loadingLabel.getPreferredSize().height; + int loadingLabelX = (width - loadingLabelWidth) / 2; + int loadingLabelY = (height - loadingLabelHeight) / 2; + loadingLabel.setBounds(loadingLabelX, loadingLabelY, loadingLabelWidth, loadingLabelHeight); + } + + @Override + public void addLayoutComponent(String name, Component comp) { + } + }); + setBackground(Color.WHITE); + loadingLabel = new UILabel(LOADING_ICON); + add(loadingLabel); + + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/TemplateSavingChecker.java b/designer-base/src/main/java/com/fr/design/mainframe/TemplateSavingChecker.java new file mode 100644 index 000000000..11ffc6e91 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/TemplateSavingChecker.java @@ -0,0 +1,41 @@ +package com.fr.design.mainframe; + +import com.fr.design.dialog.FineJOptionPane; +import com.fr.design.file.HistoryTemplateListCache; +import com.fr.design.i18n.Toolkit; +import com.fr.stable.StableUtils; +import java.util.ArrayList; +import java.util.List; + +/** + * @author hades + * @version 10.0 + * Created by hades on 2021/4/12 + */ +public class TemplateSavingChecker { + + + public static boolean check() { + List list = getSavingTemplate(); + if (!list.isEmpty()) { + FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), + Toolkit.i18nText("Fine-Design_Close_Template_Tip", StableUtils.join(list, "、")), + Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"), + FineJOptionPane.INFORMATION_MESSAGE); + return false; + } + return true; + } + + + private static List getSavingTemplate() { + List result = new ArrayList<>(); + for (JTemplate template : HistoryTemplateListCache.getInstance().getHistoryList()) { + if (template.isSaving()) { + result.add(template.getEditingFILE().getName()); + } + } + return result; + } + +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/TransparentPane.java b/designer-base/src/main/java/com/fr/design/mainframe/TransparentPane.java new file mode 100644 index 000000000..8861a7591 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/TransparentPane.java @@ -0,0 +1,162 @@ +package com.fr.design.mainframe; + +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import java.awt.AlphaComposite; +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Component; +import java.awt.Composite; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.LayoutManager; +import java.awt.RenderingHints; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import javax.swing.ImageIcon; +import javax.swing.JComponent; +import javax.swing.Timer; + +/** + * @author hades + * @version 10.0 + * Created by hades on 2021/4/12 + */ +public class TransparentPane extends JComponent implements ActionListener { + + private UILabel label; + private AlphaComposite composite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.3f); + private volatile boolean mIsRunning; + private volatile boolean mIsFadingOut; + private Timer mTimer; + private int mAngle; + private int mFadeCount; + private int mFadeLimit = 15; + private int lines = 12; + private int maxAngle = 360; + private int angleAdd = 30; + private double prec = 0.56; + + public TransparentPane() { + + addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + // do nothing + } + }); + + setLayout(getCoverLayout()); + setBackground(null); + setOpaque(false); + label = new UILabel(Toolkit.i18nText("Fine-Design_Saving_Template_Tip")); + add(label); + } + + protected LayoutManager getCoverLayout() { + return new LayoutManager() { + + @Override + public void removeLayoutComponent(Component comp) { + } + + @Override + public Dimension preferredLayoutSize(Container parent) { + return parent.getPreferredSize(); + } + + @Override + public Dimension minimumLayoutSize(Container parent) { + return null; + } + + @Override + public void layoutContainer(Container parent) { + int width = parent.getParent().getWidth(); + int height = parent.getParent().getHeight(); + int labelWidth = label.getPreferredSize().width; + int labelHeight = label.getPreferredSize().height; + int labelX = (width - labelWidth) / 2; + int labelY = (int) ((height - labelHeight) * prec); + label.setBounds(labelX, labelY, labelWidth, labelHeight); + } + + @Override + public void addLayoutComponent(String name, Component comp) { + } + }; + } + + + @Override + public void paint(Graphics g) { + int w = this.getWidth(); + int h = this.getHeight(); + super.paint(g); + if (!mIsRunning) { + return; + } + Graphics2D g2 = (Graphics2D) g.create(); + float fade = (float) mFadeCount / (float) mFadeLimit; + Composite urComposite = g2.getComposite(); + g2.setComposite(composite); + g2.fillRect(0, 0, w, h); + g2.setComposite(urComposite); + int s = Math.min(w, h) / 50; + int cx = w / 2; + int cy = h / 2; + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2.setStroke(new BasicStroke(s / 4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)); + g2.setPaint(Color.BLACK); + g2.rotate(Math.PI * mAngle / 180, cx, cy); + for (int i = 0; i < lines; i++) { + float scale = (11.0f - (float) i) / 11.0f; + g2.drawLine(cx + s, cy, cx + s * 2, cy); + g2.rotate(-Math.PI / 6, cx, cy); + g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, scale * fade)); + } + g2.dispose(); + } + + @Override + public void actionPerformed(ActionEvent e) { + if (mIsRunning) { + repaint(); + mAngle += angleAdd; + if (mAngle >= maxAngle) { + mAngle = 0; + } + if (mIsFadingOut) { + if (--mFadeCount == 0) { + mIsRunning = false; + mTimer.stop(); + } + } else if (mFadeCount < mFadeLimit) { + mFadeCount++; + } + } + } + + public void start() { + if (mIsRunning) { + return; + } + mIsRunning = true; + mIsFadingOut = false; + mFadeCount = 0; + int fps = 24; + int tick = 1000 / fps; + mTimer = new Timer(tick, this); + mTimer.start(); + } + + public void stop() { + mIsRunning = false; + mIsFadingOut = true; + } + +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/check/CheckButton.java b/designer-base/src/main/java/com/fr/design/mainframe/check/CheckButton.java new file mode 100644 index 000000000..e55f9a481 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/check/CheckButton.java @@ -0,0 +1,214 @@ +package com.fr.design.mainframe.check; + +import com.fr.base.BaseUtils; +import com.fr.design.dialog.FineJOptionPane; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.JTemplate; +import com.fr.design.worker.save.CallbackSaveWorker; +import com.fr.file.FILE; +import com.fr.file.FileNodeFILE; +import com.fr.log.FineLoggerFactory; +import com.fr.rpc.ExceptionHandler; +import com.fr.rpc.RPCInvokerExceptionInfo; +import com.fr.workspace.WorkContext; +import com.fr.workspace.server.check.TemplateChecker; + +import javax.swing.BoxLayout; +import javax.swing.JDialog; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; +import javax.swing.SwingWorker; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.util.Set; +import java.util.concurrent.ExecutionException; + +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; + +public class CheckButton extends UIButton { + + private UILabel message; + private UIButton okButton; + private JDialog dialog; + private UILabel uiLabel; + + public CheckButton() { + this.setIcon(BaseUtils.readIcon("/com/fr/design/images/buttonicon/check.png")); + this.setToolTipText(Toolkit.i18nText("Fine_Designer_Check_Font")); + this.set4ToolbarButton(); + this.addActionListener(checkListener); + } + + private ActionListener checkListener = new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + + // Try check + final SwingWorker, Void> checkThread = new SwingWorker, Void>() { + @Override + protected Set doInBackground() throws Exception { + // 返回校验结果 + return check(DesignerContext.getDesignerFrame().getSelectedJTemplate()); + } + + @Override + protected void done() { + try { + Set set = get(); + if (set == null) { + return; + } + if (set.isEmpty()) { + okButton.setEnabled(true); + uiLabel.setIcon(BaseUtils.readIcon("com/fr/design/images/correct.png")); + message.setText("" + Toolkit.i18nText("Fine_Designer_Check_Font_Success") + ""); + } else { + if (dialog != null) { + dialog.dispose(); + } + StringBuilder textBuilder = new StringBuilder(); + textBuilder.append(Toolkit.i18nText("Fine_Designer_Check_Font_Missing_Font")).append("\n"); + for (String font : set) { + textBuilder.append(font).append("\n"); + } + String areaText = textBuilder.toString(); + CheckFontInfoDialog dialog = new CheckFontInfoDialog(DesignerContext.getDesignerFrame(), areaText); + dialog.setVisible(true); + } + } catch (InterruptedException | ExecutionException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + } + }; + + JTemplate jtemplate = DesignerContext.getDesignerFrame().getSelectedJTemplate(); + if (jtemplate == null || jtemplate.getEditingFILE() == null) { + return; + } + FILE currentTemplate = jtemplate.getEditingFILE(); + if (currentTemplate instanceof FileNodeFILE) { + // 判断下模板是否存在 不存在先提示 + if (!currentTemplate.exists()) { + int selVal = showConfirmDialog( + DesignerContext.getDesignerFrame(), + Toolkit.i18nText("Fine-Design_Basic_Web_Preview_Message"), + Toolkit.i18nText("Fine_Designer_Check_Font"), + OK_CANCEL_OPTION, + WARNING_MESSAGE + ); + if (OK_OPTION == selVal) { + CallbackSaveWorker worker = jtemplate.saveAs(); + worker.addSuccessCallback(new Runnable() { + @Override + public void run() { + startCheck(checkThread); + } + }); + worker.start(jtemplate.getTarget().getTemplateID()); + } + } else { + if (!jtemplate.isSaved()) { + CallbackSaveWorker worker = jtemplate.save(); + worker.addSuccessCallback(new Runnable() { + @Override + public void run() { + startCheck(checkThread); + } + }); + worker.start(jtemplate.getTarget().getTemplateID()); + } else { + startCheck(checkThread); + } + } + } else { + //模板不在报表环境下,提示保存 + int selVal = FineJOptionPane.showConfirmDialog( + DesignerContext.getDesignerFrame(), + Toolkit.i18nText("Fine-Design_Basic_Web_Preview_Message"), + Toolkit.i18nText("Fine_Designer_Check_Font"), + OK_CANCEL_OPTION, + WARNING_MESSAGE); + if (OK_OPTION == selVal) { + CallbackSaveWorker worker = jtemplate.saveAs2Env(); + worker.addSuccessCallback(new Runnable() { + @Override + public void run() { + startCheck(checkThread); + } + }); + worker.start(jtemplate.getTarget().getTemplateID()); + } + } + } + + private void startCheck(SwingWorker, Void> checkThread) { + initDialogPane(); + dialog.addWindowListener(new WindowAdapter() { + public void windowClosed(WindowEvent e) { + checkThread.cancel(true); + } + }); + checkThread.execute(); + dialog.setVisible(true); + dialog.dispose(); + } + }; + + private Set check(JTemplate jtemplate) { + String path = jtemplate.getEditingFILE().getEnvFullName(); + Set fontSet = WorkContext.getCurrent().get(TemplateChecker.class, new ExceptionHandler() { + + @Override + public Void callHandler(RPCInvokerExceptionInfo rpcInvokerExceptionInfo) { + uiLabel.setIcon(BaseUtils.readIcon("com/fr/design/images/error.png")); + message.setText("" + Toolkit.i18nText("Fine_Designer_Check_Font_Upgrade") + ""); + okButton.setEnabled(true); + return null; + } + }).checkFont(path); + return fontSet; + } + + private void initDialogPane() { + message = new UILabel(); + message.setText(Toolkit.i18nText("Fine-Designer_Check_Font_Checking") + "..."); + uiLabel = new UILabel(); + okButton = new UIButton(Toolkit.i18nText("Fine-Design_Report_OK")); + okButton.setEnabled(false); + okButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + dialog.dispose(); + } + }); + dialog = new JDialog(); + dialog.setTitle(Toolkit.i18nText("Fine_Designer_Check_Font")); + dialog.setModal(true); + dialog.setSize(new Dimension(268, 118)); + JPanel jp = new JPanel(); + JPanel upPane = new JPanel(); + JPanel downPane = new JPanel(); + uiLabel = new UILabel(BaseUtils.readIcon("com/fr/design/images/waiting.png")); + upPane.setLayout(new FlowLayout(FlowLayout.LEFT, 10, 10)); + upPane.add(uiLabel); + upPane.add(message); + downPane.setLayout(new FlowLayout(FlowLayout.CENTER, 6, 0)); + downPane.add(okButton); + jp.setLayout(new BoxLayout(jp, BoxLayout.Y_AXIS)); + jp.add(upPane); + jp.add(downPane); + dialog.add(jp); + dialog.setResizable(false); + dialog.setLocationRelativeTo(SwingUtilities.getWindowAncestor(this)); + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/check/CheckFontInfoDialog.java b/designer-base/src/main/java/com/fr/design/mainframe/check/CheckFontInfoDialog.java new file mode 100644 index 000000000..0d5771a49 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/check/CheckFontInfoDialog.java @@ -0,0 +1,126 @@ +package com.fr.design.mainframe.check; + +import com.fr.design.dialog.link.MessageWithLink; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.general.CloudCenter; +import com.fr.general.GeneralContext; +import com.fr.general.IOUtils; + +import javax.swing.BorderFactory; +import javax.swing.JDialog; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; +import javax.swing.UIManager; +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.Locale; + +/** + * 字体缺失检测的具体结果对话框 + * + */ +public class CheckFontInfoDialog extends JDialog implements ActionListener { + + private JPanel topPanel; + private JPanel upInTopPanel; + private JPanel downInTopPanel; + private JPanel hiddenPanel; + private JPanel bottomPanel; + + private UILabel imageLabel; + private UILabel directUiLabel; + private UILabel detailLabel; + + public CheckFontInfoDialog(Frame parent, String areaText) { + super(parent,true); + //提示信息 + JPanel imagePanel = new JPanel(); + imageLabel = new UILabel(IOUtils.readIcon("com/fr/design/images/warnings/warning32.png")); + imagePanel.add(imageLabel); + + JPanel messagePanel = FRGUIPaneFactory.createVerticalFlowLayout_S_Pane(true); + MessageWithLink linkMessage = new MessageWithLink(Toolkit.i18nText("Fine_Designer_Check_Font_Message"), + Toolkit.i18nText("Fine_Designer_Check_Font_Install_Font"), + CloudCenter.getInstance().acquireUrlByKind("help.install.font", "https://help.fanruan.com/finereport/doc-view-3999.html")); + linkMessage.setPreferredSize(new Dimension(380, 31)); + messagePanel.add(linkMessage); + + // 查看详情按钮 + directUiLabel = new UILabel(); + directUiLabel.setIcon(UIManager.getIcon("OptionPane.narrow.right")); + detailLabel = new UILabel(); + detailLabel.setText(Toolkit.i18nText("Fine_Designer_Look_Detail")); + + upInTopPanel = FRGUIPaneFactory.createBorderLayout_L_Pane(); + upInTopPanel.add(imageLabel, BorderLayout.WEST); + upInTopPanel.add(messagePanel, BorderLayout.CENTER); + + downInTopPanel = FRGUIPaneFactory.createBorderLayout_L_Pane(); + downInTopPanel.add(directUiLabel, BorderLayout.WEST); + downInTopPanel.add(detailLabel, BorderLayout.CENTER); + + topPanel = FRGUIPaneFactory.createVerticalFlowLayout_S_Pane(true); + topPanel.add(upInTopPanel, BorderLayout.NORTH); + topPanel.add(downInTopPanel, BorderLayout.SOUTH); + + //中间的详情展示(可隐藏) + hiddenPanel = FRGUIPaneFactory.createBorderLayout_L_Pane(); + hiddenPanel.setBorder(BorderFactory.createEmptyBorder(0,12,0,12)); + JScrollPane scrollPane = new JScrollPane(); + JTextArea checkArea = new JTextArea(areaText); + scrollPane.setViewportView(checkArea); + scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); + checkArea.setEnabled(false); + hiddenPanel.add(scrollPane); + hiddenPanel.setVisible(false); + + downInTopPanel.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + if (hiddenPanel.isVisible()) { + hiddenPanel.setVisible(false); + CheckFontInfoDialog.this.setSize(new Dimension(380, 185)); + detailLabel.setText(Toolkit.i18nText("Fine_Designer_Look_Detail")); + directUiLabel.setIcon(UIManager.getIcon("OptionPane.narrow.right")); + } else { + CheckFontInfoDialog.this.setSize(new Dimension(380, 280)); + hiddenPanel.setVisible(true); + detailLabel.setText(Toolkit.i18nText("Fine_Designer_Hide_Detail")); + directUiLabel.setIcon(UIManager.getIcon("OptionPane.narrow.down")); + } + } + }); + + //底部的按钮面板 + UIButton okButton = new UIButton(Toolkit.i18nText("Fine-Design_Report_OK")); + okButton.addActionListener(this); + bottomPanel = FRGUIPaneFactory.createBorderLayout_L_Pane(); + bottomPanel.setBorder(BorderFactory.createEmptyBorder(10,10,10,10)); + bottomPanel.add(okButton, BorderLayout.EAST); + + this.setTitle(Toolkit.i18nText("Fine_Designer_Check_Font")); + this.setResizable(false); + + this.add(topPanel, BorderLayout.NORTH); + this.add(hiddenPanel, BorderLayout.CENTER); + this.add(bottomPanel, BorderLayout.SOUTH); + this.setSize(new Dimension(GeneralContext.getLocale().equals(Locale.US)? 400:380, 185)); + + GUICoreUtils.centerWindow(this); + } + + @Override + public void actionPerformed(ActionEvent e) { + this.dispose(); + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/reuse/ComponentReuseNotificationInfo.java b/designer-base/src/main/java/com/fr/design/mainframe/reuse/ComponentReuseNotificationInfo.java new file mode 100644 index 000000000..0ec6f26ad --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/reuse/ComponentReuseNotificationInfo.java @@ -0,0 +1,87 @@ +package com.fr.design.mainframe.reuse; + +import com.fr.design.DesignerEnvManager; +import com.fr.stable.xml.XMLPrintWriter; +import com.fr.stable.xml.XMLable; +import com.fr.stable.xml.XMLableReader; + +/** + * Created by kerry on 5/8/21 + */ +public class ComponentReuseNotificationInfo implements XMLable { + public static final String XML_TAG = "ComponentReuseNotificationInfo"; + + private static final ComponentReuseNotificationInfo INSTANCE = new ComponentReuseNotificationInfo(); + + public static ComponentReuseNotificationInfo getInstance() { + return INSTANCE; + } + + private long lastNotifyTime = 0; + + private int notifiedNumber = 0; + + private boolean clickedWidgetLib = false; + + private long lastGuidePopUpTime = 0; + + public long getLastNotifyTime() { + return lastNotifyTime; + } + + public void setLastNotifyTime(long lastNotifyTime) { + this.lastNotifyTime = lastNotifyTime; + } + + public int getNotifiedNumber() { + return notifiedNumber; + } + + public void setNotifiedNumber(int notifiedNumber) { + this.notifiedNumber = notifiedNumber; + } + + public boolean isClickedWidgetLib() { + return clickedWidgetLib; + } + + public void setClickedWidgetLib(boolean clickedWidgetLib) { + this.clickedWidgetLib = clickedWidgetLib; + } + + public long getLastGuidePopUpTime() { + return lastGuidePopUpTime; + } + + public void setLastGuidePopUpTime(long lastGuidePopUpTime) { + this.lastGuidePopUpTime = lastGuidePopUpTime; + } + + public void updateLastGuidePopUpTime() { + this.setLastGuidePopUpTime(System.currentTimeMillis()); + DesignerEnvManager.getEnvManager().saveXMLFile(); + } + + @Override + public void readXML(XMLableReader reader) { + this.setLastNotifyTime(reader.getAttrAsLong("lastNotifyTime", 0L)); + this.setNotifiedNumber(reader.getAttrAsInt("notifiedNumber", 0)); + this.setClickedWidgetLib(reader.getAttrAsBoolean("clickedWidgetLib", false)); + this.setLastGuidePopUpTime(reader.getAttrAsLong("lastGuidePopUpTime", 0L)); + } + + @Override + public void writeXML(XMLPrintWriter writer) { + writer.startTAG("ComponentReuseNotificationInfo"); + writer.attr("lastNotifyTime", this.lastNotifyTime) + .attr("notifiedNumber", this.notifiedNumber) + .attr("clickedWidgetLib", this.clickedWidgetLib) + .attr("lastGuidePopUpTime", this.lastGuidePopUpTime); + writer.end(); + } + + @Override + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/reuse/ReuseGuideDialog.java b/designer-base/src/main/java/com/fr/design/mainframe/reuse/ReuseGuideDialog.java new file mode 100644 index 000000000..4e0bb3143 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/reuse/ReuseGuideDialog.java @@ -0,0 +1,169 @@ +package com.fr.design.mainframe.reuse; + +import com.fr.base.background.ColorBackground; +import com.fr.design.dialog.UIDialog; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.PromptWindow; +import com.fr.design.mainframe.share.collect.ComponentCollector; +import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.general.IOUtils; + +import javax.swing.BorderFactory; +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.JPanel; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dialog; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Font; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.RenderingHints; +import java.awt.geom.RoundRectangle2D; + +public class ReuseGuideDialog extends UIDialog implements PromptWindow { + InnerDialog innerDialog; + private static final Dimension DEFAULT = new Dimension(735, 510); + + public ReuseGuideDialog(Frame parent) { + super(parent); + } + + @Override + public void showWindow() { + innerDialog = new InnerDialog(this); + JPanel backGroundPane = new JPanel() { + @Override + protected void paintComponent(Graphics g) { + Image icon = IOUtils.readImage("com/fr/base/images/share/background.png");// 003.jpg是测试图片在项目的根目录下 + g.drawImage(icon, 0, 0, getSize().width, getSize().height, this);// 图片会自动缩放 + } + }; + add(backGroundPane, BorderLayout.CENTER); + initStyle(); + innerDialog.showWindow(); + } + + private void initStyle() { + setSize(DEFAULT); + setUndecorated(true); + setBackground(new Color(0, 0, 0, 0)); + GUICoreUtils.centerWindow(this); + } + + @Override + public void hideWindow() { + ComponentReuseNotificationInfo.getInstance().updateLastGuidePopUpTime(); + this.setVisible(false); + if (innerDialog != null) { + innerDialog.setVisible(false); + innerDialog.dispose(); + innerDialog = null; + } + this.dispose(); + } + + @Override + public void checkValid() { + + } + + class InnerDialog extends UIDialog { + private final Dimension DEFAULT = new Dimension(700, 475); + private static final int TITLE_FONT_SIZE = 20; + + public InnerDialog(Dialog dialog) { + super(dialog); + } + + public void showWindow() { + add(createCenterPanel(), BorderLayout.CENTER); + add(createSouthPanel(), BorderLayout.SOUTH); + add(createNorthPanel(), BorderLayout.NORTH); + showDialog(); + } + + private JPanel createNorthPanel() { + JPanel northPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); + + //右上角关闭按钮 + JButton button = new JButton(new ImageIcon(IOUtils.readImage("/com/fr/base/images/share/close.png").getScaledInstance(15, 15, Image.SCALE_SMOOTH))); + button.setBorder(null); + button.setOpaque(false); + button.addActionListener(e -> ReuseGuideDialog.this.hideWindow()); + + northPanel.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 15)); + northPanel.setOpaque(false); + northPanel.add(button); + return northPanel; + } + + private JPanel createCenterPanel() { + JPanel centerPanel = new JPanel(new BorderLayout()); + + UILabel titleLabel = new UILabel(Toolkit.i18nText("Fine-Design_Share_Drag_And_Make_Component")); + UILabel imageLabel = new UILabel(new ImageIcon(IOUtils.readImage("com/fr/base/images/share/guide.png").getScaledInstance(DEFAULT.width, DEFAULT.height, Image.SCALE_SMOOTH))); + titleLabel.setFont(new Font(titleLabel.getFont().getName(), Font.BOLD, TITLE_FONT_SIZE)); + titleLabel.setBorder(BorderFactory.createEmptyBorder()); + + JPanel panel = new JPanel(new FlowLayout(FlowLayout.CENTER)); + panel.setOpaque(false); + panel.add(titleLabel); + + centerPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 10, 0)); + centerPanel.setOpaque(false); + centerPanel.add(imageLabel, BorderLayout.CENTER); + centerPanel.add(panel, BorderLayout.NORTH); + return centerPanel; + } + + private JPanel createSouthPanel() { + JPanel southPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + + JButton button = new JButton(Toolkit.i18nText("Fine-Design_Share_Try_Drag")) { + @Override + public void paint(Graphics g) { + ColorBackground buttonBackground = ColorBackground.getInstance(Color.decode("#419BF9")); + Graphics2D g2d = (Graphics2D) g; + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + buttonBackground.paint(g2d, new RoundRectangle2D.Double(0, 0, getWidth(), getHeight(), 8, 8)); + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); + super.paint(g); + } + }; + button.setBorder(null); + button.setForeground(Color.WHITE); + button.setOpaque(false); + button.addActionListener(e -> ReuseGuideDialog.this.hideWindow()); + + southPanel.setBorder(BorderFactory.createEmptyBorder(0, 290, 19, 290)); + southPanel.setPreferredSize(new Dimension(DEFAULT.width, 51)); + southPanel.setOpaque(false); + southPanel.add(button); + return southPanel; + } + + /** + * 显示窗口 + */ + private void showDialog() { + setSize(DEFAULT); + setUndecorated(true); + GUICoreUtils.centerWindow(this); + setModalityType(ModalityType.APPLICATION_MODAL); + ReuseGuideDialog.this.setVisible(true); + setVisible(true); + } + + @Override + public void checkValid() { + + } + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/reuse/SnapChatKeys.java b/designer-base/src/main/java/com/fr/design/mainframe/reuse/SnapChatKeys.java new file mode 100644 index 000000000..8f07f503b --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/reuse/SnapChatKeys.java @@ -0,0 +1,32 @@ +package com.fr.design.mainframe.reuse; + +import com.fr.design.notification.SnapChatKey; + +/** + * created by Harrison on 2020/03/24 + **/ +public enum SnapChatKeys implements SnapChatKey { + + /** + * 组件 + */ + COMPONENT("components"), + + /** + * 模板 + */ + TEMPLATE("template"); + + private String sign; + + private static final String PREFIX = "com.fr.component.share"; + + SnapChatKeys(String sign) { + this.sign = sign; + } + + @Override + public String calc() { + return PREFIX + "-" + sign; + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/share/collect/CollectorManager.java b/designer-base/src/main/java/com/fr/design/mainframe/share/collect/CollectorManager.java new file mode 100644 index 000000000..3ccb62429 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/share/collect/CollectorManager.java @@ -0,0 +1,89 @@ +package com.fr.design.mainframe.share.collect; + +import com.fr.concurrent.NamedThreadFactory; +import com.fr.stable.StringUtils; +import com.fr.third.joda.time.DateTime; +import com.fr.third.joda.time.Days; +import com.fr.third.joda.time.format.DateTimeFormat; +import com.fr.third.joda.time.format.DateTimeFormatter; + +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +/** + * created by Harrison on 2020/03/25 + **/ +public class CollectorManager { + + /** + * 1 天 + */ + private static final int DELTA = 1; + + /** + * 发送间隔 5 分钟 + */ + private static final long SEND_DELAY = 300 * 1000L; + + /** + * 线程 + */ + private ScheduledExecutorService service; + + private static class ConfigManagerHolder { + private static CollectorManager instance = new CollectorManager(); + } + + public static CollectorManager getInstance() { + + return ConfigManagerHolder.instance; + } + + public void execute() { + + service = Executors + .newSingleThreadScheduledExecutor(new NamedThreadFactory("plugin-CollectorManager", true)); + service.scheduleAtFixedRate(new Runnable() { + @Override + public void run() { + sendCloudCenter(); + } + }, SEND_DELAY, SEND_DELAY, TimeUnit.MILLISECONDS); + } + + public void shutdown() { + + ComponentCollector.getInstance().saveInfo(); + if (service != null) { + service.shutdown(); + } + } + + private void sendCloudCenter() { + + String lastTime = ComponentCollector.getInstance().getLastTime(); + if (validate(lastTime)) { + boolean sendSuccess = ComponentSender.send(); + String currentTime = DateTime.now().toString("yyyy-MM-dd"); + ComponentCollector.getInstance().setLastTime(currentTime); + if (sendSuccess) { + ComponentCollector.getInstance().clear(); + } + } + ComponentCollector.getInstance().saveInfo(); + } + + private boolean validate(String lastTime) { + + if (StringUtils.isEmpty(lastTime)) { + return true; + } + DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd"); + DateTime last = formatter.parseDateTime(lastTime); + DateTime current = DateTime.now(); + return Days.daysBetween(last, current).getDays() >= DELTA; + } + + +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/share/collect/ComponentCollector.java b/designer-base/src/main/java/com/fr/design/mainframe/share/collect/ComponentCollector.java new file mode 100644 index 000000000..1fa2b993e --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/share/collect/ComponentCollector.java @@ -0,0 +1,609 @@ +package com.fr.design.mainframe.share.collect; + +import com.fr.base.io.XMLReadHelper; +import com.fr.config.MarketConfig; +import com.fr.design.DesignerEnvManager; +import com.fr.design.mainframe.reuse.ComponentReuseNotificationInfo; +import com.fr.form.share.DefaultSharableWidget; +import com.fr.form.share.SharableWidgetProvider; +import com.fr.form.share.constants.ComponentPath; +import com.fr.form.share.group.DefaultShareGroupManager; +import com.fr.form.share.Group; +import com.fr.form.share.group.filter.DirFilter; +import com.fr.form.share.group.filter.ReuFilter; +import com.fr.general.ComparatorUtils; +import com.fr.json.JSON; +import com.fr.json.JSONArray; +import com.fr.json.JSONException; +import com.fr.json.JSONFactory; +import com.fr.json.JSONObject; +import com.fr.log.FineLoggerFactory; +import com.fr.plugin.context.PluginContexts; +import com.fr.stable.ProductConstants; +import com.fr.stable.StableUtils; +import com.fr.stable.StringUtils; +import com.fr.stable.xml.XMLPrintWriter; +import com.fr.stable.xml.XMLTools; +import com.fr.stable.xml.XMLable; +import com.fr.stable.xml.XMLableReader; +import com.fr.third.javax.xml.stream.XMLStreamException; +import com.fr.third.joda.time.DateTime; +import com.fr.third.joda.time.Days; +import com.fr.third.org.apache.commons.io.FileUtils; +import com.fr.workspace.WorkContext; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.Iterator; + +/** + * created by Harrison on 2020/03/25 + **/ +public class ComponentCollector implements XMLable { + private static final long ONE_MINUTE = 60 * 1000L; + + private static final int REUSE_INFO_FIRST_POPUP = 1; + + private static final int REUSE_INFO_SECOND_POPUP = 2; + + private static final String SIMPLE_DATE_PATTERN = "yyyy-MM-dd"; + + private static final String XML = "ComponentCollector"; + + private static final String ACTIVATE_VALUE = "activateValue"; + + private static final String COMP_PKT_CLICK = "cmpPktClick"; + + private static final String DOWNLOAD_PKT_NUM = "downloadPktNum"; + + private static final String DOWNLOAD_CMP = "downloadCmp"; + + private static final int ACTIVATE_INITIAL_VALUE = 1; + + private static final String ACTIVATE_DATE = "date"; + + private static final String GENERATE_CMP_RECORD_NAME = "name"; + + private static final String GENERATE_CMP_RECORD_TYPE = "type"; + + private static final String GENERATE_CMP_RECORD_UUID = "uuid"; + + private static final String HELP_CONFIG_INFO = "helpConfigInfo"; + + private static final String HELP_CONFIG_USE_INFO = "helpConfigUseInfo"; + + private static final String TEMPLATE_ID = "templateId"; + + private static final String SHOW_COUNT = "showCount"; + + private static final String USE_COUNT = "useCount"; + + private static final String GROUPING_DETAIL = "groupingDetail"; + + private static final String GROUP_NAME = "groupName"; + + private static final String CONTAIN_AMOUNT = "containAmount"; + + private static final String SEARCH_CONTENT = "searchContent"; + + private static final String FILTER_CONTENT = "filterContent"; + + private static final String SORT_TYPE = "sortType"; + + private static final String MARKET_CLICK = "marketClick"; + + private static final String PROMPT_JUMP = "promptJump"; + + private static final String TOOLBAR_JUMP = "toolbarJump"; + + private static final String POPUP_JUMP = "popupJump"; + + private static final String uuid = DesignerEnvManager.getEnvManager().getUUID(); + + private int localCmpNumber = 0; + + private int remoteCmpNumber = 0; + + private int generateCmpNumber = 0; + + private int uploadCmpNumber = 0; + + private int cmpBoardClick = 0; + + private int promptJump = 0; + + private int toolbarJump = 0; + + private int popupJump = 0; + + private JSONArray activateRecord = JSONFactory.createJSON(JSON.ARRAY); + + private JSONArray generateCmpRecord = JSONFactory.createJSON(JSON.ARRAY); + + private JSONArray helpConfigInfo = JSONFactory.createJSON(JSON.ARRAY); + + private JSONArray searchContent = JSONFactory.createJSON(JSON.ARRAY); + + private JSONArray filterContent = JSONFactory.createJSON(JSON.ARRAY); + + private JSONArray sortType = JSONFactory.createJSON(JSON.ARRAY); + + private String startTime = StringUtils.EMPTY; + + private String lastTime = StringUtils.EMPTY; + + private JSONArray helpConfigUseInfo = JSONFactory.createJSON(JSON.ARRAY); + + private static class ComponentCollectorHolder { + + private static ComponentCollector collector = new ComponentCollector(); + } + + public static ComponentCollector getInstance() { + return ComponentCollectorHolder.collector; + } + + private ComponentCollector() { + + loadFromFile(); + if (StringUtils.isEmpty(startTime)) { + startTime = DateTime.now().toString(SIMPLE_DATE_PATTERN); + } + } + + public void collectGenerateCmpNumber() { + + generateCmpNumber++; + saveInfo(); + } + + public void collectUploadCmpNumber() { + + uploadCmpNumber++; + saveInfo(); + } + + public void collectTepMenuEnterClick() { + + saveInfo(); + } + + public void collectCmpBoardClick() { + collectActivateRecord(); + cmpBoardClick++; + saveInfo(); + } + + public void collectCmpNumber() { + int count = 0; + //默认分组组件数量 + String[] reus = WorkContext.getWorkResource().list(ComponentPath.SHARE_PATH.path(), new ReuFilter()); + count += reus.length; + + //其他分组组件数量 + String[] groups = WorkContext.getWorkResource().list(ComponentPath.SHARE_PATH.path(), new DirFilter()); + for (String groupName : groups) { + String relativePath = StableUtils.pathJoin(ComponentPath.SHARE_PATH.path(), groupName); + String[] groupReus = WorkContext.getWorkResource().list(relativePath, new ReuFilter()); + count += groupReus.length; + } + + if (WorkContext.getCurrent().isLocal()) { + localCmpNumber = count; + } else { + remoteCmpNumber = count; + } + saveInfo(); + } + + public void collectCmpPktClick() { + collectAttrActiveCount(COMP_PKT_CLICK); + saveInfo(); + } + + public void collectDownloadPktNum() { + collectAttrActiveCount(DOWNLOAD_PKT_NUM); + saveInfo(); + } + + public void collectMarkerClick() { + collectAttrActiveCount(MARKET_CLICK); + } + + public void clearActiveRecord() { + String currentDate = DateTime.now().toString(SIMPLE_DATE_PATTERN); + Iterator iterator = activateRecord.iterator(); + while (iterator.hasNext()) { + JSONObject jo = (JSONObject) iterator.next(); + if (!ComparatorUtils.equals(currentDate, jo.getString(ACTIVATE_DATE))) { + iterator.remove(); + } + } + } + + public void collectGenerateCmpRecord(SharableWidgetProvider bindInfo) { + JSONObject jo = JSONFactory.createJSON(JSON.OBJECT); + jo.put(GENERATE_CMP_RECORD_NAME, bindInfo.getName()) + .put(GENERATE_CMP_RECORD_TYPE, ((DefaultSharableWidget) bindInfo).getChildClassify()) + .put(GENERATE_CMP_RECORD_UUID, bindInfo.getId()); + generateCmpRecord.add(jo); + } + + public void clearGenerateCmpRecord() { + generateCmpRecord = JSONFactory.createJSON(JSON.ARRAY); + } + + public void collectCmpDownLoad(String uuid) { + String currentDate = DateTime.now().toString(SIMPLE_DATE_PATTERN); + for (int i = 0; i < activateRecord.size(); i++) { + JSONObject jo = activateRecord.getJSONObject(i); + if (ComparatorUtils.equals(currentDate, jo.getString(ACTIVATE_DATE))) { + JSONArray downloadComp = jo.containsKey(DOWNLOAD_CMP) ? jo.getJSONArray(DOWNLOAD_CMP) : JSONFactory.createJSON(JSON.ARRAY); + downloadComp.add(uuid); + jo.put(DOWNLOAD_CMP, downloadComp); + saveInfo(); + return; + } + } + JSONObject jo = JSONFactory.createJSON(JSON.OBJECT); + jo.put(ACTIVATE_DATE, currentDate).put(DOWNLOAD_CMP, JSONFactory.createJSON(JSON.ARRAY).add(uuid)); + activateRecord.add(jo); + saveInfo(); + } + + public JSONArray getActivateRecord() { + return activateRecord; + } + + public JSONArray getGenerateCmpRecord() { + return generateCmpRecord; + } + + private void collectActivateRecord() { + collectAttrActiveCount(ACTIVATE_VALUE); + } + + private void collectAttrActiveCount(String attrName) { + String currentDate = DateTime.now().toString(SIMPLE_DATE_PATTERN); + for (int i = 0; i < activateRecord.size(); i++) { + JSONObject jo = activateRecord.getJSONObject(i); + if (ComparatorUtils.equals(currentDate, jo.getString(ACTIVATE_DATE))) { + int attrNum = jo.getInt(attrName); + attrNum++; + jo.put(attrName, attrNum); + return; + } + } + JSONObject jo = JSONFactory.createJSON(JSON.OBJECT); + jo.put(ACTIVATE_DATE, currentDate).put(attrName, ACTIVATE_INITIAL_VALUE); + activateRecord.add(jo); + } + + + private JSONArray getGroupingDetail() { + JSONArray ja = JSONFactory.createJSON(JSON.ARRAY); + Group[] groups = DefaultShareGroupManager.getInstance().getAllGroup(); + for(Group group : groups) { + JSONObject jo = JSONFactory.createJSON(JSON.OBJECT); + jo.put(GROUP_NAME, group.getGroupName()); + jo.put(CONTAIN_AMOUNT, group.getAllBindInfoList().length); + ja.add(jo); + } + return ja; + } + + public void collectHelpConfigInfo(String templateId, int showCount, int useCount) { + JSONObject jo = JSONFactory.createJSON(JSON.OBJECT); + jo.put(TEMPLATE_ID, templateId); + jo.put(SHOW_COUNT, showCount); + jo.put(USE_COUNT, useCount); + helpConfigInfo.add(jo); + saveInfo(); + } + + public void clearHelpConfigInfo() { + helpConfigInfo = JSONFactory.createJSON(JSON.ARRAY); + } + + public void collectSearchContent(String search) { + searchContent.add(search); + } + + public void clearSearchContent() { + searchContent = JSONFactory.createJSON(JSON.ARRAY); + } + + public void collectFilterContent(String filter) { + filterContent.add(filter); + saveInfo(); + } + + public void clearFilterContent() { + filterContent = JSONFactory.createJSON(JSON.ARRAY); + } + + public void collectSortType(String type) { + sortType.add(type); + saveInfo(); + } + + public void collectPromptJumpWhenJump(){ + if (ComponentReuseNotificationInfo.getInstance().getNotifiedNumber() == REUSE_INFO_FIRST_POPUP) { + this.promptJump = 1; + saveInfo(); + }else if(ComponentReuseNotificationInfo.getInstance().getNotifiedNumber() == REUSE_INFO_SECOND_POPUP){ + this.promptJump = 2; + saveInfo(); + } + } + + + public void collectPromptJumpWhenShow() { + if (ComponentReuseNotificationInfo.getInstance().getNotifiedNumber() == REUSE_INFO_SECOND_POPUP) { + this.promptJump = -1; + saveInfo(); + } + } + + public void collectToolbarJump() { + if (this.toolbarJump == 0) { + this.toolbarJump = 1; + saveInfo(); + } + + } + + public void collectPopupJump() { + long currentTime = System.currentTimeMillis(); + long lastGuidePopUpTime = ComponentReuseNotificationInfo.getInstance().getLastGuidePopUpTime(); + if (currentTime - lastGuidePopUpTime <= ONE_MINUTE && this.popupJump == 0) { + this.popupJump = 1; + saveInfo(); + } + } + + public void clearSortType() { + sortType = JSONFactory.createJSON(JSON.ARRAY); + } + + private int cmpBoardClickDaily() { + + DateTime dateTime = DateTime.parse(startTime); + DateTime currTime = DateTime.now(); + int days = (Days.daysBetween(dateTime, currTime).getDays() + 1); + return cmpBoardClick / days; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + /** + * 保存埋点信息到文件中 + */ + public void saveInfo() { + + try { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + XMLTools.writeOutputStreamXML(this, out); + out.flush(); + out.close(); + String fileContent = new String(out.toByteArray(), StandardCharsets.UTF_8); + FileUtils.writeStringToFile(getInfoFile(), fileContent, StandardCharsets.UTF_8); + } catch (Exception ex) { + FineLoggerFactory.getLogger().error(ex.getMessage()); + } + } + + /** + * 从文件中读取埋点信息 + */ + private void loadFromFile() { + + if (!getInfoFile().exists()) { + return; + } + XMLableReader reader = null; + try (InputStream in = new FileInputStream(getInfoFile())) { + // XMLableReader 还是应该考虑实现 Closable 接口的,这样就能使用 try-with 语句了 + reader = XMLReadHelper.createXMLableReader(in, XMLPrintWriter.XML_ENCODER); + if (reader == null) { + return; + } + reader.readXMLObject(this); + } catch (FileNotFoundException e) { + // do nothing + } catch (XMLStreamException | IOException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } finally { + try { + if (reader != null) { + reader.close(); + } + } catch (XMLStreamException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + } + } + + + private File getInfoFile() { + + File file = new File(StableUtils.pathJoin(ProductConstants.getEnvHome(), "component.info")); + try { + if (!file.exists()) { + file.createNewFile(); + } + } catch (Exception ex) { + FineLoggerFactory.getLogger().error(ex.getMessage(), ex); + } + return file; + } + + @Override + public void readXML(XMLableReader reader) { + + String tagName = reader.getTagName(); + if (tagName.equals(XML)) { + this.cmpBoardClick = reader.getAttrAsInt("cmpBoardClick", 0); + this.startTime = reader.getAttrAsString("startTime", StringUtils.EMPTY); + this.lastTime = reader.getAttrAsString("lastTime", StringUtils.EMPTY); + this.localCmpNumber = reader.getAttrAsInt("localCmpNumber", 0); + this.remoteCmpNumber = reader.getAttrAsInt("remoteCmpNumber", 0); + this.generateCmpNumber = reader.getAttrAsInt("generateCmpNumber", 0); + this.uploadCmpNumber = reader.getAttrAsInt("uploadCmpNumber", 0); + + String activateRecordStr = reader.getAttrAsString("activateRecord", StringUtils.EMPTY); + activateRecord = parseJSONArray(activateRecordStr); + String generateCmpRecordStr = reader.getAttrAsString("generateCmpRecord", StringUtils.EMPTY); + generateCmpRecord = parseJSONArray(generateCmpRecordStr); + + this.helpConfigInfo = parseJSONArray(reader.getAttrAsString(HELP_CONFIG_INFO, StringUtils.EMPTY)); + this.helpConfigUseInfo = parseJSONArray(reader.getAttrAsString(HELP_CONFIG_USE_INFO, StringUtils.EMPTY)); + this.searchContent = parseJSONArray(reader.getAttrAsString(SEARCH_CONTENT,StringUtils.EMPTY)); + this.filterContent = parseJSONArray(reader.getAttrAsString(FILTER_CONTENT, StringUtils.EMPTY)); + this.sortType = parseJSONArray(reader.getAttrAsString(SORT_TYPE, StringUtils.EMPTY)); + this.promptJump = reader.getAttrAsInt(PROMPT_JUMP, 0); + this.toolbarJump = reader.getAttrAsInt(TOOLBAR_JUMP, 0); + this.popupJump = reader.getAttrAsInt(POPUP_JUMP, 0); + + } + } + + private JSONArray parseJSONArray(String value) { + JSONArray ja; + try { + ja = new JSONArray(value); + } catch (JSONException e) { + ja = JSONFactory.createJSON(JSON.ARRAY); + + } + return ja; + } + + + @Override + public void writeXML(XMLPrintWriter writer) { + + writer.startTAG(XML) + .attr("cmpBoardClick", cmpBoardClick) + .attr("startTime", startTime) + .attr("lastTime", lastTime) + .attr("localCmpNumber", localCmpNumber) + .attr("remoteCmpNumber", remoteCmpNumber) + .attr("uploadCmpNumber", uploadCmpNumber) + .attr("generateCmpNumber", generateCmpNumber) + .attr("activateRecord", activateRecord.toString()) + .attr("generateCmpRecord", generateCmpRecord.toString()) + .attr(HELP_CONFIG_INFO, helpConfigInfo.toString()) + .attr(HELP_CONFIG_USE_INFO, helpConfigUseInfo.toString()) + .attr(SEARCH_CONTENT, searchContent.toString()) + .attr(FILTER_CONTENT, filterContent.toString()) + .attr(SORT_TYPE, sortType.toString()) + .attr(PROMPT_JUMP, promptJump) + .attr(TOOLBAR_JUMP, toolbarJump) + .attr(POPUP_JUMP, popupJump) + .end(); + } + + /** + * 累计信息 + */ + public String generateTotalInfo() { + collectCmpNumber(); + JSONObject jo = JSONObject.create(); + jo.put("userId", MarketConfig.getInstance().getBBSAttr().getBbsUid()); + jo.put("uuid", uuid); + jo.put("cmpBoardClickDaily", cmpBoardClickDaily()); + jo.put("pluginVersion", PluginContexts.currentContext().getVersion()); + jo.put("localCmpNumber", localCmpNumber); + jo.put("remoteCmpNumber", remoteCmpNumber); + jo.put("uploadCmpNumber", uploadCmpNumber); + jo.put("generateCmpNumber", generateCmpNumber); + jo.put("activateRecord", getValidActivateRecord()); + jo.put("generateCmpRecord", generateCmpRecord.toString()); + jo.put(HELP_CONFIG_INFO, helpConfigInfo.toString()); + jo.put(GROUPING_DETAIL, getGroupingDetail().toString()); + jo.put(SEARCH_CONTENT, searchContent.toString()); + jo.put(FILTER_CONTENT, filterContent.toString()); + jo.put(SORT_TYPE, sortType.toString()); + jo.put("guideInfo", assembleGuideInfo()); + return jo.toString(); + } + + private String assembleGuideInfo() { + JSONObject jo = JSONFactory.createJSON(JSON.OBJECT); + jo.put(PROMPT_JUMP, promptJump) + .put(TOOLBAR_JUMP, toolbarJump) + .put(POPUP_JUMP, popupJump); + return jo.toString(); + } + + public String getValidActivateRecord() { + JSONArray result = JSONFactory.createJSON(JSON.ARRAY); + String currentDate = DateTime.now().toString(SIMPLE_DATE_PATTERN); + for (Object o : activateRecord) { + JSONObject jo = (JSONObject) o; + if (!ComparatorUtils.equals(currentDate, jo.getString(ACTIVATE_DATE))) { + result.add(jo); + } + } + return result.toString(); + } + + @Override + public Object clone() throws CloneNotSupportedException { + + return null; + } + + public void setHelpConfigUseInfo(String templateId, String widgetId) { + for (int i = 0; i < helpConfigUseInfo.size(); i++) { + JSONObject jo = helpConfigUseInfo.getJSONObject(i); + if (ComparatorUtils.equals(templateId, jo.getString(TEMPLATE_ID))) { + JSONArray useInfo = jo.getJSONArray(HELP_CONFIG_USE_INFO); + if (!useInfo.contains(widgetId)) { + useInfo.add(widgetId); + } + jo.put(HELP_CONFIG_USE_INFO, useInfo); + return; + } + } + JSONObject jo = JSONFactory.createJSON(JSON.OBJECT); + JSONArray ja = JSONFactory.createJSON(JSON.ARRAY); + ja.add(widgetId); + jo.put(TEMPLATE_ID, templateId); + jo.put(HELP_CONFIG_USE_INFO, ja); + helpConfigUseInfo.add(jo); + saveInfo(); + } + + public JSONArray getHelpConfigUseInfoWithTemplate(String templateId) { + for (int i = 0; i < helpConfigUseInfo.size(); i++) { + JSONObject jo = helpConfigUseInfo.getJSONObject(i); + if (ComparatorUtils.equals(templateId, jo.getString(TEMPLATE_ID))) { + return jo.getJSONArray(HELP_CONFIG_USE_INFO); + } + } + return JSONFactory.createJSON(JSON.ARRAY); + } + + public void clear(){ + clearActiveRecord(); + clearGenerateCmpRecord(); + clearFilterContent(); + clearHelpConfigInfo(); + clearSearchContent(); + clearSortType(); + saveInfo(); + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/share/collect/ComponentSender.java b/designer-base/src/main/java/com/fr/design/mainframe/share/collect/ComponentSender.java new file mode 100644 index 000000000..5043e5fb7 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/share/collect/ComponentSender.java @@ -0,0 +1,45 @@ +package com.fr.design.mainframe.share.collect; + +import com.fr.design.mainframe.SiteCenterToken; +import com.fr.general.ComparatorUtils; +import com.fr.general.http.HttpToolbox; +import com.fr.json.JSONObject; +import com.fr.log.FineLoggerFactory; + +import java.util.HashMap; +import java.util.Map; + +/** + * created by Harrison on 2020/03/25 + **/ +public class ComponentSender { + + private static final String CLOUD_REUSE_URL = "https://cloud.fanruan.com/api/monitor/record_of_reusePlugin/single"; + + public static boolean send() { + + long start = System.currentTimeMillis(); + + String content = ComponentCollector.getInstance().generateTotalInfo(); + + long end = System.currentTimeMillis(); + FineLoggerFactory.getLogger().error("cal time cost {} ms", end - start); + return sendInfo(CLOUD_REUSE_URL, content); + } + + private static boolean sendInfo(String url, String content) { + + Map para = new HashMap<>(); + para.put("token", SiteCenterToken.generateToken()); + para.put("content", content); + + try { + String res = HttpToolbox.post(url, para); + return ComparatorUtils.equals(new JSONObject(res).get("status"), "success"); + } catch (Throwable e) { + // 客户不需要关心,错误等级为 debug 就行了 + FineLoggerFactory.getLogger().debug(e.getMessage(), e); + } + return false; + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/toast/DesignerToastMsgUtil.java b/designer-base/src/main/java/com/fr/design/mainframe/toast/DesignerToastMsgUtil.java new file mode 100644 index 000000000..e77cf8b86 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/toast/DesignerToastMsgUtil.java @@ -0,0 +1,106 @@ +package com.fr.design.mainframe.toast; + +import com.fr.base.BaseUtils; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.DesignerContext; +import com.fr.stable.Constants; + +import javax.swing.BorderFactory; +import javax.swing.Icon; +import javax.swing.JEditorPane; +import javax.swing.JPanel; +import javax.swing.SwingConstants; +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.Font; + +/** + * Created by kerry on 5/6/21 + */ +public class DesignerToastMsgUtil { + private static final int MIN_WIDTH = 134; + private static final int MAX_WIDTH = 454; + private static final Icon PROMPT_ICON = BaseUtils.readIcon("/com/fr/design/images/toast/toast_prompt.png"); + private static final Icon WARNING_ICON = BaseUtils.readIcon("/com/fr/design/images/toast/toast_warning.png"); + + private DesignerToastMsgUtil() { + + } + + + public static void toastPrompt(JPanel contendPane) { + toastPane(PROMPT_ICON, contendPane); + } + + public static void toastWarning(JPanel contendPane) { + toastPane(WARNING_ICON, contendPane); + + } + + public static void toastPrompt(String promptInfo) { + toastPrompt(toastPane(promptInfo)); + } + + public static void toastWarning(String warningInfo) { + toastWarning(toastPane(warningInfo)); + } + + private static JPanel toastPane(String text) { + UILabel promptLabel = new UILabel("" + text + ""); + JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + int width = promptLabel.getPreferredSize().width; + if (width > MAX_WIDTH) { + Dimension dimension = calculatePreferSize(text, promptLabel.getFont(), width); + jPanel.setPreferredSize(dimension); + } + jPanel.add(promptLabel, BorderLayout.NORTH); + return jPanel; + } + + private static void toastPane(Icon icon, JPanel contendPane) { + JPanel pane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + UILabel uiLabel = new UILabel(icon); + uiLabel.setVerticalAlignment(SwingConstants.TOP); + uiLabel.setBorder(BorderFactory.createEmptyBorder(3, 0, 0, 0)); + pane.add(uiLabel, BorderLayout.WEST); + pane.add(contendPane, BorderLayout.CENTER); + pane.setBorder(BorderFactory.createEmptyBorder(8, 15, 8, 15)); + contendPane.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 0)); + ToastMsgDialog dialog = new ToastMsgDialog(DesignerContext.getDesignerFrame(), pane); + dialog.setVisible(true); + } + + + private static Dimension calculatePreferSize(String text, Font font, int width) { + int limitWidth = Math.max(MIN_WIDTH, width); + limitWidth = Math.min(MAX_WIDTH, limitWidth); + return new Dimension(limitWidth, getHtmlHeight(text, limitWidth, font)); + } + + + private static int getHtmlHeight(String content, int width, Font font) { + StringBuffer limitDiv = new StringBuffer("
"); + return getHtmlContentDimension(content, limitDiv).height; + } + + + private static Dimension getHtmlContentDimension(String content, StringBuffer limitDiv) { + content = limitDiv.append(content).append("
").toString(); + JEditorPane editorPane = new JEditorPane(); + editorPane.setContentType("text/html"); + editorPane.setText(content); + return editorPane.getPreferredSize(); + } + + private static String getFontWrapStyle(Font font) { + double dpi96 = Constants.FR_PAINT_RESOLUTION; + double dpi72 = Constants.DEFAULT_FONT_PAINT_RESOLUTION; + return new StringBuilder() + .append(";font-size:").append(font.getSize() * dpi96 / dpi72) + .append("pt;font-family:").append(font.getFontName()) + .toString(); + } + +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/toast/ToastMsgDialog.java b/designer-base/src/main/java/com/fr/design/mainframe/toast/ToastMsgDialog.java new file mode 100644 index 000000000..8fee83378 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/toast/ToastMsgDialog.java @@ -0,0 +1,153 @@ +package com.fr.design.mainframe.toast; + +import com.fr.concurrent.NamedThreadFactory; +import com.fr.design.dialog.UIDialog; +import com.fr.design.mainframe.DesignerContext; +import com.fr.module.ModuleContext; + +import javax.swing.JPanel; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.Point; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +/** + * Created by kerry on 4/29/21 + */ +public class ToastMsgDialog extends UIDialog { + private static final int MIN_HEIGHT = 36; + private static final String TOAST_MSG_TIMER = "TOAST_MSG_TIMER"; + private ScheduledExecutorService TIMER; + private int hide_height = 0; + private JPanel contentPane; + + public ToastMsgDialog(Frame parent, JPanel panel) { + super(parent); + setFocusable(false); + setAutoRequestFocus(false); + setUndecorated(true); + contentPane = panel; + initComponent(parent); + } + + private void initComponent(Frame parent) { + this.getContentPane().setLayout(null); + this.getContentPane().add(contentPane); + Dimension dimension = calculatePreferSize(); + hide_height = dimension.height; + setSize(new Dimension(dimension.width, 0)); + contentPane.setSize(dimension); + setLocationRelativeTo(DesignerContext.getDesignerFrame().getContentFrame()); + int positionY = DesignerContext.getDesignerFrame().getContentFrame().getLocationOnScreen().y + 10; + setLocation((parent.getWidth() - dimension.width) / 2, positionY); + addMouseEvent(contentPane); + } + + + private Dimension calculatePreferSize() { + Dimension contentDimension = contentPane.getPreferredSize(); + int height = Math.max(MIN_HEIGHT, contentDimension.height); + return new Dimension(contentDimension.width, height); + } + + + public void display(JPanel outerJPanel) { + outerJPanel.setLocation(0, -hide_height); + ScheduledExecutorService TIP_TOOL_TIMER = createToastScheduleExecutorService(); + TIP_TOOL_TIMER.scheduleAtFixedRate(new Runnable() { + @Override + public void run() { + Point point = outerJPanel.getLocation(); + if (point.y >= 0) { + TIP_TOOL_TIMER.shutdown(); + disappear(outerJPanel); + } + int showDistance = 5 + point.y < 0 ? 5 : -point.y; + outerJPanel.setLocation(point.x, point.y + showDistance); + Dimension dimension = ToastMsgDialog.this.getSize(); + ToastMsgDialog.this.setSize(new Dimension(dimension.width, dimension.height + showDistance)); + } + }, 0, 50, TimeUnit.MILLISECONDS); + + } + + private void disappear(JPanel outerJPanel) { + TIMER = createToastScheduleExecutorService(); + TIMER.schedule(new Runnable() { + @Override + public void run() { + ScheduledExecutorService TIP_TOOL_TIMER = createToastScheduleExecutorService(); + TIP_TOOL_TIMER.scheduleAtFixedRate(new Runnable() { + @Override + public void run() { + Point point = outerJPanel.getLocation(); + if (point.y <= -hide_height) { + TIP_TOOL_TIMER.shutdown(); + ToastMsgDialog.this.setVisible(false); + ToastMsgDialog.this.dispose(); + } + outerJPanel.setLocation(point.x, point.y - 5); + Dimension dimension = ToastMsgDialog.this.getSize(); + ToastMsgDialog.this.setSize(new Dimension(dimension.width, dimension.height - 5)); + } + }, 0,50, TimeUnit.MILLISECONDS); + + } + }, 5000, TimeUnit.MILLISECONDS); + } + + private ScheduledExecutorService createToastScheduleExecutorService() { + return ModuleContext.getExecutor().newSingleThreadScheduledExecutor(new NamedThreadFactory(TOAST_MSG_TIMER)); + } + + private void addMouseEvent(JPanel jPanel) { + jPanel.addMouseListener(new MouseListener() { + @Override + public void mouseClicked(MouseEvent e) { + + } + + @Override + public void mousePressed(MouseEvent e) { + + } + + @Override + public void mouseReleased(MouseEvent e) { + + } + + @Override + public void mouseEntered(MouseEvent e) { + TIMER.shutdownNow(); + } + + @Override + public void mouseExited(MouseEvent e) { + disappear(jPanel); + } + }); + } + + + @Override + public void checkValid() throws Exception { + } + + public void setVisible(boolean visible) { + super.setVisible(visible); + if (visible) { + display(contentPane); + } + } + + @Override + public void dispose() { + super.dispose(); + } + + +} 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 fa9835492..b79ba23b1 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 @@ -169,6 +169,12 @@ public abstract class ToolBarMenuDock { } } + public void updateEnable() { + for (int i = 0, count = ArrayUtils.getLength(menus); i < count; i++) { + menus[i].updateEnable(); + } + } + /** * 更新toolbar */ @@ -585,6 +591,7 @@ public abstract class ToolBarMenuDock { shortCuts.add(new TechSolutionAction()); shortCuts.add(SeparatorDef.DEFAULT); + shortCuts.add(new TemplateStoreAction()); LocaleCenter.buildAction(new LocaleAction() { @Override diff --git a/designer-base/src/main/java/com/fr/design/menu/MenuDef.java b/designer-base/src/main/java/com/fr/design/menu/MenuDef.java index f2ed81394..798d4870a 100644 --- a/designer-base/src/main/java/com/fr/design/menu/MenuDef.java +++ b/designer-base/src/main/java/com/fr/design/menu/MenuDef.java @@ -1,12 +1,17 @@ package com.fr.design.menu; import com.fr.base.svg.IconUtils; +import com.fr.design.file.HistoryTemplateListCache; import com.fr.design.gui.ibutton.UIButton; import com.fr.design.gui.imenu.*; import com.fr.design.gui.iscrollbar.UIScrollBar; +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.JTemplate; import com.fr.design.utils.gui.GUICoreUtils; import com.fr.stable.StringUtils; +import java.util.HashSet; +import java.util.Set; import javax.swing.*; import javax.swing.event.MenuEvent; import javax.swing.event.MenuListener; @@ -25,6 +30,17 @@ public class MenuDef extends ShortCut { private static final int MENU_DEFAULTWDITH = 156; private static final int BLANK_WIDTH = 30; + + private static final Set FORBIDDEN_SET = new HashSet<>(); + + { + FORBIDDEN_SET.add(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_M_Template")); + FORBIDDEN_SET.add(Toolkit.i18nText("Fine-Design_Report_M_Insert")); + FORBIDDEN_SET.add(Toolkit.i18nText("Fine-Design_Basic_Action_Add")); + FORBIDDEN_SET.add(KeySetUtils.CELL.getMenuKeySetName()); + FORBIDDEN_SET.add(KeySetUtils.INSERT_FLOAT.getMenuKeySetName()); + } + protected String name; //右侧属性表弹出框重绘 protected Boolean isEastAttr = false; @@ -277,6 +293,10 @@ public class MenuDef extends ShortCut { } } + public void updateEnable() { + setEnabled(checkEnable()); + } + /** * 更新菜单 * @@ -390,6 +410,20 @@ public class MenuDef extends ShortCut { toolBar.add(this.createUIButton()); } + private boolean checkEnable() { + if (FORBIDDEN_SET.contains(this.getName())) { + JTemplate template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + boolean flag = true; + if (template != null) { + flag = template.checkEnable(); + } + if (!flag) { + return false; + } + } + return true; + } + protected MenuListener createMenuListener() { return menuDefListener; @@ -411,7 +445,6 @@ public class MenuDef extends ShortCut { if (!(source instanceof JMenu)) { return; } - MenuDef.this.updateMenu(); } }; diff --git a/designer-base/src/main/java/com/fr/design/menu/ToolBarDef.java b/designer-base/src/main/java/com/fr/design/menu/ToolBarDef.java index 07c51312e..8617ded9b 100644 --- a/designer-base/src/main/java/com/fr/design/menu/ToolBarDef.java +++ b/designer-base/src/main/java/com/fr/design/menu/ToolBarDef.java @@ -1,7 +1,11 @@ package com.fr.design.menu; +import com.fr.design.actions.UpdateAction; +import com.fr.design.file.HistoryTemplateListCache; import com.fr.design.gui.itoolbar.UIToolBarUI; import com.fr.design.gui.itoolbar.UIToolbar; +import com.fr.design.mainframe.JTemplate; +import java.util.Set; import org.jetbrains.annotations.Nullable; import javax.swing.*; @@ -82,4 +86,25 @@ public class ToolBarDef { } } + public void refreshToolBar(Set set) { + JTemplate template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + if (template != null) { + for (int i = 0; i < getShortCutCount(); i++) { + ShortCut shortCut = getShortCut(i); + if (shortCut instanceof MenuDef) { + MenuDef menuDef = (MenuDef) shortCut; + if (set.contains(menuDef.getName())) { + menuDef.setEnabled(template.checkEnable()); + } + } + if (shortCut instanceof UpdateAction) { + UpdateAction updateAction = (UpdateAction) shortCut; + if (set.contains(updateAction.getName())) { + updateAction.setEnabled(template.checkEnable()); + } + } + } + } + } + } \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/module/DesignModuleFactory.java b/designer-base/src/main/java/com/fr/design/module/DesignModuleFactory.java index f3e8c4ebd..5ff882f64 100644 --- a/designer-base/src/main/java/com/fr/design/module/DesignModuleFactory.java +++ b/designer-base/src/main/java/com/fr/design/module/DesignModuleFactory.java @@ -243,14 +243,6 @@ public class DesignModuleFactory { return bp; } - - public static void clearChartPropertyPane() { - if (instance.chartPropertyPaneClass != null) { - StableUtils.clearInstance(instance.chartPropertyPaneClass); - } - } - - public static void registerButtonDetailPaneClass(Class clazz) { instance.buttonDetailPaneClass = clazz; } diff --git a/designer-base/src/main/java/com/fr/design/os/impl/PopupDialogSaveAction.java b/designer-base/src/main/java/com/fr/design/os/impl/PopupDialogSaveAction.java index 019ee3d97..c0b060005 100644 --- a/designer-base/src/main/java/com/fr/design/os/impl/PopupDialogSaveAction.java +++ b/designer-base/src/main/java/com/fr/design/os/impl/PopupDialogSaveAction.java @@ -1,6 +1,6 @@ package com.fr.design.os.impl; -import com.fr.design.gui.controlpane.UIListControlPane; +import com.fr.design.gui.controlpane.UIControlPane; import com.fr.stable.os.OperatingSystem; import com.fr.stable.os.support.OSBasedAction; @@ -15,7 +15,7 @@ import java.awt.*; */ public class PopupDialogSaveAction implements OSBasedAction { - private UIListControlPane currentControlPane; + private UIControlPane currentControlPane; private Window popupDialog; @Override @@ -26,7 +26,7 @@ public class PopupDialogSaveAction implements OSBasedAction { } } - public void register(UIListControlPane currentControlPane, Window popupDialog) { + public void register(UIControlPane currentControlPane, Window popupDialog) { this.currentControlPane = currentControlPane; this.popupDialog = popupDialog; } diff --git a/designer-base/src/main/java/com/fr/design/selection/SelectableElement.java b/designer-base/src/main/java/com/fr/design/selection/SelectableElement.java index 083cd4cb5..8ecb1dcf2 100644 --- a/designer-base/src/main/java/com/fr/design/selection/SelectableElement.java +++ b/designer-base/src/main/java/com/fr/design/selection/SelectableElement.java @@ -15,6 +15,16 @@ public interface SelectableElement { * @return */ @SuppressWarnings("rawtypes") - public QuickEditor getQuickEditor(TargetComponent tc); + QuickEditor getQuickEditor(TargetComponent tc); + /** + * @Description 有些实现类中getQuickEditor会在获取editor后,再填充面板。这个方法只会获取editor,不会填充面板 + * @param: tc + * @return com.fr.design.selection.QuickEditor + * @Author Henry.Wang + * @Date 2021/4/2 15:02 + **/ + default QuickEditor getQuickEditorWithoutPopulate(TargetComponent tc){ + return null; + } } \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/style/color/ColorButton.java b/designer-base/src/main/java/com/fr/design/style/color/ColorButton.java index f5f2288ff..a052f99f1 100644 --- a/designer-base/src/main/java/com/fr/design/style/color/ColorButton.java +++ b/designer-base/src/main/java/com/fr/design/style/color/ColorButton.java @@ -126,6 +126,11 @@ public class ColorButton extends AbstractSelectBox { public void setVisible(boolean b) { super.setVisible(b); } + + @Override + protected boolean selectRealTime() { + return false; + } }; colorPane.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { diff --git a/designer-base/src/main/java/com/fr/design/utils/gui/GUIPaintUtils.java b/designer-base/src/main/java/com/fr/design/utils/gui/GUIPaintUtils.java index c4efc0282..fb530fd92 100644 --- a/designer-base/src/main/java/com/fr/design/utils/gui/GUIPaintUtils.java +++ b/designer-base/src/main/java/com/fr/design/utils/gui/GUIPaintUtils.java @@ -4,12 +4,15 @@ import com.fr.base.vcs.DesignerMode; import com.fr.design.constants.UIConstants; import com.fr.stable.Constants; +import com.fr.stable.os.OperatingSystem; import java.awt.*; import java.awt.geom.GeneralPath; import java.awt.geom.RoundRectangle2D; public class GUIPaintUtils { + private static boolean macos = OperatingSystem.isMacos(); + public static final void drawBorder(Graphics2D g2d, int x, int y, int width, int height, boolean isRound, int rectDirection) { drawBorder(g2d, x, y, width, height, isRound, rectDirection, false); } @@ -39,10 +42,14 @@ public class GUIPaintUtils { g2d.drawLine(x, y, x, height - 1); g2d.drawLine(x, height - 1, x + 3, height - 1); } else { - double offsetX = Math.min(GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration().getDefaultTransform().getScaleX() - 1, 0.5d); - double offsetY = Math.min(GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration().getDefaultTransform().getScaleY() - 1, 0.5d); - Shape shape = new RoundRectangle2D.Double(x + offsetX, y + offsetY, width - 1d, height - 1d, UIConstants.ARC, UIConstants.ARC); - g2d.draw(shape); + if (macos) { + g2d.drawRoundRect(x, y, width - 1, height - 1, UIConstants.ARC, UIConstants.ARC); + } else { + double offsetX = Math.min(GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration().getDefaultTransform().getScaleX() - 1, 0.5d); + double offsetY = Math.min(GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration().getDefaultTransform().getScaleY() - 1, 0.5d); + Shape shape = new RoundRectangle2D.Double(x + offsetX, y + offsetY, width - 1d, height - 1d, UIConstants.ARC, UIConstants.ARC); + g2d.draw(shape); + } } g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); } else { diff --git a/designer-base/src/main/java/com/fr/design/widget/EventCreator.java b/designer-base/src/main/java/com/fr/design/widget/EventCreator.java index 4fdfd7ed8..63d40515c 100644 --- a/designer-base/src/main/java/com/fr/design/widget/EventCreator.java +++ b/designer-base/src/main/java/com/fr/design/widget/EventCreator.java @@ -18,6 +18,10 @@ public class EventCreator extends NameableSelfCreator { this.eventName = eventName; } + public String getEventName() { + return eventName; + } + @Override public Nameable createNameable(UnrepeatedNameHelper helper) { return new NameObject(helper.createUnrepeatedName(this.menuName()),new Listener(this.eventName)) ; @@ -47,13 +51,17 @@ public class EventCreator extends NameableSelfCreator { return eventName; } } + @Override - public void saveUpdatedBean(ListModelElement wrapper, Object bean) { - ((NameObject)wrapper.wrapper).setObject(bean); + public void saveUpdatedBean(ListModelElement element, Object bean) { + if (bean instanceof Listener){ + ((Listener)bean).setName(element.wrapper.getName()); + } + ((NameObject)element.wrapper).setObject(bean); } @Override public String createTooltip() { return null; } -} \ No newline at end of file +} diff --git a/designer-base/src/main/java/com/fr/design/worker/WorkerManager.java b/designer-base/src/main/java/com/fr/design/worker/WorkerManager.java new file mode 100644 index 000000000..1346da453 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/worker/WorkerManager.java @@ -0,0 +1,49 @@ +package com.fr.design.worker; + +import java.util.HashMap; +import java.util.Map; +import javax.swing.SwingWorker; +import org.jetbrains.annotations.Nullable; + +/** + * @author hades + * @version 10.0 + * Created by hades on 2021/4/2 + */ +public class WorkerManager { + + private static final WorkerManager INSTANCE = new WorkerManager(); + + private Map workerMap = new HashMap<>(); + + public static WorkerManager getInstance() { + return INSTANCE; + } + + @Nullable + public SwingWorker getWorker(String taskName) { + return workerMap.get(taskName); + } + + public boolean isCompleted(String taskName) { + SwingWorker worker = getWorker(taskName); + return worker == null || worker.isDone(); + } + + public void registerWorker(String taskName, SwingWorker worker) { + workerMap.put(taskName, worker); + } + + public void removeWorker(String taskName) { + workerMap.remove(taskName); + } + + public void cancelWorker(String taskName) { + SwingWorker worker = getWorker(taskName); + if (worker != null && !worker.isDone()) { + worker.cancel(true); + removeWorker(taskName); + } + } + +} diff --git a/designer-base/src/main/java/com/fr/design/worker/open/OpenResult.java b/designer-base/src/main/java/com/fr/design/worker/open/OpenResult.java new file mode 100644 index 000000000..a8b6f0c57 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/worker/open/OpenResult.java @@ -0,0 +1,28 @@ +package com.fr.design.worker.open; + +import com.fr.base.io.BaseBook; + +/** + * @author hades + * @version 10.0 + * Created by hades on 2021/4/13 + */ +public class OpenResult { + + private final T baseBook; + + private final R ref; + + public OpenResult(T baseBook, R r) { + this.baseBook = baseBook; + this.ref = r; + } + + public T getBaseBook() { + return baseBook; + } + + public R getRef() { + return ref; + } +} 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 new file mode 100644 index 000000000..819660a99 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/worker/open/OpenWorker.java @@ -0,0 +1,154 @@ +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.i18n.Toolkit; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.DesignerFrameFileDealerPane; +import com.fr.design.mainframe.JTemplate; +import com.fr.design.worker.WorkerManager; +import com.fr.exception.DecryptTemplateException; +import com.fr.file.FILE; +import com.fr.general.ComparatorUtils; +import com.fr.log.FineLoggerFactory; + +import javax.swing.JOptionPane; +import javax.swing.SwingWorker; +import javax.swing.UIManager; +import java.util.concurrent.Callable; +import java.util.concurrent.CancellationException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +/** + * 模板打开的worker + * + * @author hades + * @version 10.0 + * Created by hades on 2021/4/9 + */ +public class OpenWorker extends SwingWorker { + + private static final int TIME_OUT = 400; + + private final Callable callable; + + private final JTemplate template; + + private Callable> templateCallable; + + private boolean slowly = false; + + private String taskName; + + private T result; + + public OpenWorker(Callable callable, JTemplate template) { + this.callable = callable; + this.template = template; + } + + @Override + protected T doInBackground() throws Exception { + return this.callable.call(); + } + + @Override + protected void done() { + try { + result = get(); + } catch (CancellationException ignored) { + return; + } catch (Throwable t) { + processFailed(); + Throwable cause = t.getCause(); + if (cause instanceof DecryptTemplateException) { + FineJOptionPane.showMessageDialog( + DesignerContext.getDesignerFrame(), + Toolkit.i18nText("Fine-Design_Encrypt_Decrypt_Exception"), + Toolkit.i18nText("Fine-Design_Basic_Alert"), + JOptionPane.WARNING_MESSAGE, + UIManager.getIcon("OptionPane.errorIcon") + ); + } + if (cause instanceof ChartNotFoundException) { + FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), + Toolkit.i18nText("Fine-Design_Chart_Not_Found_Exception"), + Toolkit.i18nText("Fine-Design_Basic_Error"), + JOptionPane.ERROR_MESSAGE, + UIManager.getIcon("OptionPane.errorIcon")); + } + FineLoggerFactory.getLogger().error(t.getMessage(), t); + return; + } + // 后续动作 + processResult(); + } + + private void processResult() { + this.template.setOpening(false); + if (slowly && templateCallable != null) { + try { + JTemplate book = templateCallable.call(); + FILE tplFile = book.getEditingFILE(); + JTemplate currentTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + // 当前tab页是正在打开的模板 + if (ComparatorUtils.equals(currentTemplate.getEditingFILE(), tplFile)) { + currentTemplate.whenClose(); + DesignerContext.getDesignerFrame().addAndActivateJTemplate(book); + HistoryTemplateListCache.getInstance().replaceCurrentEditingTemplate(book); + } else { + // 当前tab页是其他模板 + for (int i = 0, len = HistoryTemplateListCache.getInstance().getHistoryCount(); i < len; i++) { + JTemplate template = HistoryTemplateListCache.getInstance().getTemplate(i); + if (ComparatorUtils.equals(template.getEditingFILE(), book.getEditingFILE())) { + template.whenClose(); + HistoryTemplateListCache.getInstance().getHistoryList().set(i, book); + break; + } + } + } + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + } + DesignerFrameFileDealerPane.getInstance().stateChange(); + WorkerManager.getInstance().removeWorker(taskName); + } + + private void processFailed() { + this.template.setOpenFailed(true); + this.template.setOpening(false); + DesignerContext.getDesignerFrame().getCenterTemplateCardPane().showOpenFailedCover(); + DesignerFrameFileDealerPane.getInstance().stateChange(); + WorkerManager.getInstance().removeWorker(taskName); + + } + + public void addCallBack(Callable> templateCallable) { + this.templateCallable = templateCallable; + } + + public void start(String taskName) { + this.taskName = taskName; + this.template.setOpening(true); + this.execute(); + WorkerManager.getInstance().registerWorker(taskName, this); + } + + public T getResult() { + if (result != null) { + return result; + } + try { + return this.get(TIME_OUT, TimeUnit.MILLISECONDS); + } catch (TimeoutException e) { + slowly = true; + } catch (Exception exception) { + FineLoggerFactory.getLogger().error(exception.getMessage(), exception); + WorkerManager.getInstance().removeWorker(taskName); + } + return null; + } +} diff --git a/designer-base/src/main/java/com/fr/design/worker/save/CallbackSaveWorker.java b/designer-base/src/main/java/com/fr/design/worker/save/CallbackSaveWorker.java new file mode 100644 index 000000000..f8a0f5d4f --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/worker/save/CallbackSaveWorker.java @@ -0,0 +1,75 @@ +package com.fr.design.worker.save; + +import com.fr.common.util.Collections; +import com.fr.design.mainframe.JTemplate; +import java.util.LinkedList; +import java.util.List; +import java.util.concurrent.Callable; + +/** + * 保存之后需要做些外部回调 + * + * @author hades + * @version 10.0 + * Created by hades on 2021/4/8 + */ +public class CallbackSaveWorker extends SaveWorker { + + private List successRunnableList; + + private List failRunnableList; + + public CallbackSaveWorker(Callable callable, JTemplate template) { + super(callable, template); + } + + @Override + protected void done() { + super.done(); + + if (success) { + fireRunnable(successRunnableList); + } else { + fireRunnable(failRunnableList); + } + successRunnableList = null; + failRunnableList = null; + } + + private void fireRunnable(List list) { + if (Collections.isEmpty(list)) { + return; + } + for (Runnable runnable : list) { + runnable.run(); + } + } + + private void addCallback(List runnableList, Runnable runnable) { + if (runnableList == null) { + runnableList = new LinkedList<>(); + } + if (runnable != null) { + runnableList.add(runnable); + } + } + + public void addSuccessCallback(Runnable successRunnable) { + if (successRunnableList == null) { + successRunnableList = new LinkedList<>(); + } + if (successRunnable != null) { + successRunnableList.add(successRunnable); + } + } + + public void addFailCallback(Runnable failRunnable) { + if (failRunnableList == null) { + failRunnableList = new LinkedList<>(); + } + if (failRunnable != null) { + failRunnableList.add(failRunnable); + } + } + +} diff --git a/designer-base/src/main/java/com/fr/design/worker/save/EmptyCallBackSaveWorker.java b/designer-base/src/main/java/com/fr/design/worker/save/EmptyCallBackSaveWorker.java new file mode 100644 index 000000000..27e85f5ec --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/worker/save/EmptyCallBackSaveWorker.java @@ -0,0 +1,37 @@ +package com.fr.design.worker.save; + +import com.fr.design.mainframe.JTemplate; +import java.util.concurrent.Callable; + +/** + * 空实现 + * + * @author hades + * @version 10.0 + * Created by hades on 2021/4/9 + */ +public class EmptyCallBackSaveWorker extends CallbackSaveWorker { + + public EmptyCallBackSaveWorker(Callable callable, JTemplate template) { + super(callable, template); + } + + public EmptyCallBackSaveWorker() { + this(null, null); + } + + @Override + protected Boolean doInBackground() throws Exception { + return false; + } + + @Override + protected void done() { + // do nothing + } + + @Override + public void start(String taskName) { + // do nothing + } +} 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 new file mode 100644 index 000000000..f47a4f88e --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/worker/save/SaveWorker.java @@ -0,0 +1,99 @@ +package com.fr.design.worker.save; + +import com.fr.design.dialog.FineJOptionPane; +import com.fr.design.file.HistoryTemplateListCache; +import com.fr.design.i18n.Toolkit; +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.worker.WorkerManager; +import com.fr.general.ComparatorUtils; +import com.fr.log.FineLoggerFactory; +import java.awt.Frame; +import java.util.concurrent.Callable; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import javax.swing.JOptionPane; +import javax.swing.SwingWorker; + +/** + * 模板保存的worker + * + * @author hades + * @version 10.0 + * Created by hades on 2021/4/1 + */ +public class SaveWorker extends SwingWorker { + + private static final int TIME_OUT = 400; + + private final Callable callable; + + private String taskName; + + private final JTemplate template; + + protected boolean success; + + private boolean slowly; + + public SaveWorker(Callable callable, JTemplate template) { + this.callable = callable; + this.template = template; + } + + @Override + protected Boolean doInBackground() throws Exception { + return callable.call(); + } + + @Override + protected void done() { + try { + success = get(); + } catch (Exception e) { + processResult(); + FineLoggerFactory.getLogger().error(e.getMessage(), e); + boolean minimized = (DesignerContext.getDesignerFrame().getExtendedState() & Frame.ICONIFIED ) != 0; + FineJOptionPane.showMessageDialog( + minimized ? null : DesignerContext.getDesignerFrame(), + Toolkit.i18nText("Fine-Design-Basic_Save_Failure"), + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"), + JOptionPane.ERROR_MESSAGE); + return; + } + processResult(); + } + + private void processResult() { + this.template.setSaving(false); + // 恢复界面 + if (slowly && ComparatorUtils.equals(this.template.getName(), HistoryTemplateListCache.getInstance().getCurrentEditingTemplate().getName())) { + DesignerContext.getDesignerFrame().refreshUIToolBar(); + DesignerContext.getDesignerFrame().getCenterTemplateCardPane().hideCover(); + } + DesignerFrameFileDealerPane.getInstance().stateChange(); + WorkerManager.getInstance().removeWorker(taskName); + } + + public void start(String taskName) { + this.taskName = taskName; + 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); + } + } +} diff --git a/designer-base/src/main/java/com/fr/file/FILEChooserPane.java b/designer-base/src/main/java/com/fr/file/FILEChooserPane.java index 43c3f43ad..4bacf9a85 100644 --- a/designer-base/src/main/java/com/fr/file/FILEChooserPane.java +++ b/designer-base/src/main/java/com/fr/file/FILEChooserPane.java @@ -892,7 +892,7 @@ public class FILEChooserPane extends BasicPane { if (access(selectedFile) && access(currentDirectory)) { if (selectedFile.exists()) { int selVal = FineJOptionPane.showConfirmDialog(dialog, Toolkit.i18nText("Fine-Design_Basic_Utils_Would_You_Like_To_Cover_The_Current_File") + " ?", - Toolkit.i18nText("Fine-Design_Basic_Confirm"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE); + Toolkit.i18nText("Fine-Design_Basic_Confirm"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE); if (selVal == JOptionPane.YES_OPTION) { option = JOPTIONPANE_OK_OPTION; saveDictionary(); @@ -913,9 +913,8 @@ public class FILEChooserPane extends BasicPane { private boolean access(FILE selectedFile) { - boolean access = false; + boolean access = true; try { - access = FRContext.getOrganizationOperator().canAccess(selectedFile.getPath()); if (selectedFile.isEnvFile() && selectedFile instanceof FileNodeFILE) { FileNodeFILE fileNodeFILE = ((FileNodeFILE) selectedFile); access = access && fileNodeFILE.hasFullAuth() && NodeAuthProcessor.getInstance().checkFileNodeAuth(new FileNode(fileNodeFILE.getPath(), fileNodeFILE.isDirectory())); @@ -1158,7 +1157,7 @@ public class FILEChooserPane extends BasicPane { }; } if (FILEChooserPane.this.showWebReport) { - webReportFILE = new FileNodeFILE(FRContext.getCommonOperator().getWebRootPath()); + webReportFILE = new FileNodeFILE(FileNodeFILE.webRootPath); } if (FILEChooserPane.this.showLoc) { processSystemFile(); @@ -1219,7 +1218,7 @@ public class FILEChooserPane extends BasicPane { } if (FILEChooserPane.this.showWebReport) { - webReportFILE = new FileNodeFILE(FRContext.getCommonOperator().getWebRootPath()); + webReportFILE = new FileNodeFILE(FileNodeFILE.webRootPath); } if (FILEChooserPane.this.showLoc) { processSystemFile(); diff --git a/designer-base/src/main/java/com/fr/file/FILEFactory.java b/designer-base/src/main/java/com/fr/file/FILEFactory.java index 5a19108ee..3d48bab34 100644 --- a/designer-base/src/main/java/com/fr/file/FILEFactory.java +++ b/designer-base/src/main/java/com/fr/file/FILEFactory.java @@ -32,7 +32,7 @@ public class FILEFactory { return new FileNodeFILE(new FileNode(path.substring(envPath.length() + 1), false)); } else if (path.startsWith(WEBREPORT_PREFIX)) { return new FileNodeFILE(new FileNode(path.substring(WEBREPORT_PREFIX.length()), false), - FRContext.getCommonOperator().getWebRootPath()); + FileNodeFILE.webRootPath); } else if (path.startsWith(FILE_PREFIX)) { return new FileFILE(new java.io.File(path.substring(FILE_PREFIX.length()))); } else { @@ -50,7 +50,7 @@ public class FILEFactory { fixFILENodeAuth(new FileNode(path.substring(ENV_PREFIX.length()), true)); } else if (path.startsWith(WEBREPORT_PREFIX)) { return new FileNodeFILE(new FileNode(path.substring(WEBREPORT_PREFIX.length()), true), - FRContext.getCommonOperator().getWebRootPath()); + FileNodeFILE.webRootPath); } else if (path.startsWith(FILE_PREFIX)) { return new FileFILE(new java.io.File(path.substring(FILE_PREFIX.length()))); } else { diff --git a/designer-base/src/main/java/com/fr/file/FileNodeFILE.java b/designer-base/src/main/java/com/fr/file/FileNodeFILE.java index d096faf8a..bcf1ff768 100644 --- a/designer-base/src/main/java/com/fr/file/FileNodeFILE.java +++ b/designer-base/src/main/java/com/fr/file/FileNodeFILE.java @@ -32,7 +32,7 @@ import java.util.Arrays; public class FileNodeFILE implements FILE { - private static String webRootPath = FRContext.getCommonOperator().getWebRootPath(); + public static String webRootPath = FRContext.getCommonOperator().getWebRootPath(); private static String[] supportTypes = FRContext.getFileNodes().getSupportedTypes(); static { 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 5eaab74a5..b3945d0d7 100644 --- a/designer-base/src/main/java/com/fr/start/BaseDesigner.java +++ b/designer-base/src/main/java/com/fr/start/BaseDesigner.java @@ -155,7 +155,7 @@ public abstract class BaseDesigner extends ToolBarMenuDock { isException = true;//此时有文件nullpointer异常,执行打开空文件 } } - if (file.exists() && !isException) { + if (file != null && file.exists() && !isException) { df.openTemplate(file); } else { df.addAndActivateJTemplate(); diff --git a/designer-base/src/main/resources/com/fr/design/images/bbs/bbs_normal.svg b/designer-base/src/main/resources/com/fr/design/images/bbs/bbs_normal.svg index ae72bfa4d..4a9711e35 100644 --- a/designer-base/src/main/resources/com/fr/design/images/bbs/bbs_normal.svg +++ b/designer-base/src/main/resources/com/fr/design/images/bbs/bbs_normal.svg @@ -4,4 +4,4 @@ - + \ No newline at end of file diff --git a/designer-base/src/main/resources/com/fr/design/images/buttonicon/check.png b/designer-base/src/main/resources/com/fr/design/images/buttonicon/check.png new file mode 100644 index 000000000..36c4238a2 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/buttonicon/check.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/buttonicon/run24.png b/designer-base/src/main/resources/com/fr/design/images/buttonicon/run24.png index 8ebe92439..67127219d 100644 Binary files a/designer-base/src/main/resources/com/fr/design/images/buttonicon/run24.png and b/designer-base/src/main/resources/com/fr/design/images/buttonicon/run24.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/control/addPopup_disabled.svg b/designer-base/src/main/resources/com/fr/design/images/control/addPopup_disabled.svg new file mode 100644 index 000000000..d48e1a27b --- /dev/null +++ b/designer-base/src/main/resources/com/fr/design/images/control/addPopup_disabled.svg @@ -0,0 +1,16 @@ + + + 编组 + + + + + + + + + + + + + \ No newline at end of file diff --git a/designer-base/src/main/resources/com/fr/design/images/control/addPopup_normal.svg b/designer-base/src/main/resources/com/fr/design/images/control/addPopup_normal.svg new file mode 100644 index 000000000..8cec802fe --- /dev/null +++ b/designer-base/src/main/resources/com/fr/design/images/control/addPopup_normal.svg @@ -0,0 +1,14 @@ + + + 编组备份 + + + + + + + + + + + \ No newline at end of file diff --git a/designer-base/src/main/resources/com/fr/design/images/control/edit_disable.svg b/designer-base/src/main/resources/com/fr/design/images/control/edit_disabled.svg similarity index 100% rename from designer-base/src/main/resources/com/fr/design/images/control/edit_disable.svg rename to designer-base/src/main/resources/com/fr/design/images/control/edit_disabled.svg diff --git a/designer-base/src/main/resources/com/fr/design/images/control/remove_disable.svg b/designer-base/src/main/resources/com/fr/design/images/control/remove_disabled.svg similarity index 100% rename from designer-base/src/main/resources/com/fr/design/images/control/remove_disable.svg rename to designer-base/src/main/resources/com/fr/design/images/control/remove_disabled.svg diff --git a/designer-base/src/main/resources/com/fr/design/images/correct.png b/designer-base/src/main/resources/com/fr/design/images/correct.png new file mode 100644 index 000000000..90f74f7a9 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/correct.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/error.png b/designer-base/src/main/resources/com/fr/design/images/error.png new file mode 100644 index 000000000..89601dfb1 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/error.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/file/grey_saving_close.gif b/designer-base/src/main/resources/com/fr/design/images/file/grey_saving_close.gif new file mode 100644 index 000000000..a3c061b0f Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/file/grey_saving_close.gif differ diff --git a/designer-base/src/main/resources/com/fr/design/images/file/white_saving_close.gif b/designer-base/src/main/resources/com/fr/design/images/file/white_saving_close.gif new file mode 100644 index 000000000..2c287adbb Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/file/white_saving_close.gif differ diff --git a/designer-base/src/main/resources/com/fr/design/images/form/designer/widget_apply_icon.png b/designer-base/src/main/resources/com/fr/design/images/form/designer/widget_apply_icon.png new file mode 100644 index 000000000..3817f4c47 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/form/designer/widget_apply_icon.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/lookandfeel/Icon_Narrow_Down_16x16.png b/designer-base/src/main/resources/com/fr/design/images/lookandfeel/Icon_Narrow_Down_16x16.png new file mode 100644 index 000000000..cf65b3bc4 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/lookandfeel/Icon_Narrow_Down_16x16.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/lookandfeel/Icon_Narrow_Right_16x16.png b/designer-base/src/main/resources/com/fr/design/images/lookandfeel/Icon_Narrow_Right_16x16.png new file mode 100644 index 000000000..a1ac42cfe Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/lookandfeel/Icon_Narrow_Right_16x16.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/lookandfeel/Information_Icon_Error_32x32.png b/designer-base/src/main/resources/com/fr/design/images/lookandfeel/Information_Icon_Error_32x32.png index 8c8831e6d..b5df7646e 100644 Binary files a/designer-base/src/main/resources/com/fr/design/images/lookandfeel/Information_Icon_Error_32x32.png and b/designer-base/src/main/resources/com/fr/design/images/lookandfeel/Information_Icon_Error_32x32.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/m_file/preview_disable.svg b/designer-base/src/main/resources/com/fr/design/images/m_file/preview_disable.svg deleted file mode 100644 index 2d64f68f7..000000000 --- a/designer-base/src/main/resources/com/fr/design/images/m_file/preview_disable.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - icon_报表web属性_打印预览_normal - - - - - - - - diff --git a/designer-base/src/main/resources/com/fr/design/images/m_file/preview_disabled.svg b/designer-base/src/main/resources/com/fr/design/images/m_file/preview_disabled.svg new file mode 100644 index 000000000..6f2c4afa1 --- /dev/null +++ b/designer-base/src/main/resources/com/fr/design/images/m_file/preview_disabled.svg @@ -0,0 +1,7 @@ + + + icon_预览_disabled + + + + \ No newline at end of file diff --git a/designer-base/src/main/resources/com/fr/design/images/m_file/preview_normal.svg b/designer-base/src/main/resources/com/fr/design/images/m_file/preview_normal.svg index 7b0ea197d..0412b5e10 100644 --- a/designer-base/src/main/resources/com/fr/design/images/m_file/preview_normal.svg +++ b/designer-base/src/main/resources/com/fr/design/images/m_file/preview_normal.svg @@ -4,4 +4,4 @@ - \ No newline at end of file + diff --git a/designer-base/src/main/resources/com/fr/design/images/mainframe/loading.gif b/designer-base/src/main/resources/com/fr/design/images/mainframe/loading.gif new file mode 100644 index 000000000..c77b4fe10 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/mainframe/loading.gif differ diff --git a/designer-base/src/main/resources/com/fr/design/images/mainframe/open_failed.png b/designer-base/src/main/resources/com/fr/design/images/mainframe/open_failed.png new file mode 100644 index 000000000..0d43a117f Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/mainframe/open_failed.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/toast/reuse_icon.png b/designer-base/src/main/resources/com/fr/design/images/toast/reuse_icon.png new file mode 100644 index 000000000..90f59aa1d Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/toast/reuse_icon.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/toast/toast_prompt.png b/designer-base/src/main/resources/com/fr/design/images/toast/toast_prompt.png new file mode 100644 index 000000000..5662a88a4 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/toast/toast_prompt.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/toast/toast_warning.png b/designer-base/src/main/resources/com/fr/design/images/toast/toast_warning.png new file mode 100644 index 000000000..6499c48e0 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/toast/toast_warning.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/waiting.png b/designer-base/src/main/resources/com/fr/design/images/waiting.png new file mode 100644 index 000000000..545f54584 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/waiting.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/warnings/warning32.png b/designer-base/src/main/resources/com/fr/design/images/warnings/warning32.png new file mode 100644 index 000000000..4d2a189b6 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/warnings/warning32.png differ diff --git a/designer-base/src/test/java/com/fr/design/gui/controlpane/ListControlPaneHelperTest.java b/designer-base/src/test/java/com/fr/design/gui/controlpane/ListControlPaneHelperTest.java new file mode 100644 index 000000000..8f113089e --- /dev/null +++ b/designer-base/src/test/java/com/fr/design/gui/controlpane/ListControlPaneHelperTest.java @@ -0,0 +1,41 @@ +package com.fr.design.gui.controlpane; + +import com.fr.form.event.Listener; +import com.fr.general.NameObject; +import org.easymock.EasyMock; +import org.junit.Assert; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * Created by kerry on 5/17/21 + */ +public class ListControlPaneHelperTest { + + @Test + public void testProcessCatalog() { + ListControlPaneHelper helper = ListControlPaneHelper.newInstance(EasyMock.mock(ListControlPaneProvider.class)); + List nameObjectList = new ArrayList<>(); + Listener listener1 = new Listener(); + listener1.setEventName("click"); + Listener listener2 = new Listener(); + listener2.setEventName("afterInit"); + Listener listener3 = new Listener(); + listener3.setEventName("click"); + Listener listener4 = new Listener(); + listener4.setEventName("afterInit"); + listener4.setName("test"); + nameObjectList.add(new NameObject("click", listener1)); + nameObjectList.add(new NameObject("afterInit", listener2)); + nameObjectList.add(new NameObject("click", listener3)); + nameObjectList.add(new NameObject("afterInit", listener4)); + Map> map = helper.processCatalog(nameObjectList); + Assert.assertEquals(2, map.size()); + Assert.assertEquals(2, map.get("afterInit").size()); + Assert.assertEquals(2, map.get("click").size()); + + } +} diff --git a/designer-base/src/test/java/com/fr/design/mainframe/reuse/ComponentReuseNotificationInfoTest.java b/designer-base/src/test/java/com/fr/design/mainframe/reuse/ComponentReuseNotificationInfoTest.java new file mode 100644 index 000000000..c90e7a8b0 --- /dev/null +++ b/designer-base/src/test/java/com/fr/design/mainframe/reuse/ComponentReuseNotificationInfoTest.java @@ -0,0 +1,46 @@ +package com.fr.design.mainframe.reuse; + +import com.fr.stable.xml.XMLPrintWriter; +import com.fr.stable.xml.XMLableReader; +import com.fr.third.javax.xml.stream.XMLStreamException; +import org.junit.Assert; +import org.junit.Test; + +import java.io.PrintWriter; +import java.io.StringReader; +import java.io.StringWriter; + +/** + * Created by kerry on 5/10/21 + */ +public class ComponentReuseNotificationInfoTest { + + @Test + public void testReadXML() { + try { + XMLableReader xmlReader = XMLableReader.createXMLableReader(new StringReader("\n")); + ComponentReuseNotificationInfo notificationInfo = ComponentReuseNotificationInfo.getInstance(); + notificationInfo.readXML(xmlReader); + xmlReader.close(); + Assert.assertEquals(2, notificationInfo.getNotifiedNumber()); + Assert.assertEquals(true, notificationInfo.isClickedWidgetLib()); + Assert.assertEquals(1620612153215L, notificationInfo.getLastNotifyTime()); + } catch (XMLStreamException e) { + Assert.fail(e.getMessage()); + } + } + + @Test + public void testWriteXML() { + StringWriter sw = new StringWriter(); + XMLPrintWriter writer = XMLPrintWriter.create(new PrintWriter(sw)); + ComponentReuseNotificationInfo notificationInfo = ComponentReuseNotificationInfo.getInstance(); + notificationInfo.setNotifiedNumber(1); + notificationInfo.writeXML(writer); + writer.flush(); + writer.close(); + Assert.assertEquals("\n" + + "\n", sw.toString()); + } + +} diff --git a/designer-chart/src/main/java/com/fr/design/chart/series/PlotSeries/MapCustomPane.java b/designer-chart/src/main/java/com/fr/design/chart/series/PlotSeries/MapCustomPane.java index d3c8cc41c..8cd0743da 100644 --- a/designer-chart/src/main/java/com/fr/design/chart/series/PlotSeries/MapCustomPane.java +++ b/designer-chart/src/main/java/com/fr/design/chart/series/PlotSeries/MapCustomPane.java @@ -23,6 +23,9 @@ import org.apache.batik.swing.svg.SVGFileFilter; import javax.swing.JFileChooser; import javax.swing.JPanel; import javax.swing.SwingConstants; +import java.io.File; +import java.util.ArrayList; +import java.util.List; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.FlowLayout; @@ -30,9 +33,6 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; -import java.io.File; -import java.util.ArrayList; -import java.util.List; /** * 自定义地图界面. @@ -117,7 +117,11 @@ refreshAreaNameBox(); int returnVal = svgFileChooser.showOpenDialog(DesignerContext.getDesignerFrame()); if (returnVal != JFileChooser.CANCEL_OPTION) { File selectedFile = svgFileChooser.getSelectedFile(); - lastSelectPath = selectedFile.getAbsolutePath(); + try { + lastSelectPath = selectedFile.getCanonicalPath(); + } catch (Exception ex) { + FineLoggerFactory.getLogger().error(ex.getMessage(), ex); + } if (selectedFile != null && selectedFile.isFile()) { imageShowPane.setSvgMap(selectedFile.getPath()); imageShowPane.repaint(); @@ -133,7 +137,7 @@ refreshAreaNameBox(); String colName = Utils.objectToString(areaString.getSelectedItem()); TableDataWrapper tableDataWrappe = tableDataNameBox.getTableDataWrapper(); - + imageShowPane.refreshFromDataList(getColValuesInData(tableDataWrappe, colName)); } } diff --git a/designer-chart/src/main/java/com/fr/design/chart/series/SeriesCondition/impl/ChartHyperPoplinkPane.java b/designer-chart/src/main/java/com/fr/design/chart/series/SeriesCondition/impl/ChartHyperPoplinkPane.java index 7083da681..ae3867220 100644 --- a/designer-chart/src/main/java/com/fr/design/chart/series/SeriesCondition/impl/ChartHyperPoplinkPane.java +++ b/designer-chart/src/main/java/com/fr/design/chart/series/SeriesCondition/impl/ChartHyperPoplinkPane.java @@ -11,7 +11,6 @@ import com.fr.design.gui.itextfield.UITextField; import com.fr.design.hyperlink.AbstractHyperLinkPane; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.mainframe.chart.ChartHyperEditPane; -import com.fr.design.module.DesignModuleFactory; import com.fr.design.utils.gui.GUICoreUtils; import com.fr.log.FineLoggerFactory; @@ -122,7 +121,6 @@ public class ChartHyperPoplinkPane extends AbstractHyperLinkPane 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); + } + } + + /** + * 感觉ChartCollection加载图表属性界面. + * @param collection 收集图表 + * @param ePane 面板 + */ + public void populateChartPropertyPane(BaseChartCollection collection, TargetComponent ePane) { + if (collection instanceof ChartCollection) { + populateChartPropertyPane((ChartCollection) collection, ePane); + } + } + + /** + * 返回View的标题. + */ + public String getViewTitle() { + return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Cell_Element_Property_Table"); + } + + /** + * 返回View的Icon地址. + */ + public Icon getViewIcon() { + return BaseUtils.readIcon("/com/fr/design/images/m_report/qb.png"); + } + + /** + * 预定义定位 + * @return 定位 + */ + public Location preferredLocation() { + return Location.WEST_BELOW; + } + + /** + * 创建标题Panel + * @return 标题panel + */ + public UITitlePanel createTitlePanel() { + return new UITitlePanel(this); + } + + /** + * 刷新Dockview + */ + public void refreshDockingView() { + // TODO Auto-generated method stub + + } + + /** + * 设置是否支持单元格数据. + */ + public void setSupportCellData(boolean supportCellData) { + if (chartEditPane != null) { + chartEditPane.setSupportCellData(supportCellData); + } + } } \ No newline at end of file diff --git a/designer-chart/src/main/java/com/fr/design/mainframe/MiddleChartPropertyPane.java b/designer-chart/src/main/java/com/fr/design/mainframe/MiddleChartPropertyPane.java deleted file mode 100644 index 39832c377..000000000 --- a/designer-chart/src/main/java/com/fr/design/mainframe/MiddleChartPropertyPane.java +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright(c) 2001-2011, FineReport Inc, All Rights Reserved. - */ -package com.fr.design.mainframe; - -import com.fr.base.BaseUtils; -import com.fr.base.chart.BaseChartCollection; -import com.fr.chart.chartattr.ChartCollection; -import com.fr.chartx.attr.ChartProvider; -import com.fr.design.ChartTypeInterfaceManager; -import com.fr.design.designer.TargetComponent; -import com.fr.design.gui.chart.BaseChartPropertyPane; -import com.fr.design.gui.chart.ChartEditPaneProvider; -import com.fr.design.gui.frpane.UITitlePanel; -import com.fr.design.gui.ilable.UILabel; -import com.fr.design.gui.itabpane.TitleChangeListener; -import com.fr.design.mainframe.chart.ChartEditPane; -import com.fr.stable.StableUtils; - -import javax.swing.BorderFactory; -import javax.swing.Icon; -import javax.swing.JComponent; -import java.awt.BorderLayout; - -public abstract class MiddleChartPropertyPane extends BaseChartPropertyPane{ - - protected TargetComponentContainer container = new TargetComponentContainer(); - protected UILabel nameLabel; - - protected ChartEditPane chartEditPane; - - public MiddleChartPropertyPane() { - initComponenet(); - } - - protected void initComponenet() { - this.setLayout(new BorderLayout()); - this.setBorder(BorderFactory.createEmptyBorder(10,0,0,0)); - - createNameLabel(); - //去掉上方名字,先注释掉 -// this.add(createNorthComponent(), BorderLayout.NORTH); - chartEditPane = StableUtils.construct(ChartEditPane.class); - chartEditPane.setSupportCellData(true); - } - - public void addChartEditPane(String plotID){ - chartEditPane = ChartTypeInterfaceManager.getInstance().getChartEditPane(plotID); - chartEditPane.setSupportCellData(true); - this.createMainPane(); - setSureProperty(); - } - - protected abstract void createNameLabel(); - - protected abstract JComponent createNorthComponent(); - - protected abstract void createMainPane(); - - - @Override - public ChartEditPaneProvider getChartEditPane() { - return chartEditPane; - } - - public void setSureProperty() { - chartEditPane.setContainer(container); - chartEditPane.addTitleChangeListener(titleListener); - String tabname = chartEditPane.getSelectedTabName(); - nameLabel.setText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Property_Table") + (tabname != null ? ('-' + chartEditPane.getSelectedTabName()) : "")); - resetChartEditPane(); - } - - protected void resetChartEditPane() { - remove(chartEditPane); - add(chartEditPane, BorderLayout.CENTER); - validate(); - repaint(); - revalidate(); - } - - protected TitleChangeListener titleListener = new TitleChangeListener() { - - @Override - public void fireTitleChange(String addName) { - nameLabel.setText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Property_Table") + '-' + addName); - } - }; - - /** - * 感觉ChartCollection加载图表属性界面. - * @param collection 收集图表 - * @param ePane 面板 - */ - public void populateChartPropertyPane(ChartCollection collection, TargetComponent ePane) { - addChartEditPane(collection.getSelectedChartProvider(ChartProvider.class).getID()); - setSupportCellData(true); - this.container.setEPane(ePane); - chartEditPane.populate(collection); - } - - /** - * 感觉ChartCollection加载图表属性界面. - * @param collection 收集图表 - * @param ePane 面板 - */ - public void populateChartPropertyPane(BaseChartCollection collection, TargetComponent ePane) { - if (collection instanceof ChartCollection) { - populateChartPropertyPane((ChartCollection)collection, ePane); - } - } - -// public void clear() { -// this.container.setEPane(null); -// chartEditPane.clear(); -// getParent().remove(this); -// } - - /** - * 返回View的标题. - */ - public String getViewTitle() { - return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Cell_Element_Property_Table"); - } - - /** - * 返回View的Icon地址. - */ - public Icon getViewIcon() { - return BaseUtils.readIcon("/com/fr/design/images/m_report/qb.png"); - } - - /** - * 预定义定位 - * @return 定位 - */ - public Location preferredLocation() { - return Location.WEST_BELOW; - } - - /** - * 创建标题Panel - * @return 标题panel - */ - public UITitlePanel createTitlePanel() { - return new UITitlePanel(this); - } - - /** - * 刷新Dockview - */ - public void refreshDockingView() { - // TODO Auto-generated method stub - - } - - /** - * 设置是否支持单元格数据. - */ - public void setSupportCellData(boolean supportCellData) { - if(chartEditPane != null) { - chartEditPane.setSupportCellData(supportCellData); - } - } -} \ No newline at end of file diff --git a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/style/series/ColorPickerPaneWithMaxMin.java b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/style/series/ColorPickerPaneWithMaxMin.java new file mode 100644 index 000000000..c6ac36a0c --- /dev/null +++ b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/style/series/ColorPickerPaneWithMaxMin.java @@ -0,0 +1,121 @@ +package com.fr.design.mainframe.chart.gui.style.series; + +import com.fr.base.BaseFormula; +import com.fr.chart.chartglyph.MapHotAreaColor; +import com.fr.design.formula.TinyFormulaPane; +import com.fr.design.gui.frpane.AbstractAttrNoScrollPane; + +import javax.swing.JComponent; +import javax.swing.JPanel; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import java.awt.Color; + +/** + * @author Bjorn + * @version 10.0 + * Created by Bjorn on 2021-05-18 + */ +public class ColorPickerPaneWithMaxMin extends ColorPickerPaneWithFormula { + + private double MAX = Double.MAX_VALUE / 2; + private double MIN = -(Double.MAX_VALUE / 2); + private BaseFormula[] valueArray; + private JPanel autoPane; + + public ColorPickerPaneWithMaxMin(AbstractAttrNoScrollPane container, String meterString) { + this(container, meterString, null); + } + + public ColorPickerPaneWithMaxMin(AbstractAttrNoScrollPane container, String meterString, JPanel autoPane) { + super(container, meterString); + if (autoPane == null) { + return; + } + this.autoPane = autoPane; + this.getDesignTypeButtonGroup().addChangeListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + checkAutoPane(); + } + }); + } + + private void checkAutoPane() { + if (getDesignTypeButtonGroup().getSelectedIndex() == 0) { + autoPane.setVisible(true); + } else { + autoPane.setVisible(false); + } + } + + public void refreshGroupPane(Color[] colorArray, BaseFormula[] valueArray) { + this.valueArray = valueArray; + super.refreshGroupPane(colorArray, valueArray); + } + + protected void setTextValue4Index(int index, String value) { + TinyFormulaPane tinyFormulaPane = (TinyFormulaPane) textFieldList.get(index); + setTextState(tinyFormulaPane, index, textFieldList.size() - 1, value); + } + + protected JComponent getNewTextFieldComponent(int i, String value) { + TinyFormulaPane textField = new TinyFormulaPaneWithEnable(); + textField.setBounds(0, i * 2 * TEXTFIELD_HEIGHT, TEXTFIELD_WIDTH, TEXTFIELD_HEIGHT); + setTextState(textField, i, valueArray.length - 1, value); + return textField; + } + + protected String getValue4Index(int i) { + if (i == 0) { + return String.valueOf(MAX); + } + if (i == textFieldList.size() - 1) { + return String.valueOf(MIN); + } + return ((TinyFormulaPane) textFieldList.get(i)).getUITextField().getText(); + } + + protected BaseFormula[] getValueArray(int count) { + BaseFormula[] valueArray = new BaseFormula[count + 1]; + valueArray[0] = BaseFormula.createFormulaBuilder().build(MAX); + valueArray[count] = BaseFormula.createFormulaBuilder().build(MIN); + for (int i = 1; i < count; i++) { + if (i >= textFieldList.size() - 1) { + valueArray[i] = BaseFormula.createFormulaBuilder().build((count - i) * VALUE); + } else { + valueArray[i] = BaseFormula.createFormulaBuilder().build(getValue4Index(i)); + } + } + return valueArray; + } + + private void setTextState(TinyFormulaPane tinyFormulaPane, int index, int maxIndex, String value) { + boolean enable = false; + if (index == 0) { + value = "=∞"; + } else if (index == maxIndex) { + value = "=-∞"; + } else { + enable = true; + } + tinyFormulaPane.getUITextField().setText(value); + tinyFormulaPane.setEnabled(enable); + } + + public void populateBean(MapHotAreaColor hotAreaColor) { + super.populateBean(hotAreaColor); + if (autoPane != null) { + checkAutoPane(); + } + } + + public class TinyFormulaPaneWithEnable extends TinyFormulaPane { + @Override + public void setEnabled(boolean enabled) { + super.setEnabled(enabled); + formulaTextField.setEnabled(enabled); + formulaTextFieldButton.setEnabled(enabled); + } + } +} diff --git a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/style/series/UIColorPickerPane.java b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/style/series/UIColorPickerPane.java index 25b876033..fb2d1c31a 100644 --- a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/style/series/UIColorPickerPane.java +++ b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/style/series/UIColorPickerPane.java @@ -13,6 +13,7 @@ import com.fr.design.gui.frpane.UINumberDragPane; import com.fr.design.gui.ibutton.UIButtonGroup; import com.fr.design.gui.ilable.BoldFontTextLabel; import com.fr.design.gui.ipoppane.PopupHider; +import com.fr.design.i18n.Toolkit; import com.fr.design.layout.TableLayout; import com.fr.design.layout.TableLayoutHelper; import com.fr.design.style.color.ColorControlWindow; @@ -53,7 +54,7 @@ public class UIColorPickerPane extends BasicPane implements UIObserver { protected static final int TEXTFIELD_WIDTH = 130; protected static final int UPCONTROLPANE_WIDTH = 230; private static final int LAYOUR_DET = 6; - private static final double VALUE = 100; + public static final double VALUE = 100; protected ArrayList textFieldList; private List colorRecList = new ArrayList(); @@ -171,7 +172,7 @@ public class UIColorPickerPane extends BasicPane implements UIObserver { regionNumPane.updateBean().intValue()), getValueArray(regionNumPane.updateBean().intValue())); } }); - designTypeButtonGroup = new UIButtonGroup(new String[]{com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Mode_Auto"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Mode_Custom")}, new Integer[]{0, 1}); + designTypeButtonGroup = new UIButtonGroup<>(new String[]{Toolkit.i18nText("Fine-Design_Chart_Mode_Auto"), Toolkit.i18nText("Fine-Design_Chart_Mode_Custom")}, new Integer[]{0, 1}); designTypeButtonGroup.setSelectedIndex(0); designTypeButtonGroup.addChangeListener(new ChangeListener() { @Override @@ -201,11 +202,11 @@ public class UIColorPickerPane extends BasicPane implements UIObserver { }; double p = TableLayout.PREFERRED; - double e = getEditAreaWidth (); - double d = TableLayout4VanChartHelper.DESCRIPTION_AREA_WIDTH; + double e = getEditAreaWidth(); + double d = getDescriptionWidth(); double[] columnSize = {d, e}; double[] rowSize = {p}; - Component[][] tmpComp = new Component[][]{new Component[]{new BoldFontTextLabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Value_Divided_Stage")), regionNumPane}}; + Component[][] tmpComp = new Component[][]{new Component[]{new BoldFontTextLabel(Toolkit.i18nText("Fine-Design_Chart_Value_Divided_Stage")), regionNumPane}}; stagePanel = TableLayout4VanChartHelper.createGapTableLayoutPane(tmpComp, rowSize, columnSize); @@ -226,10 +227,14 @@ public class UIColorPickerPane extends BasicPane implements UIObserver { refreshGroupPane(colors, getValueArray(number)); } - protected double getEditAreaWidth () { + protected double getEditAreaWidth() { return TableLayout4VanChartHelper.EDIT_AREA_WIDTH; } + protected double getDescriptionWidth() { + return TableLayout4VanChartHelper.DESCRIPTION_AREA_WIDTH; + } + protected ArrayList getTextFieldList(){ return new ArrayList(); } @@ -272,11 +277,11 @@ public class UIColorPickerPane extends BasicPane implements UIObserver { */ public Dimension getPreferredSize() { if (designTypeButtonGroup.getSelectedIndex() == 0) { - return new Dimension(colorGroup.getPreferredSize().width + textGroup.getPreferredSize().width, upControlPane.getPreferredSize().height + MARGIN_TOP); + return new Dimension(colorGroup.getPreferredSize().width + textGroup.getPreferredSize().width, upControlPane.getPreferredSize().height + getBoundY()); } else { - int extra = stagePanel == null ? 0 : stagePanel.getPreferredSize().height + MARGIN_TOP; + int extra = stagePanel == null ? 0 : stagePanel.getPreferredSize().height + getBoundY(); return new Dimension(colorGroup.getPreferredSize().width + textGroup.getPreferredSize().width, - extra + textGroup.getPreferredSize().height + upControlPane.getPreferredSize().height + OFF_HEIGHT + MARGIN_TOP); + extra + textGroup.getPreferredSize().height + upControlPane.getPreferredSize().height + OFF_HEIGHT + getBoundY()); } } @@ -604,10 +609,10 @@ public class UIColorPickerPane extends BasicPane implements UIObserver { @Override public void layoutContainer(Container parent) { - upControlPane.setBounds(MARGIN_LEFT, MARGIN_TOP, UPCONTROLPANE_WIDTH, upControlPane.getPreferredSize().height + MARGIN_TOP); - stagePanel.setBounds(MARGIN_LEFT, upControlPane.getPreferredSize().height + LAYOUR_DET + MARGIN_TOP, UPCONTROLPANE_WIDTH, stagePanel.getPreferredSize().height); - colorGroup.setBounds( getColorgroupMarginLeft (), 2 * MARGIN_TOP + upControlPane.getPreferredSize().height + stagePanel.getPreferredSize().height + 2 * LAYOUR_DET, colorGroup.getPreferredSize().width, colorGroup.getPreferredSize().height + upControlPane.getPreferredSize().height); - textGroup.setBounds(colorGroup.getPreferredSize().width + getColorgroupMarginLeft (), upControlPane.getPreferredSize().height + stagePanel.getPreferredSize().height + 2 * LAYOUR_DET + MARGIN_TOP, textGroup.getPreferredSize().width, textGroup.getPreferredSize().height); + upControlPane.setBounds(getBoundX(), getBoundY(), UPCONTROLPANE_WIDTH, upControlPane.getPreferredSize().height + MARGIN_TOP); + stagePanel.setBounds(getBoundX(), upControlPane.getPreferredSize().height + LAYOUR_DET + getBoundY(), UPCONTROLPANE_WIDTH, stagePanel.getPreferredSize().height); + colorGroup.setBounds( getColorgroupMarginLeft (), 2 * getBoundY() + upControlPane.getPreferredSize().height + stagePanel.getPreferredSize().height + 2 * LAYOUR_DET, colorGroup.getPreferredSize().width, colorGroup.getPreferredSize().height + upControlPane.getPreferredSize().height); + textGroup.setBounds(colorGroup.getPreferredSize().width + getColorgroupMarginLeft (), upControlPane.getPreferredSize().height + stagePanel.getPreferredSize().height + 2 * LAYOUR_DET + getBoundY(), textGroup.getPreferredSize().width, textGroup.getPreferredSize().height); } @Override @@ -693,7 +698,7 @@ public class UIColorPickerPane extends BasicPane implements UIObserver { refreshPane(); } - private void initContainerLister(){ + protected void initContainerLister(){ this.container.initAllListeners(); } @@ -761,7 +766,7 @@ public class UIColorPickerPane extends BasicPane implements UIObserver { return ChartBaseUtils.createColorsWithHSB(color, sum); } - private BaseFormula[] getValueArray(int count) { + protected BaseFormula[] getValueArray(int count) { BaseFormula[] valueArray = new BaseFormula[count + 1]; for (int i = 0; i < valueArray.length; i++) { if (i >= textFieldList.size()) { diff --git a/designer-chart/src/main/java/com/fr/van/chart/designer/component/VanChartBeautyPane.java b/designer-chart/src/main/java/com/fr/van/chart/designer/component/VanChartBeautyPane.java index 7725d9a0c..0fefa406e 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/designer/component/VanChartBeautyPane.java +++ b/designer-chart/src/main/java/com/fr/van/chart/designer/component/VanChartBeautyPane.java @@ -44,7 +44,7 @@ public class VanChartBeautyPane extends BasicBeanPane { double[] rowSize = {p}; Component[][] components = new Component[][]{ - new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Chart_Gradient_Style")), gradientTypeBox}, + new Component[]{new UILabel(labelName()), gradientTypeBox}, }; return TableLayout4VanChartHelper.createGapTableLayoutPane(components, rowSize, columnSize); @@ -57,6 +57,10 @@ public class VanChartBeautyPane extends BasicBeanPane { }; } + protected String labelName() { + return Toolkit.i18nText("Fine-Design_Chart_Gradient_Style"); + } + public void populateBean(GradientStyle gradientStyle) { gradientTypeBox.setSelectedIndex(this.convertGradientTypeToIndex(gradientStyle.getGradientType())); } diff --git a/designer-chart/src/main/java/com/fr/van/chart/designer/component/format/TargetValueFormatPaneWithCheckBox.java b/designer-chart/src/main/java/com/fr/van/chart/designer/component/format/TargetValueFormatPaneWithCheckBox.java new file mode 100644 index 000000000..469fcb33b --- /dev/null +++ b/designer-chart/src/main/java/com/fr/van/chart/designer/component/format/TargetValueFormatPaneWithCheckBox.java @@ -0,0 +1,22 @@ +package com.fr.van.chart.designer.component.format; + +import com.fr.van.chart.designer.style.VanChartStylePane; + +import javax.swing.JPanel; + +/** + * @author Bjorn + * @version 10.0 + * Created by Bjorn on 2021-04-06 + */ +public class TargetValueFormatPaneWithCheckBox extends VanChartFormatPaneWithCheckBox { + + public TargetValueFormatPaneWithCheckBox(VanChartStylePane parent, JPanel showOnPane) { + super(parent, showOnPane); + } + + @Override + protected String getCheckBoxText() { + return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Target_Value"); + } +} diff --git a/designer-chart/src/main/java/com/fr/van/chart/designer/component/format/VanChartFormatPaneWithCheckBox.java b/designer-chart/src/main/java/com/fr/van/chart/designer/component/format/VanChartFormatPaneWithCheckBox.java index 6f5fc270a..38ae4a08c 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/designer/component/format/VanChartFormatPaneWithCheckBox.java +++ b/designer-chart/src/main/java/com/fr/van/chart/designer/component/format/VanChartFormatPaneWithCheckBox.java @@ -12,13 +12,12 @@ import com.fr.plugin.chart.base.format.AttrTooltipFormat; import com.fr.stable.Constants; import javax.swing.JPanel; +import java.text.Format; +import java.util.Map; import java.awt.BorderLayout; import java.awt.Point; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; -import java.text.Format; -import java.util.Map; /** * Created by Mitisky on 16/2/23. @@ -54,32 +53,7 @@ public abstract class VanChartFormatPaneWithCheckBox extends JPanel{ this.add(formatButton, BorderLayout.EAST); initFormatListener(); - isSelectedBox.addMouseListener(new MouseListener() { - @Override - public void mouseClicked(MouseEvent e) { - isDirty = true; - } - - @Override - public void mousePressed(MouseEvent e) { - - } - - @Override - public void mouseReleased(MouseEvent e) { - - } - - @Override - public void mouseEntered(MouseEvent e) { - - } - - @Override - public void mouseExited(MouseEvent e) { - - } - }); + isSelectedBox.addChangeListener((e)-> isDirty = true); } protected abstract String getCheckBoxText(); diff --git a/designer-chart/src/main/java/com/fr/van/chart/designer/component/label/LabelContentPaneWithCateValue.java b/designer-chart/src/main/java/com/fr/van/chart/designer/component/label/LabelContentPaneWithCateValue.java index 4b8f8013d..21fc0c0bf 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/designer/component/label/LabelContentPaneWithCateValue.java +++ b/designer-chart/src/main/java/com/fr/van/chart/designer/component/label/LabelContentPaneWithCateValue.java @@ -1,6 +1,11 @@ package com.fr.van.chart.designer.component.label; +import com.fr.design.i18n.Toolkit; +import com.fr.plugin.chart.base.AttrTooltipContent; +import com.fr.plugin.chart.gauge.attr.GaugeValueTooltipContent; import com.fr.van.chart.designer.TableLayout4VanChartHelper; +import com.fr.van.chart.designer.component.format.TargetValueFormatPaneWithCheckBox; +import com.fr.van.chart.designer.component.format.ValueFormatPaneWithCheckBox; import com.fr.van.chart.designer.style.VanChartStylePane; import javax.swing.JPanel; @@ -11,9 +16,11 @@ import java.awt.Component; */ public class LabelContentPaneWithCateValue extends GaugeLabelContentPane { + private TargetValueFormatPaneWithCheckBox targetValueFormatPane; + private static final long serialVersionUID = -8286902939543416431L; - public LabelContentPaneWithCateValue(VanChartStylePane parent, JPanel showOnPane){ + public LabelContentPaneWithCateValue(VanChartStylePane parent, JPanel showOnPane) { super(parent, showOnPane); } @@ -21,14 +28,59 @@ public class LabelContentPaneWithCateValue extends GaugeLabelContentPane { return TableLayout4VanChartHelper.createTableLayoutPaneWithSmallTitle(title, panel); } - protected double[] getRowSize(double p){ - return new double[]{p,p}; + @Override + protected void initFormatPane(VanChartStylePane parent, JPanel showOnPane) { + super.initFormatPane(parent, showOnPane); + setValueFormatPane(new ValueFormatPaneWithCheckBox(parent, showOnPane) { + @Override + protected String getCheckBoxText() { + return Toolkit.i18nText("Fine-Design_Chart_Value_Pointer"); + } + }); + this.targetValueFormatPane = new TargetValueFormatPaneWithCheckBox(parent, showOnPane); + } + + protected double[] getRowSize(double p) { + return new double[]{p, p, p}; } - protected Component[][] getPaneComponents(){ + protected Component[][] getPaneComponents() { return new Component[][]{ - new Component[]{getCategoryNameFormatPane(),null}, - new Component[]{getValueFormatPane(),null}, + new Component[]{getCategoryNameFormatPane(), null}, + new Component[]{getValueFormatPane(), null}, + new Component[]{targetValueFormatPane, null}, }; } + + @Override + protected void populateFormatPane(AttrTooltipContent attrTooltipContent) { + super.populateFormatPane(attrTooltipContent); + if (attrTooltipContent instanceof GaugeValueTooltipContent) { + GaugeValueTooltipContent gaugeValueTooltipContent = (GaugeValueTooltipContent) attrTooltipContent; + targetValueFormatPane.populate(gaugeValueTooltipContent.getTargetValueFormat()); + } + } + + @Override + protected void updateFormatPane(AttrTooltipContent attrTooltipContent) { + super.updateFormatPane(attrTooltipContent); + GaugeValueTooltipContent gaugeValueTooltipContent = (GaugeValueTooltipContent) attrTooltipContent; + targetValueFormatPane.update(gaugeValueTooltipContent.getTargetValueFormat()); + } + + @Override + public void setDirty(boolean isDirty) { + super.setDirty(isDirty); + targetValueFormatPane.setDirty(isDirty); + } + + + @Override + public boolean isDirty() { + return super.isDirty() || targetValueFormatPane.isDirty(); + } + + protected AttrTooltipContent createAttrTooltip() { + return new GaugeValueTooltipContent(); + } } \ No newline at end of file diff --git a/designer-chart/src/main/java/com/fr/van/chart/designer/component/tooltip/RefreshTooltipContentPaneWithOutSeries.java b/designer-chart/src/main/java/com/fr/van/chart/designer/component/tooltip/RefreshTooltipContentPaneWithOutSeries.java index 48d2e55cb..8512f6cab 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/designer/component/tooltip/RefreshTooltipContentPaneWithOutSeries.java +++ b/designer-chart/src/main/java/com/fr/van/chart/designer/component/tooltip/RefreshTooltipContentPaneWithOutSeries.java @@ -1,9 +1,7 @@ package com.fr.van.chart.designer.component.tooltip; import com.fr.van.chart.designer.component.format.ChangedPercentFormatPaneWithCheckBox; -import com.fr.van.chart.designer.component.format.ChangedPercentFormatPaneWithoutCheckBox; import com.fr.van.chart.designer.component.format.ChangedValueFormatPaneWithCheckBox; -import com.fr.van.chart.designer.component.format.ChangedValueFormatPaneWithoutCheckBox; import com.fr.van.chart.designer.style.VanChartStylePane; import javax.swing.JPanel; @@ -25,21 +23,27 @@ public class RefreshTooltipContentPaneWithOutSeries extends TooltipContentPaneWi protected void initFormatPane(VanChartStylePane parent, JPanel showOnPane) { super.initFormatPane(parent, showOnPane); - setChangedValueFormatPane(new ChangedValueFormatPaneWithCheckBox(parent, showOnPane)); + setChangedValueFormatPane(new ChangedValueFormatPaneWithCheckBox(parent, showOnPane) { + @Override + protected String getCheckBoxText() { + return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Pointer_Change_Value"); + } + }); setChangedPercentFormatPane(new ChangedPercentFormatPaneWithCheckBox(parent, showOnPane)); } - protected double[] getRowSize(double p){ - return new double[]{p,p,p,p,p}; + protected double[] getRowSize(double p) { + return new double[]{p, p, p, p, p, p}; } - protected Component[][] getPaneComponents(){ + protected Component[][] getPaneComponents() { return new Component[][]{ - new Component[]{getCategoryNameFormatPane(),null}, - new Component[]{getValueFormatPane(),null}, - new Component[]{getChangedValueFormatPane(),null}, - new Component[]{getPercentFormatPane(),null}, - new Component[]{getChangedPercentFormatPane(),null}, + new Component[]{getCategoryNameFormatPane(), null}, + new Component[]{getValueFormatPane(), null}, + new Component[]{getTargetValueFormatPane(), null}, + new Component[]{getChangedValueFormatPane(), null}, + new Component[]{getPercentFormatPane(), null}, + new Component[]{getChangedPercentFormatPane(), null}, }; } } diff --git a/designer-chart/src/main/java/com/fr/van/chart/designer/component/tooltip/TooltipContentPaneWithOutSeries.java b/designer-chart/src/main/java/com/fr/van/chart/designer/component/tooltip/TooltipContentPaneWithOutSeries.java index ab2f0a179..9c7ea0eb7 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/designer/component/tooltip/TooltipContentPaneWithOutSeries.java +++ b/designer-chart/src/main/java/com/fr/van/chart/designer/component/tooltip/TooltipContentPaneWithOutSeries.java @@ -6,8 +6,12 @@ import com.fr.plugin.chart.base.AttrTooltipContent; import com.fr.plugin.chart.base.format.AttrTooltipCategoryFormat; import com.fr.plugin.chart.base.format.AttrTooltipFormat; import com.fr.plugin.chart.base.format.AttrTooltipPercentFormat; +import com.fr.plugin.chart.base.format.AttrTooltipTargetValueFormat; import com.fr.plugin.chart.base.format.AttrTooltipValueFormat; +import com.fr.plugin.chart.gauge.attr.GaugeValueTooltipContent; import com.fr.van.chart.designer.component.VanChartTooltipContentPane; +import com.fr.van.chart.designer.component.format.TargetValueFormatPaneWithCheckBox; +import com.fr.van.chart.designer.component.format.ValueFormatPaneWithCheckBox; import com.fr.van.chart.designer.component.richText.VanChartFieldAttrPane; import com.fr.van.chart.designer.component.richText.VanChartFieldListPane; import com.fr.van.chart.designer.component.richText.VanChartRichEditorModel; @@ -24,19 +28,38 @@ public class TooltipContentPaneWithOutSeries extends VanChartTooltipContentPane private static final long serialVersionUID = -1973565663365672717L; - public TooltipContentPaneWithOutSeries(VanChartStylePane parent, JPanel showOnPane){ + private TargetValueFormatPaneWithCheckBox targetValueFormatPane; + + public TooltipContentPaneWithOutSeries(VanChartStylePane parent, JPanel showOnPane) { super(parent, showOnPane); } - protected double[] getRowSize(double p){ - return new double[]{p,p,p}; + public TargetValueFormatPaneWithCheckBox getTargetValueFormatPane() { + return targetValueFormatPane; + } + + @Override + protected void initFormatPane(VanChartStylePane parent, JPanel showOnPane) { + super.initFormatPane(parent, showOnPane); + setValueFormatPane(new ValueFormatPaneWithCheckBox(parent, showOnPane) { + @Override + protected String getCheckBoxText() { + return Toolkit.i18nText("Fine-Design_Chart_Value_Pointer"); + } + }); + this.targetValueFormatPane = new TargetValueFormatPaneWithCheckBox(parent, showOnPane); + } + + protected double[] getRowSize(double p) { + return new double[]{p, p, p, p}; } - protected Component[][] getPaneComponents(){ + protected Component[][] getPaneComponents() { return new Component[][]{ - new Component[]{getCategoryNameFormatPane(),null}, - new Component[]{getValueFormatPane(),null}, - new Component[]{getPercentFormatPane(),null}, + new Component[]{getCategoryNameFormatPane(), null}, + new Component[]{getValueFormatPane(), null}, + new Component[]{targetValueFormatPane, null}, + new Component[]{getPercentFormatPane(), null} }; } @@ -57,7 +80,8 @@ public class TooltipContentPaneWithOutSeries extends VanChartTooltipContentPane protected String[] getRichTextFieldNames() { return new String[]{ Toolkit.i18nText("Fine-Design_Chart_Category_Use_Name"), - Toolkit.i18nText("Fine-Design_Chart_Use_Value"), + Toolkit.i18nText("Fine-Design_Chart_Value_Pointer"), + Toolkit.i18nText("Fine-Design_Chart_Target_Value"), Toolkit.i18nText("Fine-Design_Chart_Use_Percent") }; } @@ -66,7 +90,53 @@ public class TooltipContentPaneWithOutSeries extends VanChartTooltipContentPane return new AttrTooltipFormat[]{ new AttrTooltipCategoryFormat(), new AttrTooltipValueFormat(), + new AttrTooltipTargetValueFormat(), new AttrTooltipPercentFormat() }; } + + @Override + protected void populateFormatPane(AttrTooltipContent attrTooltipContent) { + super.populateFormatPane(attrTooltipContent); + if (attrTooltipContent instanceof GaugeValueTooltipContent) { + GaugeValueTooltipContent gaugeValueTooltipContent = (GaugeValueTooltipContent) attrTooltipContent; + targetValueFormatPane.populate(gaugeValueTooltipContent.getTargetValueFormat()); + } + } + + @Override + protected void updateFormatPane(AttrTooltipContent attrTooltipContent) { + super.updateFormatPane(attrTooltipContent); + GaugeValueTooltipContent gaugeValueTooltipContent = (GaugeValueTooltipContent) attrTooltipContent; + targetValueFormatPane.update(gaugeValueTooltipContent.getTargetValueFormat()); + } + + protected void updateTooltipFormat(AttrTooltipContent target, AttrTooltipContent source) { + super.updateTooltipFormat(target, source); + + if (target instanceof GaugeValueTooltipContent && source instanceof GaugeValueTooltipContent) { + GaugeValueTooltipContent targetGauge = (GaugeValueTooltipContent) target; + GaugeValueTooltipContent sourceGauge = (GaugeValueTooltipContent) source; + targetGauge.setRichTextTargetValueFormat(sourceGauge.getRichTextTargetValueFormat()); + } + } + + @Override + public void setDirty(boolean isDirty) { + super.setDirty(isDirty); + targetValueFormatPane.setDirty(isDirty); + } + + @Override + public boolean isDirty() { + return super.isDirty() || targetValueFormatPane.isDirty(); + } + + protected AttrTooltipContent createAttrTooltip() { + GaugeValueTooltipContent gaugeValueTooltipContent = new GaugeValueTooltipContent(); + gaugeValueTooltipContent.setCustom(false); + gaugeValueTooltipContent.getTargetValueFormat().setEnable(true); + gaugeValueTooltipContent.getRichTextTargetValueFormat().setEnable(true); + return gaugeValueTooltipContent; + } } \ No newline at end of file diff --git a/designer-chart/src/main/java/com/fr/van/chart/designer/component/tooltip/VanChartFieldListPaneWithOutSeries.java b/designer-chart/src/main/java/com/fr/van/chart/designer/component/tooltip/VanChartFieldListPaneWithOutSeries.java index c651dbf89..7e67886ac 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/designer/component/tooltip/VanChartFieldListPaneWithOutSeries.java +++ b/designer-chart/src/main/java/com/fr/van/chart/designer/component/tooltip/VanChartFieldListPaneWithOutSeries.java @@ -1,9 +1,15 @@ package com.fr.van.chart.designer.component.tooltip; +import com.fr.design.i18n.Toolkit; import com.fr.design.ui.ModernUIPane; +import com.fr.plugin.chart.base.AttrTooltipContent; +import com.fr.plugin.chart.base.format.AttrTooltipTargetValueFormat; +import com.fr.plugin.chart.base.format.AttrTooltipValueFormat; +import com.fr.plugin.chart.gauge.attr.GaugeValueTooltipContent; import com.fr.van.chart.designer.component.richText.VanChartFieldAttrPane; import com.fr.van.chart.designer.component.richText.VanChartFieldButton; import com.fr.van.chart.designer.component.richText.VanChartFieldListPane; +import com.fr.van.chart.designer.component.richText.VanChartFieldListener; import com.fr.van.chart.designer.component.richText.VanChartRichEditorModel; import javax.swing.JPanel; @@ -12,13 +18,26 @@ import java.util.List; public class VanChartFieldListPaneWithOutSeries extends VanChartFieldListPane { + private VanChartFieldButton targetValueButton; + public VanChartFieldListPaneWithOutSeries(VanChartFieldAttrPane fieldAttrPane, ModernUIPane richEditorPane) { super(fieldAttrPane, richEditorPane); } + protected void initDefaultFieldButton() { + super.initDefaultFieldButton(); + + VanChartFieldListener listener = getFieldListener(); + setValueButton(new VanChartFieldButton(Toolkit.i18nText("Fine-Design_Chart_Value_Pointer"), + new AttrTooltipValueFormat(), false, listener)); + targetValueButton = new VanChartFieldButton(Toolkit.i18nText("Fine-Design_Chart_Target_Value"), + new AttrTooltipTargetValueFormat(), false, listener); + } + protected void addDefaultFieldButton(JPanel fieldPane) { fieldPane.add(getCategoryNameButton()); fieldPane.add(getValueButton()); + fieldPane.add(targetValueButton); fieldPane.add(getPercentButton()); } @@ -27,8 +46,24 @@ public class VanChartFieldListPaneWithOutSeries extends VanChartFieldListPane { fieldButtonList.add(getCategoryNameButton()); fieldButtonList.add(getValueButton()); + fieldButtonList.add(targetValueButton); fieldButtonList.add(getPercentButton()); return fieldButtonList; } + + public void populateDefaultField(AttrTooltipContent tooltipContent) { + super.populateDefaultField(tooltipContent); + + if (tooltipContent instanceof GaugeValueTooltipContent) { + GaugeValueTooltipContent gaugeValueTooltipContent = (GaugeValueTooltipContent) tooltipContent; + populateButtonFormat(targetValueButton, gaugeValueTooltipContent.getRichTextTargetValueFormat()); + } + } + + public void updateDefaultField(AttrTooltipContent tooltipContent) { + super.updateDefaultField(tooltipContent); + GaugeValueTooltipContent gaugeValueTooltipContent = (GaugeValueTooltipContent) tooltipContent; + updateButtonFormat(targetValueButton, gaugeValueTooltipContent.getRichTextTargetValueFormat()); + } } diff --git a/designer-chart/src/main/java/com/fr/van/chart/designer/style/label/VanChartGaugeLabelDetailPane.java b/designer-chart/src/main/java/com/fr/van/chart/designer/style/label/VanChartGaugeLabelDetailPane.java index 86d140f1d..8c672bab6 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/designer/style/label/VanChartGaugeLabelDetailPane.java +++ b/designer-chart/src/main/java/com/fr/van/chart/designer/style/label/VanChartGaugeLabelDetailPane.java @@ -10,7 +10,6 @@ import com.fr.design.layout.TableLayout; import com.fr.design.layout.TableLayoutHelper; import com.fr.design.mainframe.chart.gui.style.ChartTextAttrPane; import com.fr.design.mainframe.chart.gui.style.ChartTextAttrPaneWithAuto; -import com.fr.general.ComparatorUtils; import com.fr.plugin.chart.base.AttrLabelDetail; import com.fr.plugin.chart.gauge.VanChartGaugePlot; import com.fr.plugin.chart.type.FontAutoType; @@ -50,7 +49,7 @@ public class VanChartGaugeLabelDetailPane extends VanChartPlotLabelDetailPane { } public GaugeStyle getGaugeStyle() { - return ((VanChartGaugePlot)this.getPlot()).getGaugeStyle(); + return ((VanChartGaugePlot) this.getPlot()).getGaugeStyle(); } public void setGaugeStyle(GaugeStyle gaugeStyle) { @@ -127,15 +126,13 @@ public class VanChartGaugeLabelDetailPane extends VanChartPlotLabelDetailPane { protected Component[][] getLabelPaneComponents(Plot plot, double p, double[] columnSize) { if (hasLabelAlignPane()) { - return new Component[][]{ new Component[]{getDataLabelContentPane(), null}, - new Component[]{createLabelPositionPane(Toolkit.i18nText("Fine-Design_Chart_Layout_Vertical"), plot), null}, - new Component[]{createLabelAlignPane(Toolkit.i18nText("Fine-Design_Chart_Layout_Horizontal")), null}, + new Component[]{createLabelPositionPane(getVerticalTitle(), plot), null}, + new Component[]{createLabelAlignPane(), null}, new Component[]{createLabelStylePane(getLabelStyleRowSize(p), columnSize, plot), null}, }; } else { - return new Component[][]{ new Component[]{getDataLabelContentPane(), null}, new Component[]{createLabelStylePane(getLabelStyleRowSize(p), columnSize, plot), null}, @@ -143,50 +140,37 @@ public class VanChartGaugeLabelDetailPane extends VanChartPlotLabelDetailPane { } } - private JPanel createLabelAlignPane(String title) { - JPanel panel = new JPanel(new BorderLayout()); - - alignPane = new JPanel(); - checkAlignPane(title); - panel.add(alignPane, BorderLayout.CENTER); - - return panel; + private JPanel createLabelAlignPane() { + alignPane = new JPanel(new BorderLayout()); + checkAlignPane(); + return alignPane; } - protected void checkAlignPane(String title) { - if (alignPane == null && !hasLabelAlign(getPlot())) { + protected void checkAlignPane() { + if (!hasLabelAlignPane()) { return; } - if (alignPane != null && !hasLabelAlign(getPlot())) { - oldAlignValues = null; + if (!hasLabelAlign()) { alignPane.removeAll(); return; } - if (alignPane == null && hasLabelAlign(getPlot())) { - alignPane = new JPanel(); + + if (alignPane.getComponents().length > 0) { + return; } TwoTuple result = getAlignNamesAndValues(); - String[] names = result.getFirst(); Integer[] values = result.getSecond(); - if (ComparatorUtils.equals(values, oldAlignValues)) { - return; - } - - oldAlignValues = values; - - align = new UIButtonGroup(names, values); + align = new UIButtonGroup<>(names, values); Component[][] comps = new Component[2][2]; comps[0] = new Component[]{null, null}; - comps[1] = new Component[]{new UILabel(title, SwingConstants.LEFT), align}; + comps[1] = new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Chart_Layout_Horizontal"), SwingConstants.LEFT), align}; double[] row = new double[]{TableLayout.PREFERRED, TableLayout.PREFERRED, TableLayout.PREFERRED}; double[] col = new double[]{TableLayout.FILL, TableLayout4VanChartHelper.EDIT_AREA_WIDTH}; - alignPane.removeAll(); - alignPane.setLayout(new BorderLayout()); alignPane.add(getLabelPositionPane(comps, row, col), BorderLayout.CENTER); if (getParentPane() != null) { @@ -214,12 +198,16 @@ public class VanChartGaugeLabelDetailPane extends VanChartPlotLabelDetailPane { } protected void checkPane() { - String verticalTitle = hasLabelAlign(getPlot()) - ? Toolkit.i18nText("Fine-Design_Chart_Layout_Vertical") - : Toolkit.i18nText("Fine-Design_Chart_Layout_Position"); + String verticalTitle = getVerticalTitle(); checkPositionPane(verticalTitle); - checkAlignPane(Toolkit.i18nText("Fine-Design_Chart_Layout_Horizontal")); + checkAlignPane(); + } + + private String getVerticalTitle() { + return hasLabelAlign() + ? Toolkit.i18nText("Fine-Design_Chart_Layout_Vertical") + : Toolkit.i18nText("Fine-Design_Chart_Layout_Position"); } protected void checkStyleUse() { @@ -227,8 +215,8 @@ public class VanChartGaugeLabelDetailPane extends VanChartPlotLabelDetailPane { textFontPane.setPreferredSize(new Dimension(0, TEXT_FONT_PANE_HEIGHT)); } - protected boolean hasLabelAlign(Plot plot) { - return getGaugeStyle() == GaugeStyle.THERMOMETER && !((VanChartGaugePlot) plot).getGaugeDetailStyle().isHorizontalLayout(); + protected boolean hasLabelAlign() { + return getGaugeStyle() == GaugeStyle.THERMOMETER && !((VanChartGaugePlot) getPlot()).getGaugeDetailStyle().isHorizontalLayout(); } protected boolean hasLabelAlignPane() { @@ -240,7 +228,7 @@ public class VanChartGaugeLabelDetailPane extends VanChartPlotLabelDetailPane { style.setSelectedIndex(1); textFontPane.populate(detail.getTextAttr()); - if (hasLabelAlign(this.getPlot()) && align != null) { + if (hasLabelAlign() && align != null) { align.setSelectedItem(detail.getAlign()); } diff --git a/designer-chart/src/main/java/com/fr/van/chart/designer/style/series/VanChartAbstractPlotSeriesPane.java b/designer-chart/src/main/java/com/fr/van/chart/designer/style/series/VanChartAbstractPlotSeriesPane.java index 5188912bf..849507e05 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/designer/style/series/VanChartAbstractPlotSeriesPane.java +++ b/designer-chart/src/main/java/com/fr/van/chart/designer/style/series/VanChartAbstractPlotSeriesPane.java @@ -147,7 +147,7 @@ public abstract class VanChartAbstractPlotSeriesPane extends AbstractPlotSeriesP } } - private void checkFillStylePane(GradientStyle gradientStyle) { + protected void checkFillStylePane(GradientStyle gradientStyle) { if (vanChartFillStylePane != null) { vanChartFillStylePane.setVisible(gradientStyle.getGradientType() != GradientType.CUSTOM); } diff --git a/designer-chart/src/main/java/com/fr/van/chart/designer/style/series/VanChartColorValueSeriesPane.java b/designer-chart/src/main/java/com/fr/van/chart/designer/style/series/VanChartColorValueSeriesPane.java index 34f86d020..78bc20667 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/designer/style/series/VanChartColorValueSeriesPane.java +++ b/designer-chart/src/main/java/com/fr/van/chart/designer/style/series/VanChartColorValueSeriesPane.java @@ -2,42 +2,27 @@ package com.fr.van.chart.designer.style.series; import com.fr.chart.chartattr.Plot; import com.fr.design.gui.ibutton.UIButtonGroup; -import com.fr.design.gui.ilable.UILabel; import com.fr.design.i18n.Toolkit; -import com.fr.design.layout.TableLayout; -import com.fr.design.layout.TableLayoutHelper; import com.fr.design.mainframe.chart.gui.ChartStylePane; -import com.fr.design.widget.FRWidgetFactory; import com.fr.plugin.chart.range.VanChartRangeLegend; import com.fr.plugin.chart.type.LegendType; -import com.fr.van.chart.designer.TableLayout4VanChartHelper; import com.fr.van.chart.designer.component.VanChartBeautyPane; import com.fr.van.chart.designer.component.VanChartValueColorPane; import com.fr.van.chart.designer.style.VanChartStylePane; -import javax.swing.BorderFactory; import javax.swing.JPanel; -import java.awt.BorderLayout; import java.awt.CardLayout; -import java.awt.Component; import java.awt.Dimension; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; /** * @author Bjorn * @version 10.0 * Created by Bjorn on 2020-08-03 */ -public abstract class VanChartColorValueSeriesPane extends VanChartAbstractPlotSeriesPane { - - //颜色划分切换 - private UIButtonGroup colorDivideButton; +public abstract class VanChartColorValueSeriesPane extends VanChartMultiColorSeriesPane { private VanChartValueColorPane vanChartValueColorPane; - private JPanel colorDividePane; - public VanChartColorValueSeriesPane(ChartStylePane parent, Plot plot) { super(parent, plot); } @@ -51,79 +36,36 @@ public abstract class VanChartColorValueSeriesPane extends VanChartAbstractPlotS this.vanChartValueColorPane = vanChartValueColorPane; } - //获取颜色面板 - protected JPanel getColorPane() { - JPanel panel = new JPanel(new BorderLayout()); - JPanel colorChoosePane = createColorChoosePane(); - if (colorChoosePane != null) { - panel.add(colorChoosePane, BorderLayout.CENTER); - } - - stylePane = createStylePane(); - setColorPaneContent(panel); - JPanel colorPane = TableLayout4VanChartHelper.createExpandablePaneWithTitle(Toolkit.i18nText("Fine-Design_Chart_Color"), panel); - panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 0)); - return panel.getComponentCount() == 0 ? null : colorPane; - } - protected JPanel createColorChoosePane() { vanChartFillStylePane = getVanChartFillStylePane(); if (vanChartFillStylePane != null) { - JPanel divideButtonPane = initDivideButtonPane(); - vanChartValueColorPane = new VanChartValueColorPane((VanChartStylePane) parentPane); - - colorDividePane = new JPanel(new CardLayout()) { - @Override - public Dimension getPreferredSize() { - if (colorDivideButton.getSelectedIndex() == 0) { - return vanChartFillStylePane.getPreferredSize(); - } else { - return vanChartValueColorPane.getPreferredSize(); - } - } - }; - colorDividePane.add(vanChartFillStylePane, "series"); - colorDividePane.add(vanChartValueColorPane, "value"); - - double p = TableLayout.PREFERRED; - double f = TableLayout.FILL; - double[] col = {f}; - double[] row = {p, p, p}; - Component[][] components = new Component[][]{ - new Component[]{divideButtonPane}, - new Component[]{colorDividePane} - }; - return TableLayoutHelper.createCommonTableLayoutPane(components, row, col, 0); + return super.createColorChoosePane(); } return null; } - private JPanel initDivideButtonPane() { - colorDivideButton = new UIButtonGroup<>(new String[]{ + protected UIButtonGroup createDivideButton() { + return new UIButtonGroup<>(new String[]{ Toolkit.i18nText("Fine-Design_Chart_Series"), Toolkit.i18nText("Fine-Design_Chart_Use_Value") }, new String[]{"series", "value"}); - colorDivideButton.addActionListener(new ActionListener() { + } + + protected JPanel createColorDividePane() { + vanChartValueColorPane = new VanChartValueColorPane((VanChartStylePane) parentPane); + JPanel colorDividePane = new JPanel(new CardLayout()) { @Override - public void actionPerformed(ActionEvent e) { - checkCardPane(); + public Dimension getPreferredSize() { + if (getColorDivideButton().getSelectedIndex() == 0) { + return vanChartFillStylePane.getPreferredSize(); + } else { + return vanChartValueColorPane.getPreferredSize(); + } } - }); - colorDivideButton.setSelectedIndex(0); - UILabel label = FRWidgetFactory.createLineWrapLabel(Toolkit.i18nText("Fine-Design_Chart_Color_Divide")); - Component[][] labelComponent = new Component[][]{ - new Component[]{label, colorDivideButton}, }; - JPanel gapTableLayoutPane = TableLayout4VanChartHelper.createGapTableLayoutPane(labelComponent); - gapTableLayoutPane.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0)); - return gapTableLayoutPane; - } - - private void checkCardPane() { - CardLayout cardLayout = (CardLayout) colorDividePane.getLayout(); - cardLayout.show(colorDividePane, colorDivideButton.getSelectedItem()); - colorDividePane.validate(); - colorDividePane.repaint(); + colorDividePane.add(vanChartFillStylePane, "series"); + colorDividePane.add(vanChartValueColorPane, "value"); + return colorDividePane; } //风格 @@ -139,9 +81,9 @@ public abstract class VanChartColorValueSeriesPane extends VanChartAbstractPlotS return; } super.updateBean(plot); - if (colorDivideButton != null) { + if (getColorDivideButton() != null) { VanChartRangeLegend legend = (VanChartRangeLegend) plot.getLegend(); - int selectedIndex = colorDivideButton.getSelectedIndex(); + int selectedIndex = getColorDivideButton().getSelectedIndex(); if (selectedIndex == 0) { legend.setLegendType(LegendType.ORDINARY); } else { @@ -158,13 +100,13 @@ public abstract class VanChartColorValueSeriesPane extends VanChartAbstractPlotS return; } super.populateBean(plot); - if (colorDivideButton != null) { + if (getColorDivideButton() != null) { VanChartRangeLegend legend = (VanChartRangeLegend) plot.getLegend(); LegendType legendType = legend.getLegendType(); if (legendType == LegendType.ORDINARY) { - colorDivideButton.setSelectedIndex(0); + getColorDivideButton().setSelectedIndex(0); } else { - colorDivideButton.setSelectedIndex(1); + getColorDivideButton().setSelectedIndex(1); } vanChartValueColorPane.populateBean(legend); checkCardPane(); diff --git a/designer-chart/src/main/java/com/fr/van/chart/designer/style/series/VanChartMultiColorSeriesPane.java b/designer-chart/src/main/java/com/fr/van/chart/designer/style/series/VanChartMultiColorSeriesPane.java new file mode 100644 index 000000000..ec87d3675 --- /dev/null +++ b/designer-chart/src/main/java/com/fr/van/chart/designer/style/series/VanChartMultiColorSeriesPane.java @@ -0,0 +1,92 @@ +package com.fr.van.chart.designer.style.series; + +import com.fr.chart.chartattr.Plot; +import com.fr.design.gui.ibutton.UIButtonGroup; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.TableLayout; +import com.fr.design.layout.TableLayoutHelper; +import com.fr.design.mainframe.chart.gui.ChartStylePane; +import com.fr.design.widget.FRWidgetFactory; +import com.fr.van.chart.designer.TableLayout4VanChartHelper; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import java.awt.BorderLayout; +import java.awt.CardLayout; +import java.awt.Component; + +/** + * @author Bjorn + * @version 10.0 + * Created by Bjorn on 2021-05-19 + */ +public abstract class VanChartMultiColorSeriesPane extends VanChartAbstractPlotSeriesPane { + + //颜色划分切换 + private UIButtonGroup colorDivideButton; + + private JPanel colorDividePane; + + public VanChartMultiColorSeriesPane(ChartStylePane parent, Plot plot) { + super(parent, plot); + } + + public UIButtonGroup getColorDivideButton() { + return colorDivideButton; + } + + //获取颜色面板 + protected JPanel getColorPane() { + JPanel panel = new JPanel(new BorderLayout()); + JPanel colorChoosePane = createColorChoosePane(); + if (colorChoosePane != null) { + panel.add(colorChoosePane, BorderLayout.CENTER); + } + + stylePane = createStylePane(); + setColorPaneContent(panel); + JPanel colorPane = TableLayout4VanChartHelper.createExpandablePaneWithTitle(Toolkit.i18nText("Fine-Design_Chart_Color"), panel); + panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 0)); + return panel.getComponentCount() == 0 ? null : colorPane; + } + + protected JPanel createColorChoosePane() { + JPanel divideButtonPane = initDivideButtonPane(); + colorDividePane = createColorDividePane(); + + double p = TableLayout.PREFERRED; + double f = TableLayout.FILL; + double[] col = {f}; + double[] row = {p, p, p, p}; + Component[][] components = new Component[][]{ + new Component[]{divideButtonPane}, + new Component[]{colorDividePane} + }; + return TableLayoutHelper.createCommonTableLayoutPane(components, row, col, 0); + } + + private JPanel initDivideButtonPane() { + colorDivideButton = createDivideButton(); + colorDivideButton.addActionListener(e -> checkCardPane()); + colorDivideButton.setSelectedIndex(0); + UILabel label = FRWidgetFactory.createLineWrapLabel(Toolkit.i18nText("Fine-Design_Chart_Color_Divide")); + Component[][] labelComponent = new Component[][]{ + new Component[]{label, colorDivideButton}, + }; + JPanel gapTableLayoutPane = TableLayout4VanChartHelper.createGapTableLayoutPane(labelComponent); + gapTableLayoutPane.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0)); + return gapTableLayoutPane; + } + + protected abstract UIButtonGroup createDivideButton(); + + protected abstract JPanel createColorDividePane(); + + protected void checkCardPane() { + CardLayout cardLayout = (CardLayout) colorDividePane.getLayout(); + cardLayout.show(colorDividePane, String.valueOf(colorDivideButton.getSelectedItem())); + colorDividePane.validate(); + colorDividePane.repaint(); + } +} diff --git a/designer-chart/src/main/java/com/fr/van/chart/gauge/VanChartGaugeBeautyPane.java b/designer-chart/src/main/java/com/fr/van/chart/gauge/VanChartGaugeBeautyPane.java new file mode 100644 index 000000000..61a1fc5e3 --- /dev/null +++ b/designer-chart/src/main/java/com/fr/van/chart/gauge/VanChartGaugeBeautyPane.java @@ -0,0 +1,115 @@ +package com.fr.van.chart.gauge; + +import com.fr.chart.base.ChartConstants; +import com.fr.chart.base.GradientStyle; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.TableLayout; +import com.fr.design.style.background.gradient.FixedGradientBar; +import com.fr.plugin.chart.type.GradientType; +import com.fr.van.chart.designer.TableLayout4VanChartHelper; +import com.fr.van.chart.designer.component.VanChartBeautyPane; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/** + * @author Bjorn + * @version 10.0 + * Created by Bjorn on 2021-05-20 + */ +public class VanChartGaugeBeautyPane extends VanChartBeautyPane { + + private FixedGradientBar colorGradient; + private JPanel gradientBarPane; + + public VanChartGaugeBeautyPane() { + super(); + this.add(initGradientBarPane(), BorderLayout.SOUTH); + this.setBorder(BorderFactory.createEmptyBorder(0, 0, 5, 0)); + initListener(); + } + + private JPanel initGradientBarPane() { + colorGradient = new FixedGradientBar(4, 140); + + double p = TableLayout.PREFERRED; + double f = TableLayout.FILL; + double e = TableLayout4VanChartHelper.EDIT_AREA_WIDTH; + double[] columnSize = {f, e}; + double[] rowSize = {p, p}; + Component[][] components = new Component[][]{ + new Component[]{null, null}, + new Component[]{null, colorGradient}, + }; + + gradientBarPane = TableLayout4VanChartHelper.createGapTableLayoutPane(components, rowSize, columnSize); + colorGradient.updateColor(ChartConstants.GRADIENT_END, ChartConstants.GRADIENT_START); + return gradientBarPane; + } + + private void initListener() { + getGradientTypeBox().addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + checkGradientBarVisible(); + } + }); + } + + protected String labelName() { + return Toolkit.i18nText("Fine-Design_Chart_Color_Style"); + } + + private void checkGradientBarVisible() { + gradientBarPane.setVisible(getGradientTypeBox().getSelectedIndex() == 1); + } + + protected String[] getNameArray() { + return new String[]{ + Toolkit.i18nText("Fine-Design_Chart_Solid_Color"), + Toolkit.i18nText("Fine-Design_Chart_Legend_Gradual"), + }; + } + + public void populateBean(GradientStyle gradientStyle) { + super.populateBean(gradientStyle); + + if (gradientStyle.getGradientType() == GradientType.CUSTOM) { + colorGradient.updateColor(gradientStyle.getStartColor(), gradientStyle.getEndColor()); + } + + checkGradientBarVisible(); + } + + @Override + public GradientStyle updateBean() { + GradientStyle gradientStyle = super.updateBean(); + + if (gradientStyle.getGradientType() == GradientType.CUSTOM) { + gradientStyle.setStartColor(colorGradient.getSelectColorPointBtnP1().getColorInner()); + gradientStyle.setEndColor(colorGradient.getSelectColorPointBtnP2().getColorInner()); + } + return gradientStyle; + } + + protected int convertGradientTypeToIndex(GradientType gradientType) { + switch (gradientType) { + case CUSTOM: + return 1; + default: + return 0; + } + } + + protected GradientType convertIndexToGradientType(int index) { + switch (index) { + case 1: + return GradientType.CUSTOM; + default: + return GradientType.AUTO; + } + } +} diff --git a/designer-chart/src/main/java/com/fr/van/chart/gauge/VanChartGaugeSeriesPane.java b/designer-chart/src/main/java/com/fr/van/chart/gauge/VanChartGaugeSeriesPane.java index aab8f3cf2..afdd2d4ca 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/gauge/VanChartGaugeSeriesPane.java +++ b/designer-chart/src/main/java/com/fr/van/chart/gauge/VanChartGaugeSeriesPane.java @@ -1,5 +1,7 @@ package com.fr.van.chart.gauge; +import com.fr.chart.base.AttrFillStyle; +import com.fr.chart.base.GradientStyle; import com.fr.chart.chartattr.Plot; import com.fr.chart.chartglyph.ConditionAttr; import com.fr.design.gui.frpane.UINumberDragPane; @@ -12,7 +14,7 @@ import com.fr.design.i18n.Toolkit; import com.fr.design.layout.TableLayout; import com.fr.design.layout.TableLayoutHelper; import com.fr.design.mainframe.chart.gui.ChartStylePane; -import com.fr.design.mainframe.chart.gui.style.series.ColorPickerPaneWithFormula; +import com.fr.design.mainframe.chart.gui.style.series.ColorPickerPaneWithMaxMin; import com.fr.design.mainframe.chart.gui.style.series.UIColorPickerPane; import com.fr.design.style.color.ColorSelectBox; import com.fr.general.ComparatorUtils; @@ -21,15 +23,17 @@ import com.fr.plugin.chart.base.AttrLabel; import com.fr.plugin.chart.base.AttrLabelDetail; import com.fr.plugin.chart.gauge.VanChartGaugePlot; import com.fr.plugin.chart.type.GaugeStyle; +import com.fr.plugin.chart.type.GradientType; import com.fr.stable.Constants; import com.fr.van.chart.designer.TableLayout4VanChartHelper; -import com.fr.van.chart.designer.component.VanChartBeautyPane; -import com.fr.van.chart.designer.style.series.VanChartAbstractPlotSeriesPane; +import com.fr.van.chart.designer.component.VanChartFillStylePane; +import com.fr.van.chart.designer.style.series.VanChartMultiColorSeriesPane; import javax.swing.JPanel; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import java.awt.BorderLayout; +import java.awt.CardLayout; import java.awt.Component; import java.awt.Dimension; import java.awt.event.ActionEvent; @@ -38,7 +42,7 @@ import java.awt.event.ActionListener; /** * Created by Mitisky on 15/11/27. */ -public class VanChartGaugeSeriesPane extends VanChartAbstractPlotSeriesPane { +public class VanChartGaugeSeriesPane extends VanChartMultiColorSeriesPane { private static final long serialVersionUID = -4414343926082129759L; private UIButtonGroup gaugeLayout;//布局:横向、纵向 @@ -61,6 +65,10 @@ public class VanChartGaugeSeriesPane extends VanChartAbstractPlotSeriesPane { private UISpinner thermometerWidth; private UINumberDragPane chutePercent; + private VanChartFillStylePane valueFillStylePane; + + private JPanel colorChoosePane; + public VanChartGaugeSeriesPane(ChartStylePane parent, Plot plot) { super(parent, plot); } @@ -71,16 +79,86 @@ public class VanChartGaugeSeriesPane extends VanChartAbstractPlotSeriesPane { double e = TableLayout4VanChartHelper.EDIT_AREA_WIDTH; double[] columnSize = {f}; //TODO Bjorn - double[] rowSize = {p,p,p,p,p,p,p}; + double[] rowSize = {p, p, p, p, p, p, p}; Component[][] components = new Component[][]{ new Component[]{createGaugeLayoutPane()}, - new Component[]{createGaugeStylePane(rowSize, new double[]{f,e})}, + new Component[]{createGaugeStylePane(rowSize, new double[]{f, e})}, new Component[]{createGaugeBandsPane()} }; return TableLayoutHelper.createTableLayoutPane(components, rowSize, columnSize); } + protected JPanel createColorChoosePane() { + vanChartFillStylePane = getVanChartFillStylePane(); + GaugeStyle style = getGaugeStyle(); + switch (style) { + case RING: + case SLOT: + case THERMOMETER: + colorChoosePane = super.createColorChoosePane(); + break; + default: + colorChoosePane = vanChartFillStylePane; + break; + } + return colorChoosePane; + } + + protected void checkFillStylePane(GradientStyle gradientStyle) { + if (colorChoosePane != null) { + colorChoosePane.setVisible(gradientStyle.getGradientType() != GradientType.CUSTOM); + } + } + + protected UIButtonGroup createDivideButton() { + return new UIButtonGroup<>(new String[]{ + Toolkit.i18nText("Fine-Design_Chart_Style_Category"), + Toolkit.i18nText("Fine-Design_Chart_Use_Value") + }, new String[]{"category", "value"}); + } + + protected JPanel createColorDividePane() { + JPanel panel = new JPanel(new BorderLayout(0, 0)); + valueFillStylePane = getVanChartFillStylePane(); + JPanel stylePane = valueFillStylePane == null ? new JPanel() : valueFillStylePane; + + colorPickerPane = new ColorPickerPaneWithMaxMin(parentPane, "meterString", valueFillStylePane) { + protected int getBoundX() { + return 0; + } + + protected int getBoundY() { + return 10; + } + + protected double getDescriptionWidth() { + double descriptionWidth = super.getDescriptionWidth(); + if (valueFillStylePane == null) { + descriptionWidth += 3; + } + return descriptionWidth; + } + }; + panel.add(colorPickerPane, BorderLayout.NORTH); + panel.add(stylePane, BorderLayout.CENTER); + + JPanel categoryFillPane = vanChartFillStylePane == null ? new JPanel() : vanChartFillStylePane; + JPanel colorDividePane = new JPanel(new CardLayout()) { + @Override + public Dimension getPreferredSize() { + if (getColorDivideButton().getSelectedIndex() == 0) { + return categoryFillPane.getPreferredSize(); + } else { + return panel.getPreferredSize(); + } + } + }; + colorDividePane.add(categoryFillPane, "category"); + colorDividePane.add(panel, "value"); + return colorDividePane; + } + private JPanel createGaugeLayoutPane() { gaugeLayout = new UIButtonGroup(new String[]{Toolkit.i18nText("Fine-Design_Chart_Direction_Horizontal"), Toolkit.i18nText("Fine-Design_Chart_Direction_Vertical")}); @@ -105,20 +183,20 @@ public class VanChartGaugeSeriesPane extends VanChartAbstractPlotSeriesPane { } private void changeLabelPosition() { - if(plot instanceof VanChartGaugePlot){ - VanChartGaugePlot gaugePlot = (VanChartGaugePlot)plot; - if (ComparatorUtils.equals(gaugePlot.getGaugeStyle(), GaugeStyle.THERMOMETER)){ + if (plot instanceof VanChartGaugePlot) { + VanChartGaugePlot gaugePlot = (VanChartGaugePlot) plot; + if (ComparatorUtils.equals(gaugePlot.getGaugeStyle(), GaugeStyle.THERMOMETER)) { ConditionAttr attrList = gaugePlot.getConditionCollection().getDefaultAttr(); - AttrLabel attrLabel = (AttrLabel)attrList.getExisted(AttrLabel.class); - if(attrLabel == null){ + AttrLabel attrLabel = (AttrLabel) attrList.getExisted(AttrLabel.class); + if (attrLabel == null) { return; } AttrLabelDetail attrLabelDetail = attrLabel.getAttrLabelDetail(); - if(attrLabelDetail == null || attrLabelDetail.getTextAttr() == null){ + if (attrLabelDetail == null || attrLabelDetail.getTextAttr() == null) { return; } attrLabelDetail.getTextAttr().setFRFont(VanChartGaugePlot.THERMOMETER_LABEL_FONT); - if(gaugeLayout.getSelectedIndex() == 0){ + if (gaugeLayout.getSelectedIndex() == 0) { attrLabel.getAttrLabelDetail().setPosition(Constants.LEFT); attrLabel.getGaugeValueLabelDetail().setPosition(Constants.LEFT); } else { @@ -133,7 +211,7 @@ public class VanChartGaugeSeriesPane extends VanChartAbstractPlotSeriesPane { JPanel panel = new JPanel(new BorderLayout(0, 6)); JPanel centerPanel = TableLayoutHelper.createTableLayoutPane(getDiffComponentsWithGaugeStyle(), row, col); panel.add(centerPanel, BorderLayout.CENTER); - if(rotate != null){ + if (rotate != null) { JPanel panel1 = TableLayout4VanChartHelper.createGapTableLayoutPane(Toolkit.i18nText("Fine-Design_Chart_Rotation_Direction"), rotate); panel.add(panel1, BorderLayout.NORTH); } @@ -141,7 +219,7 @@ public class VanChartGaugeSeriesPane extends VanChartAbstractPlotSeriesPane { } private Component[][] getDiffComponentsWithGaugeStyle() { - GaugeStyle style = plot == null ? GaugeStyle.POINTER : ((VanChartGaugePlot)plot).getGaugeStyle(); + GaugeStyle style = getGaugeStyle(); switch (style) { //TODO Bjorn 仪表盘样式自动逻辑 case RING: @@ -149,8 +227,8 @@ public class VanChartGaugeSeriesPane extends VanChartAbstractPlotSeriesPane { return new Component[][]{ new Component[]{null, null}, getPaneBackgroundColor(), - /* getPaneBackgroundColorAuto(), - new Component[]{null, paneBackgroundColor},*/ + /* getPaneBackgroundColorAuto(), + new Component[]{null, paneBackgroundColor},*/ getInnerPaneBackgroundColor(), new Component[]{createRadiusPane(Toolkit.i18nText("Fine-Design_Chart_Radius_Set")), null}, getChutePercent() @@ -160,8 +238,8 @@ public class VanChartGaugeSeriesPane extends VanChartAbstractPlotSeriesPane { new Component[]{null, null}, getNeedleColor(), getSlotBackgroundColor(), - /* getSlotBackgroundColorAuto(), - new Component[]{null, slotBackgroundColor},*/ + /* getSlotBackgroundColorAuto(), + new Component[]{null, slotBackgroundColor},*/ new Component[]{createRadiusPane(Toolkit.i18nText("Fine-Design_Chart_Radius_Set")), null}, getChutePercent() }; @@ -179,13 +257,13 @@ public class VanChartGaugeSeriesPane extends VanChartAbstractPlotSeriesPane { return new Component[][]{ new Component[]{null, null}, getHingeColor(), - /* getHingeColorAuto(), - new Component[]{null, hingeColor},*/ + /* getHingeColorAuto(), + new Component[]{null, hingeColor},*/ getHingeBackgroundColor(), getNeedleColor(), getPaneBackgroundColor(), - /* getPaneBackgroundColorAuto(), - new Component[]{null, paneBackgroundColor},*/ + /* getPaneBackgroundColorAuto(), + new Component[]{null, paneBackgroundColor},*/ new Component[]{createRadiusPane(Toolkit.i18nText("Fine-Design_Chart_Radius_Set")), null} }; } @@ -212,12 +290,12 @@ public class VanChartGaugeSeriesPane extends VanChartAbstractPlotSeriesPane { private Component[] getHingeBackgroundColor() { hingeBackgroundColor = new ColorSelectBox(120); - return new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Chart_Hinge_Background")),hingeBackgroundColor}; + return new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Chart_Hinge_Background")), hingeBackgroundColor}; } private Component[] getNeedleColor() { needleColor = new ColorSelectBox(120); - return new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Chart_Needle")),needleColor}; + return new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Chart_Needle")), needleColor}; } private Component[] getPaneBackgroundColorAuto() { @@ -236,7 +314,7 @@ public class VanChartGaugeSeriesPane extends VanChartAbstractPlotSeriesPane { private Component[] getPaneBackgroundColor() { paneBackgroundColor = new ColorSelectBox(120); - return new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Chart_Pane_Background")),paneBackgroundColor}; + return new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Chart_Pane_Background")), paneBackgroundColor}; } private Component[] getSlotBackgroundColorAuto() { @@ -255,17 +333,17 @@ public class VanChartGaugeSeriesPane extends VanChartAbstractPlotSeriesPane { private Component[] getSlotBackgroundColor() { slotBackgroundColor = new ColorSelectBox(120); - return new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Chart_Slot_Background")),slotBackgroundColor}; + return new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Chart_Slot_Background")), slotBackgroundColor}; } private Component[] getThermometerWidth() { thermometerWidth = new UISpinnerWithPx(0, Double.MAX_VALUE, 0.1, 10); - return new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Chart_Thermometer_Width")),thermometerWidth}; + return new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Chart_Thermometer_Width")), thermometerWidth}; } private Component[] getChutePercent() { chutePercent = new UINumberDragPaneWithPercent(0, 100, 1); - return new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Chart_Chute_Percent")),chutePercent}; + return new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Chart_Chute_Percent")), chutePercent}; } private void initRotate() { @@ -274,12 +352,16 @@ public class VanChartGaugeSeriesPane extends VanChartAbstractPlotSeriesPane { private Component[] getInnerPaneBackgroundColor() { innerPaneBackgroundColor = new ColorSelectBox(120); - return new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Chart_Inner_Pane_Background")),innerPaneBackgroundColor}; + return new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Chart_Inner_Pane_Background")), innerPaneBackgroundColor}; } private JPanel createGaugeBandsPane() { - colorPickerPane = new ColorPickerPaneWithFormula(parentPane, "meterString"); - return TableLayout4VanChartHelper.createExpandablePaneWithTitle(Toolkit.i18nText("Fine-Design_Chart_Range"), colorPickerPane); + GaugeStyle gaugeStyle = getGaugeStyle(); + if (gaugeStyle == GaugeStyle.POINTER || gaugeStyle == GaugeStyle.POINTER_SEMI) { + colorPickerPane = new ColorPickerPaneWithMaxMin(parentPane, "meterString"); + return TableLayout4VanChartHelper.createExpandablePaneWithTitle(Toolkit.i18nText("Fine-Design_Chart_Range"), colorPickerPane); + } + return null; } private void checkHingeColorAutoButton() { @@ -298,12 +380,12 @@ public class VanChartGaugeSeriesPane extends VanChartAbstractPlotSeriesPane { } public void populateBean(Plot plot) { - if(plot == null) { + if (plot == null) { return; } super.populateBean(plot); - if(plot instanceof VanChartGaugePlot){ - VanChartGaugePlot gaugePlot = (VanChartGaugePlot)plot; + if (plot instanceof VanChartGaugePlot) { + VanChartGaugePlot gaugePlot = (VanChartGaugePlot) plot; GaugeDetailStyle detailStyle = gaugePlot.getGaugeDetailStyle(); gaugeLayout.setSelectedIndex(detailStyle.isHorizontalLayout() ? 0 : 1); @@ -319,46 +401,53 @@ public class VanChartGaugeSeriesPane extends VanChartAbstractPlotSeriesPane { slotBackgroundColorAuto.setSelectedIndex(detailStyle.isSlotBackgroundColorAuto() ? 0 : 1); checkSlotBackgroundColorAutoButton(); } - if(hingeColor != null){ + if (hingeColor != null) { hingeColor.setSelectObject(detailStyle.getHingeColor()); } - if(hingeBackgroundColor != null){ + if (hingeBackgroundColor != null) { hingeBackgroundColor.setSelectObject(detailStyle.getHingeBackgroundColor()); } - if(needleColor != null){ + if (needleColor != null) { needleColor.setSelectObject(detailStyle.getNeedleColor()); } - if(paneBackgroundColor != null){ + if (paneBackgroundColor != null) { paneBackgroundColor.setSelectObject(detailStyle.getPaneBackgroundColor()); } - if(slotBackgroundColor != null){ + if (slotBackgroundColor != null) { slotBackgroundColor.setSelectObject(detailStyle.getSlotBackgroundColor()); } - if(rotate != null){ + if (rotate != null) { rotate.setSelectedIndex(detailStyle.isAntiClockWise() ? 0 : 1); } - if(innerPaneBackgroundColor != null){ + if (innerPaneBackgroundColor != null) { innerPaneBackgroundColor.setSelectObject(detailStyle.getInnerPaneBackgroundColor()); } - if(thermometerWidth != null){ + if (thermometerWidth != null) { thermometerWidth.setValue(detailStyle.getThermometerWidth()); } - if(chutePercent != null){ + if (chutePercent != null) { chutePercent.populateBean(detailStyle.getChutePercent()); } + if (getColorDivideButton() != null) { + getColorDivideButton().setSelectedIndex(detailStyle.isColorUseCategory() ? 0 : 1); + checkCardPane(); + } colorPickerPane.populateBean(detailStyle.getHotAreaColor()); + if (valueFillStylePane != null) { + valueFillStylePane.populateBean(plot.getPlotFillStyle()); + } } } @Override public void updateBean(Plot plot) { - if(plot == null){ + if (plot == null) { return; } super.updateBean(plot); - if(plot instanceof VanChartGaugePlot){ - VanChartGaugePlot gaugePlot = (VanChartGaugePlot)plot; + if (plot instanceof VanChartGaugePlot) { + VanChartGaugePlot gaugePlot = (VanChartGaugePlot) plot; GaugeDetailStyle detailStyle = gaugePlot.getGaugeDetailStyle(); detailStyle.setHorizontalLayout(gaugeLayout.getSelectedIndex() == 0); @@ -372,40 +461,65 @@ public class VanChartGaugeSeriesPane extends VanChartAbstractPlotSeriesPane { if (slotBackgroundColorAuto != null) { detailStyle.setSlotBackgroundColorAuto(slotBackgroundColorAuto.getSelectedIndex() == 0); } - if(hingeColor != null){ + if (hingeColor != null) { detailStyle.setHingeColor(hingeColor.getSelectObject()); } - if(hingeBackgroundColor != null){ + if (hingeBackgroundColor != null) { detailStyle.setHingeBackgroundColor(hingeBackgroundColor.getSelectObject()); } - if(needleColor != null){ + if (needleColor != null) { detailStyle.setNeedleColor(needleColor.getSelectObject()); } - if(paneBackgroundColor != null){ + if (paneBackgroundColor != null) { detailStyle.setPaneBackgroundColor(paneBackgroundColor.getSelectObject()); } - if(slotBackgroundColor != null){ + if (slotBackgroundColor != null) { detailStyle.setSlotBackgroundColor(slotBackgroundColor.getSelectObject()); } - if(rotate != null){ + if (rotate != null) { detailStyle.setAntiClockWise(rotate.getSelectedIndex() == 0); } - if(innerPaneBackgroundColor != null){ + if (innerPaneBackgroundColor != null) { detailStyle.setInnerPaneBackgroundColor(innerPaneBackgroundColor.getSelectObject()); } - if(thermometerWidth != null){ + if (thermometerWidth != null) { detailStyle.setThermometerWidth(thermometerWidth.getValue()); } - if(chutePercent != null){ + if (chutePercent != null) { detailStyle.setChutePercent(chutePercent.updateBean()); } colorPickerPane.updateBean(detailStyle.getHotAreaColor()); + if (getColorDivideButton() != null) { + int selectedIndex = getColorDivideButton().getSelectedIndex(); + detailStyle.setColorUseCategory(selectedIndex == 0); + } + if (!detailStyle.isColorUseCategory()) { + if (valueFillStylePane != null) { + AttrFillStyle plotFillStyle = plot.getPlotFillStyle(); + if (plotFillStyle == null) { + plotFillStyle = new AttrFillStyle(); + plot.setPlotFillStyle(plotFillStyle); + } + valueFillStylePane.updateBean(plotFillStyle); + } + } } } @Override - protected VanChartBeautyPane createStylePane() { - return null; + protected VanChartGaugeBeautyPane createStylePane() { + GaugeStyle gaugeStyle = getGaugeStyle(); + switch (gaugeStyle) { + case POINTER: + case POINTER_SEMI: + return null; + default: + return new VanChartGaugeBeautyPane(); + } + } + + private GaugeStyle getGaugeStyle() { + return plot == null ? GaugeStyle.POINTER : ((VanChartGaugePlot) plot).getGaugeStyle(); } } \ No newline at end of file diff --git a/designer-chart/src/main/java/com/fr/van/chart/map/designer/type/GisLayerPane.java b/designer-chart/src/main/java/com/fr/van/chart/map/designer/type/GisLayerPane.java index e94c79818..4a43d7619 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/map/designer/type/GisLayerPane.java +++ b/designer-chart/src/main/java/com/fr/van/chart/map/designer/type/GisLayerPane.java @@ -79,6 +79,7 @@ public class GisLayerPane extends JPanel implements UIObserver { private JPanel createGISLayerPane() { gisButton = new UIButtonGroup(new String[]{Toolkit.i18nText("Fine-Design_Form_Widget_Style_Standard"), Toolkit.i18nText("Fine-Design_Chart_Custom")}); + gisButton.setSelectedIndex(0); gisGaoDeLayer = new UIComboBox(MapLayerConfigManager.getGaoDeLayerItems()); gisButton.addActionListener(event -> { refreshZoomLevel(); diff --git a/designer-chart/src/main/java/com/fr/van/chart/map/designer/type/WMSLayerPane.java b/designer-chart/src/main/java/com/fr/van/chart/map/designer/type/WMSLayerPane.java index 19afd688f..67369d826 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/map/designer/type/WMSLayerPane.java +++ b/designer-chart/src/main/java/com/fr/van/chart/map/designer/type/WMSLayerPane.java @@ -1,6 +1,6 @@ package com.fr.van.chart.map.designer.type; -import com.fr.decision.webservice.v10.map.WMSFactory; +import com.fr.decision.webservice.v10.map.MapEditService; import com.fr.design.dialog.FineJOptionPane; import com.fr.design.event.UIObserver; import com.fr.design.event.UIObserverListener; @@ -11,7 +11,6 @@ import com.fr.design.gui.itextarea.UITextArea; import com.fr.design.i18n.Toolkit; import com.fr.design.layout.TableLayout; import com.fr.design.layout.TableLayoutHelper; -import com.fr.general.http.HttpClient; import com.fr.plugin.chart.base.GisLayer; import com.fr.plugin.chart.map.layer.WMSLayer; import com.fr.van.chart.designer.TableLayout4VanChartHelper; @@ -85,21 +84,13 @@ public class WMSLayerPane extends JPanel implements UIObserver { public void actionPerformed(ActionEvent e) { new SwingWorker() { - private java.util.List list = new ArrayList<>(); + private List list = new ArrayList<>(); @Override protected Void doInBackground() { - HttpClient httpClient = new HttpClient(wmsUrl.getText() + "service=WMS&request=GetCapabilities"); - httpClient.asGet(); - - if (!httpClient.isServerAlive()) { - return null; - } - - String res = httpClient.getResponseText(); - List layers = WMSFactory.readLayers(res); + List wmsNames = MapEditService.getInstance().getWMSNames(wmsUrl.getText()); list.clear(); - for (String layer : layers) { + for (String layer : wmsNames) { list.add(new WMSLayer(layer, false)); } return null; @@ -108,9 +99,8 @@ public class WMSLayerPane extends JPanel implements UIObserver { @Override protected void done() { connectButton.setText(Toolkit.i18nText("Fine-Design_Chart_Connect_WMP")); - if (list != null && list.size() > 0) { - resetWMSLayerPane(list); - } else { + resetWMSLayerPane(list); + if (list == null || list.isEmpty()) { FineJOptionPane.showMessageDialog(null, Toolkit.i18nText("Fine-Design_Chart_Invalid_WMS")); } } diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRAbsoluteLayoutAdapter.java b/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRAbsoluteLayoutAdapter.java index 0c6adeb09..932338a3f 100644 --- a/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRAbsoluteLayoutAdapter.java +++ b/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRAbsoluteLayoutAdapter.java @@ -235,6 +235,8 @@ public class FRAbsoluteLayoutAdapter extends FRBodyLayoutAdapter { } else { container.add(creator, creator.toData().getWidgetName(),0); } + //这边将组件添加到container后,需要做下layout处理,否则其内部的一些组件的宽高可能为0,从而导致在updateChildBounds的时候出现问题 + LayoutUtils.layoutRootContainer(creator); XWAbsoluteLayout layout = (XWAbsoluteLayout) container; layout.updateBoundsWidget(creator); updateCreatorBackBound(); diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRFitLayoutAdapter.java b/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRFitLayoutAdapter.java index c0eb39297..22d74d774 100644 --- a/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRFitLayoutAdapter.java +++ b/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRFitLayoutAdapter.java @@ -347,15 +347,7 @@ public class FRFitLayoutAdapter extends FRBodyLayoutAdapter { //拖拽组件原大小、位置 Rectangle backupBound = creator.getBackupBound(); backupBound.x -= container.getX(); - // REPORT-34739 对绝对画布块的backupBound.y的调整还需要考虑一下参数面板块的高度造成的偏移 - int paraHeight = 0; - if (creator.acceptType(XWAbsoluteLayout.class)) { - JTemplate jTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); - if (jTemplate instanceof JForm) { - paraHeight = ((JForm) jTemplate).getFormDesign().getParaHeight(); - } - } - backupBound.y -= (container.getY() - paraHeight); + backupBound.y -= container.getY(); //当前拖拽组件的位置 int x = creator.getX(); int y = creator.getY(); diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XBorderStyleWidgetCreator.java b/designer-form/src/main/java/com/fr/design/designer/creator/XBorderStyleWidgetCreator.java index fdefc019a..e4b5377ba 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XBorderStyleWidgetCreator.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XBorderStyleWidgetCreator.java @@ -1,6 +1,7 @@ package com.fr.design.designer.creator; import com.fr.base.BaseFormula; +import com.fr.base.iofile.attr.ExtendSharableAttrMark; import com.fr.design.border.UIRoundedBorder; import com.fr.form.ui.AbstractBorderStyleWidget; import com.fr.form.ui.Label; @@ -31,6 +32,11 @@ public class XBorderStyleWidgetCreator extends XWidgetCreator{ public XBorderStyleWidgetCreator(Widget widget, Dimension initSize) { super(widget, initSize); + + ExtendSharableAttrMark sharableAttrMark = this.toData().getWidgetAttrMark(ExtendSharableAttrMark.XML_TAG); + if (sharableAttrMark != null) { + this.setShareId(sharableAttrMark.getShareId()); + } } /** diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XChartEditor.java b/designer-form/src/main/java/com/fr/design/designer/creator/XChartEditor.java index a6a29339e..24bea0177 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XChartEditor.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XChartEditor.java @@ -17,7 +17,6 @@ import com.fr.design.mainframe.CoverReportPane; import com.fr.design.mainframe.EastRegionContainerPane; import com.fr.design.mainframe.EditingMouseListener; import com.fr.design.mainframe.FormDesigner; -import com.fr.design.mainframe.HelpDialogManager; import com.fr.design.mainframe.widget.editors.WLayoutBorderStyleEditor; import com.fr.design.module.DesignModuleFactory; import com.fr.form.ui.BaseChartEditor; @@ -273,10 +272,11 @@ public class XChartEditor extends XBorderStyleWidgetCreator { } } } - HelpDialogManager.getInstance().setPane(coverPanel); - if (this.isHelpBtnOnFocus()) { - coverPanel.setMsgDisplay(e); + if (this.isShareConfigButtonFocus()) { + CoverReportPane.showShareConfig(((XCreator) this.getParent()).toData()); } + + } @Override @@ -315,23 +315,6 @@ public class XChartEditor extends XBorderStyleWidgetCreator { return editor; } - /** - * 是否展现覆盖的pane - * - * @param display 是否 - */ - public void displayCoverPane(boolean display) { - isHovering = display; - coverPanel.setVisible(display); - coverPanel.setPreferredSize(editor.getPreferredSize()); - coverPanel.setBounds(editor.getBounds()); - editor.repaint(); - } - - public JComponent getCoverPane() { - return coverPanel; - } - /** * 是否支持设置可用 * return boolean diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XCreator.java b/designer-form/src/main/java/com/fr/design/designer/creator/XCreator.java index c7c91d9aa..3cd33d6c3 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XCreator.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XCreator.java @@ -24,16 +24,11 @@ import com.fr.design.utils.gui.LayoutUtils; import com.fr.form.ui.Widget; import com.fr.form.ui.container.WTitleLayout; import com.fr.stable.Constants; -import com.fr.stable.CoreGraphHelper; import com.fr.stable.StableUtils; import com.fr.stable.StringUtils; -import com.fr.third.javax.annotation.Nullable; import javax.swing.BorderFactory; -import javax.swing.Icon; -import javax.swing.ImageIcon; import javax.swing.JComponent; -import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.border.Border; import java.awt.BorderLayout; @@ -43,7 +38,6 @@ import java.awt.Dimension; import java.awt.Graphics; import java.awt.Rectangle; import java.awt.event.MouseEvent; -import java.awt.image.BufferedImage; import java.beans.IntrospectionException; import java.util.ArrayList; import java.util.List; @@ -71,7 +65,7 @@ public abstract class XCreator extends JPanel implements XComponent, XCreatorToo private int[] directions; private Rectangle backupBound; private String shareId = StringUtils.EMPTY;//如果组件是共享的会有这个属性 - private boolean isHelpBtnOnFocus = false;//焦点是否在帮助按钮上 + private boolean isShareConfigButtonFocus = false;//焦点是否在帮助按钮上 private static final int SHORTS_SEPARATOR_POS = 4; // 弹出菜单分割的位置 public XCreator(Widget ob, Dimension initSize) { @@ -658,6 +652,9 @@ public abstract class XCreator extends JPanel implements XComponent, XCreatorToo public void setShareId(String shareId) { this.shareId = shareId; + if (coverPanel != null) { + coverPanel.setShared(isShared()); + } } public String getShareId() { @@ -668,54 +665,31 @@ public abstract class XCreator extends JPanel implements XComponent, XCreatorToo * 焦点是否在帮助按钮上 * @return 焦点是否在帮助按钮上 */ - public boolean isHelpBtnOnFocus() { - return isHelpBtnOnFocus; + public boolean isShareConfigButtonFocus() { + return isShareConfigButtonFocus; } - public void setHelpBtnOnFocus(boolean helpBtnOnFocus) { - isHelpBtnOnFocus = helpBtnOnFocus; + public void setShareConfigButtonFocus(boolean shareConfigButtonFocus) { + isShareConfigButtonFocus = shareConfigButtonFocus; } - /** - * 设置描述信息 - * @param msg 帮助信息 - */ - public void setXDescrption(String msg){ - if (coverPanel != null) { - coverPanel.setHelpMsg(msg); - } - } - public JComponent getCoverPane(){ + public CoverReportPane getCoverPane(){ return coverPanel; } - /** - * 销毁帮助提示框 - */ - public void destroyHelpDialog(){ - if (coverPanel != null) { - coverPanel.destroyHelpDialog(); - } - } - /** * 是否展现覆盖的pane * @param display 是否 */ public void displayCoverPane(boolean display){ - } - - /** - * 根据widget设置Xcreator描述信息 - * @param widget - */ - public void setXDescrption(Widget widget){ - if (widget != null) { - setXDescrption(widget.getDescription()); + if (coverPanel != null) { + coverPanel.setVisible(display); + coverPanel.setPreferredSize(editor.getPreferredSize()); + coverPanel.setBounds(editor.getBounds()); + editor.repaint(); } } - /** * 按照比例调整组件的宽度 * @param percent 比例 diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XCreatorUtils.java b/designer-form/src/main/java/com/fr/design/designer/creator/XCreatorUtils.java index 260318023..945d3bfdd 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XCreatorUtils.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XCreatorUtils.java @@ -257,7 +257,6 @@ public class XCreatorUtils { FineLoggerFactory.getLogger().error("Error to create xcreator!"); creator = new NullCreator(widget, d); } - creator.setXDescrption(widget);//设置描述信息 return creator; } diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XElementCase.java b/designer-form/src/main/java/com/fr/design/designer/creator/XElementCase.java index 14e0a6511..9c459e986 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XElementCase.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XElementCase.java @@ -32,345 +32,324 @@ import java.beans.IntrospectionException; import java.beans.PropertyDescriptor; import java.util.Set; -public class XElementCase extends XBorderStyleWidgetCreator implements FormElementCaseContainerProvider{ - private UILabel imageLable; - private CoverReportPane coverPanel; - private FormDesigner designer; - private static BufferedImage DEFAULT_BACKGROUND; - private boolean isHovering = false; - - static{ - try{ - DEFAULT_BACKGROUND = BaseUtils.readImageWithCache("com/fr/base/images/report/elementcase.png"); - }catch (Throwable e) { - //IBM jdk 1.5.0_22 并发下读取图片有时会异常(EOFException), 这个图片反正只有设计器用到, 捕获住 - DEFAULT_BACKGROUND = CoreGraphHelper.createBufferedImage(0, 0); - } - } - - public XElementCase(ElementCaseEditor widget, Dimension initSize) { - super(widget, initSize); - - - } - - protected void initXCreatorProperties() { - super.initXCreatorProperties(); - - // 报表块初始化时要加载对应的borderStyle - initBorderStyle(); - } - - /** - * 是否支持设置标题 - * @return 是返回true - */ - public boolean hasTitleStyle() { - return true; - } - - /** - * 返回组件属性值 - * @return 返回组件属性值 - * @throws IntrospectionException 异常 - */ - public CRPropertyDescriptor[] supportedDescriptor() throws IntrospectionException { - - CRPropertyDescriptor[] propertyTableEditor = new CRPropertyDescriptor[]{ - new CRPropertyDescriptor("widgetName", this.data.getClass()) - .setI18NName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Form_Widget_Name")), - new CRPropertyDescriptor("visible", this.data.getClass()).setI18NName( - com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Visible")).setPropertyChangeListener(new PropertyChangeAdapter() { - - @Override - public void propertyChange() { - makeVisible(toData().isVisible()); - } - }), - new CRPropertyDescriptor("borderStyle", this.data.getClass()).setEditorClass( - WLayoutBorderStyleEditor.class).setI18NName( - com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style")).putKeyValue(XCreatorConstants.PROPERTY_CATEGORY, "Fine-Design_Basic_Advanced") - .setPropertyChangeListener(new PropertyChangeAdapter() { - - @Override - public void propertyChange() { - initStyle(); - } - }), - new CRPropertyDescriptor("margin", this.data.getClass()).setEditorClass(PaddingMarginEditor.class) - .setI18NName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Layout_Padding")) - .putKeyValue(XCreatorConstants.PROPERTY_CATEGORY, "Fine-Design_Basic_Advanced"), - new CRPropertyDescriptor("toolBars", this.data.getClass()).setEditorClass(ElementCaseToolBarEditor.class) - .setI18NName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_EC_Toolbar")) - .putKeyValue(XCreatorConstants.PROPERTY_CATEGORY, "Fine-Design_Basic_Advanced") - - - }; - CRPropertyDescriptor[] extraTableEditor = getExtraTableEditor(); - return ArrayUtils.addAll(propertyTableEditor, extraTableEditor); - } - - - public CRPropertyDescriptor[] getExtraTableEditor(){ - CRPropertyDescriptor[] extraTableEditor = resolveCompatible(); - CRPropertyDescriptor reportFitEditor = getReportFitEditor(); - if (reportFitEditor == null) { - return extraTableEditor; - } - return ArrayUtils.add(extraTableEditor, reportFitEditor); - } - - @Override - public boolean supportMobileStyle() { - return false; - } - - private CRPropertyDescriptor getReportFitEditor() { - this.designer = WidgetPropertyPane.getInstance().getEditingFormDesigner(); - FitProvider wbTpl = designer.getTarget(); - ReportFitAttr fitAttr = wbTpl.getReportFitAttr(); - ElementCaseEditor editor = this.toData(); - //兼容之前报表块(之前三个选项为:默认 横向 双向 现在是:横向 双向 不自适应) - if (editor.getFitStateInPC() == 0) { - editor.setReportFitAttr(null); - } - ReportFitAttr reportFit = editor.getReportFitAttr(); - if(fitAttr != null){ - reportFit = fitAttr.fitInBrowser() ? editor.getReportFitAttr() : fitAttr; - } - ReportFitAttr reportFitAttr = editor.getReportFitAttr() == null ? fitAttr : reportFit; - BrowserFitPropertyEditor browserFitPropertyEditor = new BrowserFitPropertyEditor(); - CRPropertyDescriptor extraEditor = browserFitPropertyEditor.createPropertyDescriptor(this.data.getClass(), reportFitAttr); - if (editor.getReportFitAttr() == null) { - editor.setReportFitInPc(browserFitPropertyEditor.getFitStateInPC(fitAttr)); - } - return extraEditor; - } - - - private CRPropertyDescriptor[] resolveCompatible() { - CRPropertyDescriptor[] extraProperty = new CRPropertyDescriptor[0]; - //这边有个插件兼容问题,之后还是要改回process才行 - Set set = ExtraDesignClassManager.getInstance().getArray(AbstractFormElementCaseEditorProvider.MARK_STRING); - for (FormElementCaseEditorProvider provider : set) { - if (provider == null) { - continue; - } - this.designer = WidgetPropertyPane.getInstance().getEditingFormDesigner(); - FormProvider formProvider = designer.getTarget(); - ElementCaseEditorProvider elementCaseEditorProvider = this.toData(); - PropertyDescriptor[] extraEditor = provider.createPropertyDescriptor(this.data.getClass(), formProvider, elementCaseEditorProvider); - extraProperty = (CRPropertyDescriptor[]) ArrayUtils.addAll(extraProperty, extraEditor); - } - return extraProperty; - } - - @Override - protected String getIconName() { - return "text_field_16.png"; - } - - /** - * 返回组件默认名 - * @return 组件类名(小写) - */ - public String createDefaultName() { - return "report"; - } - - @Override - protected JComponent initEditor() { - if (editor == null) { - setBorder(DEFALUTBORDER); - editor = new JPanel(); - editor.setBackground(null); - editor.setLayout(null); - imageLable = initImageBackground(); - - coverPanel = new CoverReportPane(); - coverPanel.setPreferredSize(imageLable.getPreferredSize()); - coverPanel.setBounds(imageLable.getBounds()); - - editor.add(coverPanel); - coverPanel.setVisible(false); - editor.add(imageLable); - } - return editor; - } - - /** - * 从data中获取到图片背景, 并设置到Label上 - */ - private UILabel initImageBackground(){ - UILabel imageLable = new UILabel(); - BufferedImage image = toData().getECImage(); - if (image == null) { - image = DEFAULT_BACKGROUND; - } - setLabelBackground(image, imageLable); - - return imageLable; - } - - /** - * 设置指定Label的背景 - */ - private void setLabelBackground(Image image, UILabel imageLable){ - ImageIcon icon = new ImageIcon(image); - imageLable.setIcon(icon); - imageLable.setOpaque(true); - imageLable.setLayout(null); - imageLable.setBounds(0, 0, icon.getIconWidth(), icon.getIconHeight()); - } - - /** - * 是否展现覆盖的pane - * @param display 是否 - */ - public void displayCoverPane(boolean display){ - isHovering = display; - coverPanel.setVisible(display); - coverPanel.setBounds(1, 1, (int) editor.getBounds().getWidth(), (int) editor.getBounds().getHeight()); - editor.repaint(); - } - - /** - * 销毁帮助提示框 - */ - public void destroyHelpDialog(){ - coverPanel.destroyHelpDialog(); - } - - public JComponent getCoverPane(){ - return coverPanel; - } - - @Override - public void paintBorder(Graphics g, Rectangle bounds){ - if (!isHovering) { - super.paintBorder(g, bounds); - } - } - - - /** - * 初始化大小 - * @return 尺寸 - */ - public Dimension initEditorSize() { - return BORDER_PREFERRED_SIZE; - } - - /** - * 是否是报表块 - * @return 是 - */ - public boolean isReport() { - return true; - } - - /** - * 该组件是否可以拖入参数面板 - * @return 是则返回true - */ - public boolean canEnterIntoParaPane(){ - return false; - } - - /** - * 返回报表块对应的widget - * @return 返回ElementCaseEditor - */ - public ElementCaseEditor toData() { - return ((ElementCaseEditor) data); - } - - public FormElementCaseProvider getElementCase() { - return toData().getElementCase(); - } - - public String getElementCaseContainerName() { - return toData().getWidgetName(); - } - - public void setElementCase(FormElementCaseProvider el) { - toData().setElementCase(el); - } - - public void setBackground(BufferedImage image){ - toData().setECImage(image); - setEditorIcon(image); - } - - private void setEditorIcon(BufferedImage image){ - setLabelBackground(image, imageLable); - } - - public Dimension getSize(){ - return new Dimension(this.getWidth(), this.getHeight()); - } - - /** - * 响应点击事件 - * @param editingMouseListener 事件处理器 - * @param e 点击事件 - */ - public void respondClick(EditingMouseListener editingMouseListener,MouseEvent e){ - HelpDialogManager.getInstance().setPane(coverPanel); - super.respondClick(editingMouseListener, e); - editingMouseListener.refreshTopXCreator(); - if (this.isHelpBtnOnFocus()) { - coverPanel.setMsgDisplay(e); - } else { - switchTab(e, editingMouseListener); - } - } - - - private void switchTab(MouseEvent e,EditingMouseListener editingMouseListener){ - FormDesigner designer = editingMouseListener.getDesigner(); - if (e.getButton() == MouseEvent.BUTTON1 && - (e.getClickCount() == 2 || designer.getCursor().getType() == Cursor.HAND_CURSOR)){ - FormElementCaseContainerProvider component = (FormElementCaseContainerProvider) designer.getComponentAt(e); - //切换设计器 - designer.switchTab(component); - } - } - - @Override - public WidgetPropertyUIProvider[] getWidgetPropertyUIProviders() { - return new WidgetPropertyUIProvider[]{ new ElementCasePropertyUI(this)}; - } - - @Override - public void setXDescrption(String msg) { - coverPanel.setHelpMsg(msg); - } - - /** - * data属性改变触发其他操作 - * - */ - public void firePropertyChange(){ - initStyle(); - } - - /** - * 是否支持设置可用 - * return boolean - */ - public boolean supportSetEnable(){ - return false; - } - - /** - * 是否支持共享-现只支持报表块、图表、tab块、绝对布局 - * @return - */ - public boolean isSupportShared() { - return true; - } - - - +public class XElementCase extends XBorderStyleWidgetCreator implements FormElementCaseContainerProvider { + private UILabel imageLable; + private FormDesigner designer; + private static BufferedImage DEFAULT_BACKGROUND; + private boolean isHovering = false; + + static { + try { + DEFAULT_BACKGROUND = BaseUtils.readImageWithCache("com/fr/base/images/report/elementcase.png"); + } catch (Throwable e) { + //IBM jdk 1.5.0_22 并发下读取图片有时会异常(EOFException), 这个图片反正只有设计器用到, 捕获住 + DEFAULT_BACKGROUND = CoreGraphHelper.createBufferedImage(0, 0); + } + } + + public XElementCase(ElementCaseEditor widget, Dimension initSize) { + super(widget, initSize); + + + } + + protected void initXCreatorProperties() { + super.initXCreatorProperties(); + + // 报表块初始化时要加载对应的borderStyle + initBorderStyle(); + } + + /** + * 是否支持设置标题 + * @return 是返回true + */ + public boolean hasTitleStyle() { + return true; + } + + /** + * 返回组件属性值 + * @return 返回组件属性值 + * @throws IntrospectionException 异常 + */ + public CRPropertyDescriptor[] supportedDescriptor() throws IntrospectionException { + + CRPropertyDescriptor[] propertyTableEditor = new CRPropertyDescriptor[]{ + new CRPropertyDescriptor("widgetName", this.data.getClass()) + .setI18NName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Form_Widget_Name")), + new CRPropertyDescriptor("visible", this.data.getClass()).setI18NName( + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Visible")).setPropertyChangeListener(new PropertyChangeAdapter() { + + @Override + public void propertyChange() { + makeVisible(toData().isVisible()); + } + }), + new CRPropertyDescriptor("borderStyle", this.data.getClass()).setEditorClass( + WLayoutBorderStyleEditor.class).setI18NName( + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style")).putKeyValue(XCreatorConstants.PROPERTY_CATEGORY, "Fine-Design_Basic_Advanced") + .setPropertyChangeListener(new PropertyChangeAdapter() { + + @Override + public void propertyChange() { + initStyle(); + } + }), + new CRPropertyDescriptor("margin", this.data.getClass()).setEditorClass(PaddingMarginEditor.class) + .setI18NName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Layout_Padding")) + .putKeyValue(XCreatorConstants.PROPERTY_CATEGORY, "Fine-Design_Basic_Advanced"), + new CRPropertyDescriptor("toolBars", this.data.getClass()).setEditorClass(ElementCaseToolBarEditor.class) + .setI18NName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_EC_Toolbar")) + .putKeyValue(XCreatorConstants.PROPERTY_CATEGORY, "Fine-Design_Basic_Advanced") + + + }; + CRPropertyDescriptor[] extraTableEditor = getExtraTableEditor(); + return ArrayUtils.addAll(propertyTableEditor, extraTableEditor); + } + + + public CRPropertyDescriptor[] getExtraTableEditor() { + CRPropertyDescriptor[] extraTableEditor = resolveCompatible(); + CRPropertyDescriptor reportFitEditor = getReportFitEditor(); + if (reportFitEditor == null) { + return extraTableEditor; + } + return ArrayUtils.add(extraTableEditor, reportFitEditor); + } + + @Override + public boolean supportMobileStyle() { + return false; + } + + private CRPropertyDescriptor getReportFitEditor() { + this.designer = WidgetPropertyPane.getInstance().getEditingFormDesigner(); + FitProvider wbTpl = designer.getTarget(); + ReportFitAttr fitAttr = wbTpl.getReportFitAttr(); + ElementCaseEditor editor = this.toData(); + //兼容之前报表块(之前三个选项为:默认 横向 双向 现在是:横向 双向 不自适应) + if (editor.getFitStateInPC() == 0) { + editor.setReportFitAttr(null); + } + ReportFitAttr reportFit = editor.getReportFitAttr(); + if (fitAttr != null) { + reportFit = fitAttr.fitInBrowser() ? editor.getReportFitAttr() : fitAttr; + } + ReportFitAttr reportFitAttr = editor.getReportFitAttr() == null ? fitAttr : reportFit; + BrowserFitPropertyEditor browserFitPropertyEditor = new BrowserFitPropertyEditor(); + CRPropertyDescriptor extraEditor = browserFitPropertyEditor.createPropertyDescriptor(this.data.getClass(), reportFitAttr); + if (editor.getReportFitAttr() == null) { + editor.setReportFitInPc(browserFitPropertyEditor.getFitStateInPC(fitAttr)); + } + return extraEditor; + } + + + private CRPropertyDescriptor[] resolveCompatible() { + CRPropertyDescriptor[] extraProperty = new CRPropertyDescriptor[0]; + //这边有个插件兼容问题,之后还是要改回process才行 + Set set = ExtraDesignClassManager.getInstance().getArray(AbstractFormElementCaseEditorProvider.MARK_STRING); + for (FormElementCaseEditorProvider provider : set) { + if (provider == null) { + continue; + } + this.designer = WidgetPropertyPane.getInstance().getEditingFormDesigner(); + FormProvider formProvider = designer.getTarget(); + ElementCaseEditorProvider elementCaseEditorProvider = this.toData(); + PropertyDescriptor[] extraEditor = provider.createPropertyDescriptor(this.data.getClass(), formProvider, elementCaseEditorProvider); + extraProperty = (CRPropertyDescriptor[]) ArrayUtils.addAll(extraProperty, extraEditor); + } + return extraProperty; + } + + @Override + protected String getIconName() { + return "text_field_16.png"; + } + + /** + * 返回组件默认名 + * @return 组件类名(小写) + */ + public String createDefaultName() { + return "report"; + } + + @Override + protected JComponent initEditor() { + if (editor == null) { + setBorder(DEFALUTBORDER); + editor = new JPanel(); + editor.setBackground(null); + editor.setLayout(null); + imageLable = initImageBackground(); + + coverPanel = new CoverReportPane(); + coverPanel.setPreferredSize(imageLable.getPreferredSize()); + coverPanel.setBounds(imageLable.getBounds()); + + editor.add(coverPanel); + coverPanel.setVisible(false); + editor.add(imageLable); + } + return editor; + } + + /** + * 从data中获取到图片背景, 并设置到Label上 + */ + private UILabel initImageBackground() { + UILabel imageLable = new UILabel(); + BufferedImage image = toData().getECImage(); + if (image == null) { + image = DEFAULT_BACKGROUND; + } + setLabelBackground(image, imageLable); + + return imageLable; + } + + /** + * 设置指定Label的背景 + */ + private void setLabelBackground(Image image, UILabel imageLable) { + ImageIcon icon = new ImageIcon(image); + imageLable.setIcon(icon); + imageLable.setOpaque(true); + imageLable.setLayout(null); + imageLable.setBounds(0, 0, icon.getIconWidth(), icon.getIconHeight()); + } + + @Override + public void paintBorder(Graphics g, Rectangle bounds) { + if (!isHovering) { + super.paintBorder(g, bounds); + } + } + + + /** + * 初始化大小 + * @return 尺寸 + */ + public Dimension initEditorSize() { + return BORDER_PREFERRED_SIZE; + } + + /** + * 是否是报表块 + * @return 是 + */ + public boolean isReport() { + return true; + } + + /** + * 该组件是否可以拖入参数面板 + * @return 是则返回true + */ + public boolean canEnterIntoParaPane() { + return false; + } + + /** + * 返回报表块对应的widget + * @return 返回ElementCaseEditor + */ + public ElementCaseEditor toData() { + return ((ElementCaseEditor) data); + } + + public FormElementCaseProvider getElementCase() { + return toData().getElementCase(); + } + + public String getElementCaseContainerName() { + return toData().getWidgetName(); + } + + public void setElementCase(FormElementCaseProvider el) { + toData().setElementCase(el); + } + + public void setBackground(BufferedImage image) { + toData().getElementCaseImage().adjustImageBytes(image); + setEditorIcon(toData().getECImage() == null ? DEFAULT_BACKGROUND : toData().getECImage()); + } + + public void updateECImage() { + XElementCase self = this; + self.toData().getElementCaseImage().updateImage(() -> { + self.setEditorIcon(self.toData().getECImage() == null ? DEFAULT_BACKGROUND : self.toData().getECImage()); + if (self.designer != null) { + self.designer.repaint(); + } + }); + } + + + private void setEditorIcon(BufferedImage image) { + setLabelBackground(image, imageLable); + } + + public Dimension getSize() { + return new Dimension(this.getWidth(), this.getHeight()); + } + + /** + * 响应点击事件 + * @param editingMouseListener 事件处理器 + * @param e 点击事件 + */ + public void respondClick(EditingMouseListener editingMouseListener, MouseEvent e) { + super.respondClick(editingMouseListener, e); + editingMouseListener.refreshTopXCreator(); + if (this.isShareConfigButtonFocus()) { + CoverReportPane.showShareConfig(((XCreator) this.getParent()).toData()); + } else { + switchTab(e, editingMouseListener); + } + } + + + private void switchTab(MouseEvent e, EditingMouseListener editingMouseListener) { + FormDesigner designer = editingMouseListener.getDesigner(); + if (e.getButton() == MouseEvent.BUTTON1 && + (e.getClickCount() == 2 || designer.getCursor().getType() == Cursor.HAND_CURSOR)) { + FormElementCaseContainerProvider component = (FormElementCaseContainerProvider) designer.getComponentAt(e); + //切换设计器 + designer.switchTab(component); + } + } + + @Override + public WidgetPropertyUIProvider[] getWidgetPropertyUIProviders() { + return new WidgetPropertyUIProvider[]{new ElementCasePropertyUI(this)}; + } + + /** + * data属性改变触发其他操作 + * + */ + public void firePropertyChange() { + initStyle(); + } + + /** + * 是否支持设置可用 + * return boolean + */ + public boolean supportSetEnable() { + return false; + } + + /** + * 是否支持共享-现只支持报表块、图表、tab块、绝对布局 + * @return + */ + public boolean isSupportShared() { + return true; + } } diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XWAbsoluteLayout.java b/designer-form/src/main/java/com/fr/design/designer/creator/XWAbsoluteLayout.java index da268b0e6..32273ca08 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XWAbsoluteLayout.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XWAbsoluteLayout.java @@ -4,8 +4,6 @@ package com.fr.design.designer.creator; import com.fr.base.GraphHelper; -import com.fr.base.iofile.attr.SharableAttrMark; -import com.fr.design.constants.UIConstants; import com.fr.design.designer.beans.AdapterBus; import com.fr.design.designer.beans.ComponentAdapter; import com.fr.design.designer.beans.LayoutAdapter; @@ -16,14 +14,11 @@ import com.fr.design.designer.creator.cardlayout.XWTabFitLayout; import com.fr.design.designer.properties.mobile.MobileBooKMarkUsePropertyUI; import com.fr.design.form.layout.FRAbsoluteLayout; import com.fr.design.form.util.FormDesignerUtils; -import com.fr.design.form.util.XCreatorConstants; import com.fr.design.fun.WidgetPropertyUIProvider; -import com.fr.design.icon.IconPathConstants; -import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.CoverReportPane; import com.fr.design.mainframe.EditingMouseListener; import com.fr.design.mainframe.FormArea; import com.fr.design.mainframe.FormDesigner; -import com.fr.design.mainframe.WidgetHelpDialog; import com.fr.design.mainframe.WidgetPropertyPane; import com.fr.form.ui.Connector; import com.fr.form.ui.Widget; @@ -31,26 +26,17 @@ import com.fr.form.ui.container.WAbsoluteLayout; import com.fr.form.ui.container.WAbsoluteLayout.BoundsWidget; import com.fr.form.ui.container.WLayout; import com.fr.general.FRScreen; -import com.fr.general.IOUtils; - -import com.fr.share.ShareConstants; import com.fr.stable.AssistUtils; import com.fr.stable.Constants; -import javax.swing.Icon; -import java.awt.AlphaComposite; import java.awt.Color; -import java.awt.Composite; import java.awt.Cursor; import java.awt.Dimension; import java.awt.Graphics; -import java.awt.Graphics2D; import java.awt.Rectangle; -import java.awt.RenderingHints; import java.awt.Toolkit; import java.awt.event.ContainerEvent; import java.awt.event.MouseEvent; -import java.awt.image.BufferedImage; import java.beans.IntrospectionException; import java.util.ArrayList; import java.util.HashMap; @@ -61,20 +47,14 @@ import java.util.HashMap; */ public class XWAbsoluteLayout extends XLayoutContainer { - private static final int EDIT_BTN_WIDTH = 75; - private static final int EDIT_BTN_HEIGHT = 20; private int minWidth = WLayout.MIN_WIDTH; private int minHeight = WLayout.MIN_HEIGHT; private static final Color OUTER_BORDER_COLOR = new Color(65, 155, 249, 30); private static final Color INNER_BORDER_COLOR = new Color(65, 155, 249); - private static final int BORDER_WIDTH = 1; - private Icon controlMode = IOUtils.readIcon(IconPathConstants.TD_EL_SHARE_HELP_ICON_PATH); //由于屏幕分辨率不同,界面上的容器大小可能不是默认的100%,此时拖入组件时,保存的大小按照100%时的计算 protected double containerPercent = 1.0; - private boolean isHovering = false; - private HashMap xConnectorMap; public XWAbsoluteLayout() { @@ -462,52 +442,10 @@ public class XWAbsoluteLayout extends XLayoutContainer { super.paint(g); //如果鼠标移动到布局内且布局不可编辑,画出编辑蒙层 if (isMouseEnter && !this.editable) { - int x = 0; - int y = 0; - int w = getWidth(); - int h = getHeight(); - - Graphics2D g2d = (Graphics2D) g; - Composite oldComposite = g2d.getComposite(); - //画白色的编辑层 - g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 50 / 100.0F)); - g2d.setColor(XCreatorConstants.COVER_COLOR); - g2d.fillRect(x, y, w, h); - //画编辑按钮所在框 - FormDesigner formDesigner = WidgetPropertyPane.getInstance().getEditingFormDesigner(); - AlphaComposite alphaComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, formDesigner.getCursor().getType() != Cursor.DEFAULT_CURSOR ? 0.9f : 0.7f); - g2d.setColor(XCreatorConstants.EDIT_COLOR); - g2d.setComposite(alphaComposite); - g2d.fillRoundRect((x + w / 2 - EDIT_BTN_WIDTH / 2), (y + h / 2 - EDIT_BTN_HEIGHT / 2), EDIT_BTN_WIDTH, EDIT_BTN_HEIGHT, 4, 4); - g2d.setComposite(oldComposite); - //画编辑按钮图标 - BufferedImage image = IOUtils.readImage(IconPathConstants.EDIT_ICON_PATH); - g2d.drawImage( - image, - (x + w / 2 - 23), - (y + h / 2 - image.getHeight() / 2), - image.getWidth(), - image.getHeight(), - null, - this - ); - g2d.setColor(Color.WHITE); - //画编辑文字 - g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - g2d.drawString(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Edit"), x + w / 2 - 2, y + h / 2 + 5); - g.setColor(XCreatorConstants.FORM_BORDER_COLOR); - GraphHelper.draw(g, new Rectangle(BORDER_WIDTH, BORDER_WIDTH, getWidth() - BORDER_WIDTH * 2, getHeight() - BORDER_WIDTH * 2), Constants.LINE_MEDIUM); - paintExtro(g); - } - } - - public void paintExtro(Graphics g) { - if (this.toData().getWidgetAttrMark(SharableAttrMark.XML_TAG) != null) { - int width = getWidth() - ShareConstants.SHARE_EL_CONTROL_BUTTON_HW; - g.setColor(UIConstants.NORMAL_BACKGROUND); - g.fillArc(width, 0, ShareConstants.SHARE_EL_CONTROL_BUTTON_HW, ShareConstants.SHARE_EL_CONTROL_BUTTON_HW, - 0, 360); - controlMode.paintIcon(this, g, width, 0); + CoverReportPane.paintEditButton(g, this); + if (isShared()) { + CoverReportPane.paintShareButton(g, this); + } } } @@ -529,9 +467,8 @@ public class XWAbsoluteLayout extends XLayoutContainer { * @param e 鼠标点击事件 */ public void respondClick(EditingMouseListener editingMouseListener, MouseEvent e) { - //帮助弹窗 - if (this.isHelpBtnOnFocus()) { - new WidgetHelpDialog(DesignerContext.getDesignerFrame(), this.toData().getDescription()).showWindow(e); + if (this.isShareConfigButtonFocus()) { + CoverReportPane.showShareConfig(this.toData()); return; } FormDesigner designer = editingMouseListener.getDesigner(); diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XWFitLayout.java b/designer-form/src/main/java/com/fr/design/designer/creator/XWFitLayout.java index 6d55c658f..6d7aa5d9f 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XWFitLayout.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XWFitLayout.java @@ -121,7 +121,7 @@ public class XWFitLayout extends XLayoutContainer { * 更新组件的backupBound * 拖动滑块改变容器大小,改变的是界面显示大小,更新bound,再次拖入或拉伸边框用到 */ - private void updateCreatorsBackupBound() { + public void updateCreatorsBackupBound() { for (int i=0,size=this.getComponentCount(); i nameEdListMap = new HashMap<>(); + + private CommonShortCutHandlers commonHandlers; + + private ListControlPaneHelper helper; + + private JPanel contentPane; + + private FormDesigner designer; + + + private ListControlPaneHelper getHelper() { + if (helper == null) { + helper = ListControlPaneHelper.newInstance(this); + } + return helper; + } + + private CommonShortCutHandlers getCommonHandlers() { + if (commonHandlers == null) { + commonHandlers = CommonShortCutHandlers.newInstance(this); + } + return commonHandlers; + } + + + public EventPropertyPane(FormDesigner designer) { + super(); + this.designer = designer; + } + + + @Override + protected void initLeftPane(JPanel leftPane) { + leftPane.add(new UIScrollPane(contentPane = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, FlowLayout.LEADING, 0, 0)), BorderLayout.CENTER); + } + + /** + * 刷新 + */ + public void refresh() { + int selectionSize = designer.getSelectionModel().getSelection().size(); + if (selectionSize == 0 || selectionSize == 1) { + this.creator = selectionSize == 0 ? designer.getRootComponent() : designer.getSelectionModel() + .getSelection().getSelectedCreator(); + } else { + this.creator = null; + contentPane.removeAll(); + checkButtonEnabled(); + return; + } + Widget widget = creator.toData(); + + refreshContentPane(widget.supportedEvents()); + refreshNameableCreator(EventCreator.createEventCreator(widget.supportedEvents(), EventPropertyTable.WidgetEventListenerUpdatePane.class)); + populateNameObjects(); + } + + + private void refreshContentPane(String[] supportedEvents) { + for (String event : supportedEvents) { + if (nameEdListMap.containsKey(event)) { + continue; + } + UINameEdList list = createJNameList(event); + EventListWrapperPane wrapperPane = new EventListWrapperPane(switchLang(event), list); + if (this.selectNameEdList == null) { + this.selectNameEdList = wrapperPane.getNameEdList(); + } + contentPane.add(wrapperPane); + nameEdListMap.put(event, wrapperPane); + } + } + + public void populateNameObjects() { + Widget widget = creator.toData(); + + ArrayList nameObjectList = new ArrayList<>(); + for (int i = 0, size = widget.getListenerSize(); i < size; i++) { + Listener listener = widget.getListener(i); + if (!listener.isDefault()) { + nameObjectList.add(i, new NameObject(switchLang(listener.getEventName()) + (i + 1), listener)); + } + } + populate(getHelper().processCatalog(nameObjectList)); + checkButtonEnabled(); + this.repaint(); + } + + public void populate(Map> map) { + isPopulating = true; // 加一个标识位,避免切换单元格时,触发 saveSettings + Iterator>> iterator = map.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry> entry = iterator.next(); + List valueList = entry.getValue(); + EventListWrapperPane eventListWrapperPane = nameEdListMap.get(entry.getKey()); + populateChildNameList(eventListWrapperPane.getNameEdList(), valueList.toArray(new NameObject[valueList.size()])); + } + this.checkButtonEnabled(); + refreshEventListWrapperPane(); + isPopulating = false; + } + + private void refreshEventListWrapperPane() { + Iterator> iterator = nameEdListMap.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry entry = iterator.next(); + EventListWrapperPane eventListWrapperPane = entry.getValue(); + UINameEdList nameEdList = eventListWrapperPane.getNameEdList(); + int listSize = nameEdList.getModel().getSize(); + if (this.selectNameEdList.getModel().getSize() == 0 && listSize > 0) { + this.selectNameEdList = nameEdList; + } + eventListWrapperPane.setVisible(listSize > 0); + } + if (this.selectNameEdList != null) { + this.selectNameEdList.setSelectedIndex(0); + } + this.repaint(); + } + + + private void populateChildNameList(UINameEdList nameableList, Nameable[] nameableArray) { + nameableList.getCellEditor().stopCellEditing(); + DefaultListModel listModel = (DefaultListModel) nameableList.getModel(); + listModel.removeAllElements(); + if (ArrayUtils.isEmpty(nameableArray)) { + isPopulating = false; + return; + } + + listModel.setSize(nameableArray.length); + for (int i = 0; i < nameableArray.length; i++) { + listModel.set(i, new ListModelElement(nameableArray[i])); + } + + } + + + protected UINameEdList createJNameList(String text) { + UINameEdList nameEdList = new UINameEdList(new DefaultListModel()) { + @Override + protected void doAfterLostFocus() { + ((JControlUpdatePane) controlUpdatePane).update(); + } + + @Override + protected void doAfterStopEditing() { + saveSettings(); + } + }; + + nameEdList.setCellRenderer(new UINameableListCellRenderer(true, this.creators)); + nameEdList.setName(text); + nameEdList.setSelectionBackground(UIConstants.ATTRIBUTE_PRESS); + nameEdList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); + nameEdList.addMouseListener(new MouseAdapter() { + @Override + public void mouseReleased(MouseEvent e) { + selectNameEdList = nameEdList; + updateUINameListSelect(); + } + }); + nameEdList.addMouseListener(getHelper().getListMouseListener(nameEdList, this)); + nameEdList.addModNameActionListener(new ModNameActionListener() { + @Override + public void nameModed(int index, String oldName, String newName) { + saveSettings(); + } + }); + nameEdList.addListSelectionListener(new ListSelectionListener() { + public void valueChanged(ListSelectionEvent evt) { + // richie:避免多次update和populate大大降低效率 + if (!evt.getValueIsAdjusting()) { + // shoc 切换的时候加检验 + if (hasInvalid(false)) { + return; + } + ((JControlUpdatePane) EventPropertyPane.this.controlUpdatePane).update(); + ((JControlUpdatePane) EventPropertyPane.this.controlUpdatePane).populate(); + EventPropertyPane.this.checkButtonEnabled(); + } + } + }); + nameEdList.getModel().addListDataListener(new ListDataListener() { + @Override + public void intervalAdded(ListDataEvent e) { + saveSettings(); + } + + @Override + public void intervalRemoved(ListDataEvent e) { + saveSettings(); + } + + @Override + public void contentsChanged(ListDataEvent e) { + saveSettings(); + } + }); + return nameEdList; + } + + private void updateUINameListSelect() { + Iterator> iterator = nameEdListMap.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry entry = iterator.next(); + UINameEdList nameEdList = entry.getValue().getNameEdList(); + if (nameEdList != selectNameEdList) { + nameEdList.clearSelection(); + } + } + } + + @Override + public void checkButtonEnabled() { + getHelper().checkButtonEnabled(); + } + + + + private String switchLang(String eventName) { + // 在 properties 文件中找到相应的 key 值 + String localeKey = ReportEngineEventMapping.getLocaleName(eventName); + return com.fr.design.i18n.Toolkit.i18nText(localeKey); + } + + /** + * 更新控件事件 + * + * @param creator 控件 + */ + public void updateWidgetListener(XCreator creator) { + (creator.toData()).clearListeners(); + Nameable[] res = this.update(); + for (int i = 0; i < res.length; i++) { + NameObject nameObject = (NameObject) res[i]; + (creator.toData()).addListener((Listener) nameObject.getObject()); + } + + designer.fireTargetModified(); + checkButtonEnabled(); + } + + + /** + * 生成不重复的名字 + * + * @param prefix 名字前缀 + * @return 名字 + */ + @Override + public String createUnrepeatedName(String prefix) { + return getCommonHandlers().createUnrepeatedName(prefix); + } + + private void updateSelectedNameList(NameableCreator creator) { + String eventName = ((EventCreator) creator).getEventName(); + EventListWrapperPane wrapperPane = nameEdListMap.get(eventName); + wrapperPane.setVisible(true); + setSelectNameEdList(wrapperPane.getNameEdList()); + } + + private void setSelectNameEdList(UINameEdList nameEdList) { + if (this.selectNameEdList != null) { + this.selectNameEdList.clearSelection(); + } + this.selectNameEdList = nameEdList; + } + + @Override + public void onAddItem(NameableCreator creator) { + updateSelectedNameList(creator); + getCommonHandlers().onAddItem(creator); + } + + @Override + public void onRemoveItem() { + getCommonHandlers().onRemoveItem(); + refreshEventListWrapperPane(); + } + + @Override + public void onCopyItem() { + getCommonHandlers().onCopyItem(); + } + + @Override + public void onMoveUpItem() { + getCommonHandlers().onMoveUpItem(); + } + + @Override + public void onMoveDownItem() { + getCommonHandlers().onMoveDownItem(); + } + + @Override + public void onSortItem(boolean isAtoZ) { + Iterator> iterator = nameEdListMap.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry entry = iterator.next(); + UINameEdList nameEdList = entry.getValue().getNameEdList(); + getCommonHandlers().onSortItem(isAtoZ, nameEdList); + } + + } + + @Override + public boolean isItemSelected() { + return getModel().getSize() > 0 && getSelectedIndex() != -1; + } + + + @Override + protected JPanel createControlUpdatePane() { + return JControlUpdatePane.newInstance(this); + } + + + @Override + public Nameable[] update() { + java.util.List res = new java.util.ArrayList(); + getControlUpdatePane().update(); + Iterator> iterator = nameEdListMap.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry entry = iterator.next(); + UINameEdList nameEdList = entry.getValue().getNameEdList(); + DefaultListModel listModel = (DefaultListModel) nameEdList.getModel(); + for (int i = 0, len = listModel.getSize(); i < len; i++) { + res.add(((ListModelElement) listModel.getElementAt(i)).wrapper); + } + } + return res.toArray(new Nameable[0]); + } + + + @Override + public NameableCreator[] createNameableCreators() { + return new NameableCreator[]{ + new EventCreator(Widget.EVENT_STATECHANGE, EventPropertyTable.WidgetEventListenerUpdatePane.class) + }; + } + + @Override + public void saveSettings() { + if (isPopulating) { + return; + } + updateWidgetListener(creator); + } + + @Override + protected String title4PopupWindow() { + return "Event"; + } + + @Override + public String getAddItemText() { + return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Add_Event"); + } + + public BasicBeanPane createPaneByCreators(NameableCreator creator) { + try { + return creator.getUpdatePane().newInstance(); + } catch (InstantiationException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + } + + public BasicBeanPane createPaneByCreators(NameableCreator creator, String string) { + Constructor constructor = null; + try { + constructor = creator.getUpdatePane().getDeclaredConstructor(new Class[]{String.class}); + constructor.setAccessible(true); + return (BasicBeanPane) constructor.newInstance(string); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } catch (InstantiationException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } catch (InvocationTargetException e) { + throw new RuntimeException(e); + } + } + + @Override + public DefaultListModel getModel() { + if (this.selectNameEdList == null) { + return new DefaultListModel(); + } + return (DefaultListModel) this.selectNameEdList.getModel(); + } + + /** + * 检查是否符合规范 + * + * @throws Exception + */ + @Override + public void checkValid() throws Exception { + ((JControlUpdatePane) this.controlUpdatePane).checkValid(); + } + + @Override + public boolean hasInvalid(boolean isAdd) { + return getHelper().hasInvalid(isAdd); + } + + public void addNameable(Nameable nameable, int index) { + getHelper().addNameable(nameable, index); + popupEditDialog(); + } + + + /** + * 设置选中项 + * + * @param index 选中项的序列号 + */ + public void setSelectedIndex(int index) { + if (this.selectNameEdList != null) { + this.selectNameEdList.setSelectedIndex(index); + + } + } + + @Override + public int getSelectedIndex() { + if (this.selectNameEdList == null) { + return -1; + } + return this.selectNameEdList.getSelectedIndex(); + } + + + @Override + public ListModelElement getSelectedValue() { + if (this.selectNameEdList == null) { + return null; + } + return (ListModelElement) this.selectNameEdList.getSelectedValue(); + } + + @Override + public JControlUpdatePane getControlUpdatePane() { + return (JControlUpdatePane) controlUpdatePane; + } + + @Override + public JNameEdList getNameableList() { + return this.selectNameEdList; + } + + private void popupEditDialog() { + getHelper().popupEditDialog(null, this.selectNameEdList, this); + } + + + private class EventListWrapperPane extends JPanel { + private UINameEdList nameEdList; + + public EventListWrapperPane(String labelText, UINameEdList nameEdList) { + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + UILabel label = new UILabel(labelText + Toolkit.i18nText("Fine-Design_Report_Event")); + label.setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 0)); + label.setBackground(Color.decode("#FFFFFF")); + label.setPreferredSize(new Dimension(226, 26)); + this.nameEdList = nameEdList; + this.add(label, BorderLayout.NORTH); + this.add(this.nameEdList, BorderLayout.CENTER); + } + + public UINameEdList getNameEdList() { + return this.nameEdList; + } + + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/CoverPane.java b/designer-form/src/main/java/com/fr/design/mainframe/CoverPane.java index a4c401440..f63c43055 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/CoverPane.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/CoverPane.java @@ -13,13 +13,12 @@ import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Component; import java.awt.Composite; -import java.awt.Container; import java.awt.Cursor; -import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; -import java.awt.LayoutManager; import java.awt.Rectangle; +import java.awt.RenderingHints; +import java.awt.image.BufferedImage; /** @@ -29,29 +28,52 @@ import java.awt.Rectangle; * Time: 上午9:09 */ public class CoverPane extends JComponent { - - private UIButton editButton; private AlphaComposite composite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f); - private static final int BORDER_WIDTH = 2; - private static final Color COVER_COLOR = new Color(216, 242, 253); - private static final int EDIT_BTN_WIDTH = 75; - private static final int EDIT_BTN_HEIGHT = 20; + protected static final int BORDER_WIDTH = 2; + public static final int EDIT_BTN_W = 75; + public static final int EDIT_BTN_H = 20; + + public static void paintEditButton(Graphics g, Component component) { + int x = 0; + int y = 0; + int w = component.getWidth(); + int h = component.getHeight(); + + Graphics2D g2d = (Graphics2D) g; + Composite oldComposite = g2d.getComposite(); + //画白色的编辑层 + g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 50 / 100.0F)); + g2d.setColor(XCreatorConstants.COVER_COLOR); + g2d.fillRect(x, y, w, h); + //画编辑按钮所在框 + FormDesigner formDesigner = WidgetPropertyPane.getInstance().getEditingFormDesigner(); + AlphaComposite alphaComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, formDesigner.getCursor().getType() != Cursor.DEFAULT_CURSOR ? 0.9f : 0.7f); + g2d.setColor(XCreatorConstants.EDIT_COLOR); + g2d.setComposite(alphaComposite); + g2d.fillRoundRect((x + w / 2 - EDIT_BTN_W / 2), (y + h / 2 - EDIT_BTN_H / 2), EDIT_BTN_W, EDIT_BTN_H, 4, 4); + g2d.setComposite(oldComposite); + //画编辑按钮图标 + BufferedImage image = IOUtils.readImage(IconPathConstants.EDIT_ICON_PATH); + g2d.drawImage( + image, + (x + w / 2 - 23), + (y + h / 2 - image.getHeight() / 2), + image.getWidth(), + image.getHeight(), + null + ); + g2d.setColor(Color.WHITE); + //画编辑文字 + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2d.drawString(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Edit"), x + w / 2 - 2, y + h / 2 + 5); + + g.setColor(XCreatorConstants.FORM_BORDER_COLOR); + GraphHelper.draw(g, new Rectangle(BORDER_WIDTH, BORDER_WIDTH, w - BORDER_WIDTH * 2, h - BORDER_WIDTH * 2), Constants.LINE_MEDIUM); + } public CoverPane() { - setLayout(getCoverLayout()); setBackground(null); setOpaque(false); - - editButton = new UIButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Edit"), IOUtils.readIcon(IconPathConstants.EDIT_ICON_PATH)) { - @Override - public Dimension getPreferredSize() { - return new Dimension(60, 24); - } - }; - editButton.setBorderPainted(false); - editButton.setExtraPainted(false); - editButton.setForeground(Color.WHITE); - add(editButton); } public AlphaComposite getComposite() { @@ -62,72 +84,9 @@ public class CoverPane extends JComponent { this.composite = composite; } - public UIButton getEditButton() { - return editButton; - } - - public void setEditButton(UIButton editButton) { - this.editButton = editButton; - } - - protected LayoutManager getCoverLayout() { - return new LayoutManager() { - - @Override - public void removeLayoutComponent(Component comp) { - } - - @Override - public Dimension preferredLayoutSize(Container parent) { - return parent.getPreferredSize(); - } - - @Override - public Dimension minimumLayoutSize(Container parent) { - return null; - } - - @Override - public void layoutContainer(Container parent) { - int width = parent.getParent().getWidth(); - int height = parent.getParent().getHeight(); - int preferWidth = editButton.getPreferredSize().width; - int preferHeight = editButton.getPreferredSize().height; - editButton.setBounds((width - preferWidth) / 2, (height - preferHeight) / 2, preferWidth, preferHeight); - } - - @Override - public void addLayoutComponent(String name, Component comp) { - } - }; - } - public void paint(Graphics g) { - int x = 0; - int y = 0; - int w = getWidth(); - int h = getHeight(); - Graphics2D g2d = (Graphics2D) g; - Composite oldComposite = g2d.getComposite(); - g2d.setComposite(composite); - g2d.setColor(COVER_COLOR); - g2d.fillRect(0, 0, getWidth(), getHeight()); - FormDesigner formDesigner = WidgetPropertyPane.getInstance().getEditingFormDesigner(); - g2d.setColor(XCreatorConstants.EDIT_COLOR); - boolean editHover = formDesigner.getCursor().getType() != Cursor.DEFAULT_CURSOR; - AlphaComposite alphaComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, editHover ? 0.9f : 0.7f); - g2d.setComposite(alphaComposite); - g2d.fillRoundRect((x + w / 2 - EDIT_BTN_WIDTH / 2), (y + h / 2 - EDIT_BTN_HEIGHT / 2), EDIT_BTN_WIDTH, EDIT_BTN_HEIGHT, 4, 4); - g2d.setComposite(oldComposite); - g.setColor(XCreatorConstants.FORM_BORDER_COLOR); - GraphHelper.draw(g, getPaintBorderBounds(), Constants.LINE_MEDIUM); - - super.paint(g); - } - - protected Rectangle getPaintBorderBounds(){ - return new Rectangle(BORDER_WIDTH, BORDER_WIDTH, getWidth() - BORDER_WIDTH * 2 , getHeight() - BORDER_WIDTH * 2); + paintEditButton(g, this); } } diff --git a/designer-form/src/main/java/com/fr/design/mainframe/CoverReportPane.java b/designer-form/src/main/java/com/fr/design/mainframe/CoverReportPane.java index d976691c6..14b8aed7a 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/CoverReportPane.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/CoverReportPane.java @@ -1,18 +1,20 @@ package com.fr.design.mainframe; -import com.fr.design.constants.UIConstants; -import com.fr.design.gui.ibutton.UIButton; -import com.fr.design.icon.IconPathConstants; -import com.fr.share.ShareConstants; -import com.fr.general.FRScreen; -import com.fr.general.IOUtils; -import com.fr.stable.StringUtils; - -import javax.swing.*; -import java.awt.*; -import java.awt.event.MouseEvent; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; +import com.fr.base.BaseUtils; +import com.fr.design.dialog.BasicPane; +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.share.constants.ShareEntryKey; +import com.fr.form.ui.Widget; +import com.fr.stable.Constants; +import com.fr.stable.bridge.StableFactory; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.image.BufferedImage; +import java.util.HashMap; /** * 报表块的封面(如果后面所有的组件都有帮助信息的话就抽接口吧) @@ -20,123 +22,61 @@ import java.awt.event.WindowEvent; * Date: 2016/11/2 * Time: 11:32 */ -public class CoverReportPane extends CoverPane implements HelpDialogHandler{ - private static final int BORDER_WIDTH = 1; - private Icon controlMode = IOUtils.readIcon(IconPathConstants.TD_EL_SHARE_HELP_ICON_PATH); - private JComponent controlButton = new JComponent() { - protected void paintComponent(Graphics g) { - g.setColor(UIConstants.NORMAL_BACKGROUND); - g.fillArc(0, 0, ShareConstants.SHARE_EL_CONTROL_BUTTON_HW, ShareConstants.SHARE_EL_CONTROL_BUTTON_HW, - 0, 360); - controlMode.paintIcon(this, g, 0, 0); - } - }; - - - private String helpMsg;//帮助信息(后续帮助信息可能会变成标配,就直接放这边了) - - private WidgetHelpDialog helpDialog = null; - - public CoverReportPane() { - this(StringUtils.EMPTY); - } - - public CoverReportPane(String helpMsg) { - super(); - this.helpMsg = helpMsg; +public class CoverReportPane extends CoverPane{ + public static final int SHARE_CONF_BTN_W = 90; + public static final int SHARE_CONF_BTN_H = 24; + + public static final Color SHARE_BTN_BG = new Color(152, 193, 250); + + public static void showShareConfig(Widget widget) { + Object[] compositeArg = new Object[]{widget}; + HashMap compoClass = new HashMap(); + compoClass.put(Constants.ARG_0, Widget.class); + BasicPane shareGuidePane = StableFactory.getMarkedInstanceObjectFromClass(ShareEntryKey.SHARE_CONFIG, compositeArg, compoClass, BasicPane.class); + shareGuidePane.show(); } - public String getHelpMsg() { - return helpMsg; + public static void paintShareButton(Graphics g, Component component) { + int x = component.getWidth() - SHARE_CONF_BTN_W; + int y = 0; + + Graphics2D g2d = (Graphics2D) g; + g2d.setColor(SHARE_BTN_BG); + g2d.fillRoundRect(x ,y, SHARE_CONF_BTN_W, SHARE_CONF_BTN_H,5,5); + g2d.setColor(Color.WHITE); + + // 画配置文字 + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2d.drawString(Toolkit.i18nText("Fine-Design_Share_Help_Settings"),x + 30, 17); + // 画图标 + BufferedImage image = BaseUtils.readImage("com/fr/base/images/share/config.png"); + g2d.drawImage(image, x + 10, 5, image.getWidth(), image.getHeight(), null); } - public void setHelpMsg(String helpMsg) { - this.helpMsg = helpMsg; - //帮助信息为空就不显示帮助按钮 - if (StringUtils.isNotEmpty(helpMsg)) { - add(controlButton); - } - } + private boolean isShared = false; - public void setMsgDisplay(MouseEvent e) { - if (helpDialog == null) { -// controlMode = IOUtils.readIcon(IconPathConstants.TD_EL_SHARE_CLOSE_ICON_PATH); - controlButton.setVisible(false); - helpDialog = new WidgetHelpDialog(DesignerContext.getDesignerFrame(), helpMsg); - double screenValue = FRScreen.getDesignScreenByDimension(Toolkit.getDefaultToolkit().getScreenSize()).getValue(); - int offsetX = 0; - if (screenValue < FormArea.DEFAULT_SLIDER) { - offsetX = (int) ((1 - screenValue / FormArea.DEFAULT_SLIDER) - * WidgetPropertyPane.getInstance().getEditingFormDesigner().getRootComponent().getWidth() / 2); - } - int rX = WestRegionContainerPane.getInstance().getWidth() + e.getX() + offsetX - 227;//弹出框宽度190加上图标的宽度27加上10的偏移 - int rY = 165 + e.getY();//165是设计器最上面几个面板的高度 - helpDialog.setLocationRelativeTo(DesignerContext.getDesignerFrame(), rX, rY); - helpDialog.showWindow(); - helpDialog.addWindowListener(new WindowAdapter() { - @Override - public void windowClosed(WindowEvent e) { - helpDialog = null; - controlButton.setVisible(true); - } - }); - HelpDialogManager.getInstance().setPane(this); - } + public CoverReportPane() { + this(false); } - protected LayoutManager getCoverLayout() { - return new LayoutManager() { - - @Override - public void removeLayoutComponent(Component comp) { - } - - @Override - public Dimension preferredLayoutSize(Container parent) { - return parent.getPreferredSize(); - } - - @Override - public Dimension minimumLayoutSize(Container parent) { - return null; - } - - @Override - public void layoutContainer(Container parent) { - UIButton editButton = getEditButton(); - int width = parent.getParent().getWidth(); - int height = parent.getParent().getHeight(); - int preferWidth = editButton.getPreferredSize().width; - int preferHeight = editButton.getPreferredSize().height; - editButton.setBounds((width - preferWidth) / 2, (height - preferHeight) / 2, preferWidth, preferHeight); - controlButton.setBounds((width - 28), 0, 27, 27); - } - - @Override - public void addLayoutComponent(String name, Component comp) { - } - }; + public CoverReportPane(boolean shared) { + super(); + isShared = shared; } - public void destroyHelpDialog() { - if (helpDialog != null) { - controlMode = IOUtils.readIcon(IconPathConstants.TD_EL_SHARE_HELP_ICON_PATH); - controlButton.repaint(); - helpDialog.dispose(); - helpDialog = null; - } + public boolean isShared() { + return isShared; } - @Override - protected Rectangle getPaintBorderBounds(){ - return new Rectangle(BORDER_WIDTH, BORDER_WIDTH, getWidth() - 3 * BORDER_WIDTH , getHeight() - 3 * BORDER_WIDTH); + public void setShared(boolean shared) { + isShared = shared; } @Override - public void setVisible(boolean aFlag) { - super.setVisible(aFlag); -// if (aFlag) { -// HelpDialogManager.getInstance().setPane(this); -// } + public void paint(Graphics g) { + super.paint(g); + if (isShared()) { + paintShareButton(g, this); + } } } diff --git a/designer-form/src/main/java/com/fr/design/mainframe/EditingMouseListener.java b/designer-form/src/main/java/com/fr/design/mainframe/EditingMouseListener.java index 524dd8bf1..fd1236091 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/EditingMouseListener.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/EditingMouseListener.java @@ -11,6 +11,7 @@ import com.fr.design.designer.beans.location.Direction; import com.fr.design.designer.beans.location.Location; import com.fr.design.designer.beans.models.SelectionModel; import com.fr.design.designer.beans.models.StateModel; +import com.fr.design.designer.creator.XBorderStyleWidgetCreator; import com.fr.design.designer.creator.XChartEditor; import com.fr.design.designer.creator.XCreator; import com.fr.design.designer.creator.XCreatorUtils; @@ -28,9 +29,7 @@ import com.fr.design.icon.IconPathConstants; import com.fr.design.utils.ComponentUtils; import com.fr.design.utils.gui.GUICoreUtils; import com.fr.design.utils.gui.LayoutUtils; -import com.fr.share.ShareConstants; import com.fr.stable.Constants; -import com.fr.stable.StringUtils; import javax.swing.BorderFactory; import javax.swing.JComponent; @@ -41,6 +40,7 @@ import javax.swing.event.MouseInputAdapter; import java.awt.Color; import java.awt.Container; import java.awt.Cursor; +import java.awt.Insets; import java.awt.Rectangle; import java.awt.event.MouseEvent; @@ -106,10 +106,10 @@ public class EditingMouseListener extends MouseInputAdapter { private int minDragSize = 5; private int minMoveSize = 8; - private static final int EDIT_BTN_WIDTH = 60; - private static final int EDIT_BTN_HEIGHT = 24; + private static final Insets DEEFAULT_INSETS = new Insets(0,0,0,0); + //报表块的编辑按钮不灵敏,范围扩大一点 - private static final int GAP = 10; + private static final int GAP = 5; private XElementCase xElementCase; private XChartEditor xChartEditor; @@ -353,62 +353,48 @@ public class EditingMouseListener extends MouseInputAdapter { } - private void elementCaseMouseMoved(MouseEvent e, XCreator component) { - xElementCase = (XElementCase) component; - UIButton button = (UIButton) xElementCase.getCoverPane().getComponent(0); - if (designer.getCursor().getType() == Cursor.HAND_CURSOR) { - designer.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); - } // component.getParent() 是报表块所在的XWTitleLayout - int minX = button.getX() + getParentPositionX(component, 0) - designer.getHorizontalScaleValue(); - int minY = button.getY() + getParentPositionY(component, 0) - designer.getVerticalScaleValue() + xElementCase.getY(); - if (e.getX() + GAP - xElementCase.getInsets().left > minX && e.getX() - GAP - xElementCase.getInsets().left < minX + button.getWidth()) { - if (e.getY() + GAP - xElementCase.getInsets().top > minY && e.getY() - GAP - xElementCase.getInsets().top < minY + button.getHeight()) { - designer.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + private boolean isShareConfigButton(MouseEvent e, XCreator component, Insets insets) { + if (component.isShared()) { + int minX = getParentPositionX(component, component.getX()) + component.getWidth() - insets.right - CoverReportPane.SHARE_CONF_BTN_W - designer.getHorizontalScaleValue(); + int maxX = minX + CoverReportPane.SHARE_CONF_BTN_W; + int minY = getParentPositionY(component, component.getY()) + insets.top - designer.getVerticalScaleValue(); + int maxY = minY + CoverReportPane.SHARE_CONF_BTN_H; + + if ((e.getX() > minX - GAP) && e.getX() < maxX + GAP) { + if (e.getY() > minY - GAP && e.getY() < maxY + GAP) { + return true; + } } } - setHelpBtnFocus(e, xElementCase); + return false; } - private void setHelpBtnFocus(MouseEvent e, XCreator component) { - component.setHelpBtnOnFocus(false); - if (component.getCoverPane() != null) { - if (component.getCoverPane().getComponentCount() > 1) { - JComponent button1 = (JComponent) component.getCoverPane().getComponent(1); - int minX1 = button1.getX() + getParentPositionX(component, 0) - designer.getHorizontalScaleValue(); - int minY1 = button1.getY() + getParentPositionY(component, 0) - designer.getVerticalScaleValue() + component.getY(); - if (e.getX() + GAP - component.getInsets().left > minX1 && e.getX() - GAP - component.getInsets().left < minX1 + button1.getWidth()) { - if (e.getY() + GAP - component.getInsets().top > minY1 && e.getY() - GAP - component.getInsets().top < minY1 + button1.getHeight()) { - designer.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); - component.setHelpBtnOnFocus(true); - } - } - } - component.displayCoverPane(true); - component.setDirections(Direction.TOP_BOTTOM_LEFT_RIGHT); - } else { - //没有帮助信息时,不显示帮助图标 - if (StringUtils.isEmpty(component.toData().getDescription())) { - return; - } - int minX1 = getParentPositionX(component, component.getX()) + component.getWidth() - ShareConstants.SHARE_EL_CONTROL_BUTTON_HW - designer.getHorizontalScaleValue(); - int minY1 = getParentPositionY(component, component.getY()) - designer.getVerticalScaleValue(); - if (e.getX() + GAP - component.getInsets().left > minX1 && e.getX() - GAP - component.getInsets().left < minX1 + ShareConstants.SHARE_EL_CONTROL_BUTTON_HW) { - if (e.getY() + GAP - component.getInsets().top > minY1 && e.getY() - GAP - component.getInsets().top < minY1 + ShareConstants.SHARE_EL_CONTROL_BUTTON_HW) { - designer.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); - component.setHelpBtnOnFocus(true); - } + private boolean isEditButton(MouseEvent e, XCreator component, Insets insets) { + int innerWidth = component.getWidth() - insets.left - insets.right; + int innerHeight = component.getHeight() - insets.top - insets.bottom; + + int minX = getParentPositionX(component, component.getX()) + insets.left + (innerWidth - CoverReportPane.EDIT_BTN_W) / 2 - designer.getHorizontalScaleValue(); + int maxX = minX + CoverReportPane.EDIT_BTN_W; + int minY = getParentPositionY(component, component.getY()) + insets.top + (innerHeight - CoverReportPane.EDIT_BTN_H) / 2 - designer.getVerticalScaleValue(); + int maxY = minY + CoverReportPane.EDIT_BTN_H; + if (e.getX() > minX - GAP && e.getX() < maxX + GAP) { + if (e.getY() > minY - GAP && e.getY() < maxY + GAP) { + return true; } } + return false; } - private void setCoverPaneNotDisplay(XCreator component, MouseEvent e, boolean isLinkedHelpDialog) { + private void elementCaseMouseMoved(MouseEvent e, XCreator component) { + xElementCase = (XElementCase) component; + component.displayCoverPane(true); + processCoverMouseMove(component, e); + } + private void setCoverPaneNotDisplay(XCreator component, MouseEvent e, boolean isLinkedHelpDialog) { if (xChartEditor != null) { xChartEditor.displayCoverPane(false); } - if (isLinkedHelpDialog) { - component.destroyHelpDialog(); - } component.displayCoverPane(false); if (xTopLayoutContainer != null) { xTopLayoutContainer.setMouseEnter(false); @@ -432,19 +418,7 @@ public class EditingMouseListener extends MouseInputAdapter { xTopLayoutContainer.setMouseEnter(true); designer.repaint(); if (!xTopLayoutContainer.isEditable()) { - if (designer.getCursor().getType() == Cursor.HAND_CURSOR) { - designer.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); - } - int minX = getParentPositionX(parent, parent.getX()) + parent.getWidth() / 2; - int minY = getParentPositionY(parent, parent.getY()) + parent.getHeight() / 2; - int offsetX = EDIT_BTN_WIDTH / 2 + GAP; - int offsetY = EDIT_BTN_HEIGHT / 2 + GAP; - if (e.getX() > (minX - offsetX) && e.getX() < (minX + offsetX)) { - if (e.getY() > (minY - offsetY) && e.getY() < (minY + offsetY + designer.getParaHeight())) { - designer.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); - } - } - setHelpBtnFocus(e, xTopLayoutContainer); + processCoverMouseMove(parent, e); return true; } } @@ -454,19 +428,28 @@ public class EditingMouseListener extends MouseInputAdapter { private void processChartEditorMouseMove(XCreator component, MouseEvent e) { if (component instanceof XChartEditor) { xChartEditor = (XChartEditor) component; - UIButton button = (UIButton) xChartEditor.getCoverPane().getComponent(0); - if (designer.getCursor().getType() == Cursor.HAND_CURSOR) { - designer.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); - } - int minX = button.getX() + getParentPositionX(component, 0) - designer.getHorizontalScaleValue(); - int minY = button.getY() + getParentPositionY(component, 0) - designer.getVerticalScaleValue() + xChartEditor.getY(); - if (e.getX() + GAP > minX && e.getX() - GAP < minX + button.getWidth()) { - if (e.getY() + GAP > minY && e.getY() - GAP < minY + button.getHeight()) { - designer.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); - } - } - setHelpBtnFocus(e, xChartEditor); - designer.repaint(); + component.displayCoverPane(true); + processCoverMouseMove(component, e); + + } + } + + private void processCoverMouseMove(XCreator component, MouseEvent e) { + component.setShareConfigButtonFocus(false); + Insets insets; + if (component instanceof XBorderStyleWidgetCreator) { + insets = ((XBorderStyleWidgetCreator) component).getInsets(); + } else { + insets = DEEFAULT_INSETS; + } + if (designer.getCursor().getType() == Cursor.HAND_CURSOR) { + designer.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + } + if (isShareConfigButton(e, component, insets)) { + designer.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + component.setShareConfigButtonFocus(true); + } else if (isEditButton(e, component, insets)) { + designer.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); } } diff --git a/designer-form/src/main/java/com/fr/design/mainframe/FormArea.java b/designer-form/src/main/java/com/fr/design/mainframe/FormArea.java index f127f8ea0..ca3aa13f3 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/FormArea.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/FormArea.java @@ -36,6 +36,7 @@ import javax.swing.event.ChangeListener; import java.awt.AWTEvent; import java.awt.Adjustable; import java.awt.Color; +import java.awt.Component; import java.awt.Container; import java.awt.Dimension; import java.awt.Insets; @@ -268,8 +269,26 @@ public class FormArea extends JComponent implements ScrollRulerComponent { } } LayoutUtils.layoutContainer(root); + updateCreatorsBackupBound(root); } + /** + * 给所有自适应布局内部的组件设置backupBounds + * @param creator + */ + private void updateCreatorsBackupBound(XCreator creator) { + if (creator.acceptType(XWFitLayout.class)) { + ((XWFitLayout) creator).updateCreatorsBackupBound(); + } + for (int i = 0; i < creator.getComponentCount(); i++) { + Component object = creator.getComponent(i); + if(object instanceof XCreator){ + updateCreatorsBackupBound((XCreator) object); + } + } + } + + //设置宽度的控件及响应事件 private void addWidthPaneListener() { widthPane.addActionListener( @@ -449,7 +468,6 @@ public class FormArea extends JComponent implements ScrollRulerComponent { layout.setContainerPercent(1.0); traverAndAdjust(layout, 0.0); layout.adjustCreatorsWhileSlide(0.0); - // 拖动滑块,先将内部组件百分比大小计算,再计算容器大小 Dimension d = new Dimension(layout.getWidth(), layout.getHeight()); diff --git a/designer-form/src/main/java/com/fr/design/mainframe/FormCreatorDropTarget.java b/designer-form/src/main/java/com/fr/design/mainframe/FormCreatorDropTarget.java index e35580b91..eb036239b 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/FormCreatorDropTarget.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/FormCreatorDropTarget.java @@ -22,10 +22,9 @@ import com.fr.design.gui.ibutton.UIButton; import com.fr.design.icon.IconPathConstants; import com.fr.design.mainframe.chart.info.ChartInfoCollector; import com.fr.design.utils.ComponentUtils; -import com.fr.form.share.SharableEditorProvider; +import com.fr.form.share.editor.SharableEditorProvider; import com.fr.form.share.SharableWidgetProvider; import com.fr.form.share.ShareLoader; -import com.fr.form.ui.ChartEditor; import com.fr.form.ui.Widget; import com.fr.stable.Constants; import com.fr.stable.StringUtils; @@ -43,7 +42,6 @@ import java.awt.dnd.DropTarget; import java.awt.dnd.DropTargetDragEvent; import java.awt.dnd.DropTargetDropEvent; import java.awt.dnd.DropTargetEvent; -import java.util.Map; /** * 添加模式下鼠标事件处理器。 diff --git a/designer-form/src/main/java/com/fr/design/mainframe/FormModelAdapter.java b/designer-form/src/main/java/com/fr/design/mainframe/FormModelAdapter.java index e5617c946..bf047a3be 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/FormModelAdapter.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/FormModelAdapter.java @@ -27,6 +27,10 @@ public class FormModelAdapter extends DesignModelAdapter> super(jForm); } + public FormModelAdapter(BaseJForm
jTemplate, Parameter[] parameters) { + super(jTemplate, parameters); + } + /** * 环境改变. */ diff --git a/designer-form/src/main/java/com/fr/design/mainframe/FormParaWidgetPane.java b/designer-form/src/main/java/com/fr/design/mainframe/FormParaWidgetPane.java index ddd78c13f..b8f3ff638 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/FormParaWidgetPane.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/FormParaWidgetPane.java @@ -15,6 +15,8 @@ import com.fr.design.gui.ibutton.UIButton; import com.fr.design.gui.icontainer.UIScrollPane; import com.fr.design.gui.ilable.UILabel; import com.fr.design.gui.imenu.UIPopupMenu; +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.share.collect.ComponentCollector; import com.fr.design.module.DesignModuleFactory; import com.fr.design.utils.gui.LayoutUtils; import com.fr.form.ui.UserDefinedWidgetConfig; @@ -31,10 +33,13 @@ import com.fr.plugin.observer.PluginEvent; import com.fr.plugin.observer.PluginEventListener; import com.fr.stable.ArrayUtils; +import javax.swing.BorderFactory; import javax.swing.JComponent; import javax.swing.JPanel; import javax.swing.JSeparator; import javax.swing.SwingConstants; +import java.awt.Cursor; +import java.awt.event.MouseListener; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; @@ -233,8 +238,50 @@ public class FormParaWidgetPane extends JPanel { } add(createWidgetCombinationPane(widgetPane, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_ToolBar_Widget"))); add(createJSeparator()); + + add(createComponentReuseToolPane()); + add(createJSeparator()); } + private JPanel createComponentReuseToolPane() { + JPanel jPanel = new JPanel(new BorderLayout(17, 10)); + UILabel uiLabel = new UILabel(BaseUtils.readIcon("/com/fr/design/images/form/designer/widget_apply_icon.png")); + uiLabel.setBorder(BorderFactory.createEmptyBorder(5, 0 ,5, 0)); + jPanel.addMouseListener(new MouseListener() { + @Override + public void mouseClicked(MouseEvent e) { + FormWidgetDetailPane.getInstance().enterWidgetLib(); + ComponentCollector.getInstance().collectToolbarJump(); + } + + @Override + public void mousePressed(MouseEvent e) { + jPanel.setBackground(Color.decode("#419BF9")); + } + + @Override + public void mouseReleased(MouseEvent e) { + jPanel.setBackground(null); + } + + @Override + public void mouseEntered(MouseEvent e) { + + } + + @Override + public void mouseExited(MouseEvent e) { + + } + }); + jPanel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + jPanel.add(uiLabel, BorderLayout.NORTH); + jPanel.add(new UILabel(Toolkit.i18nText("Fine-Design_Component_Reuse_Apply_Widget")), BorderLayout.CENTER); + jPanel.setToolTipText(Toolkit.i18nText("Fine-Design_Share_Component")); + return jPanel; + } + + private void loadPredefinedWidget() { predifinedwidgeList.clear(); if (designer != null) { diff --git a/designer-form/src/main/java/com/fr/design/mainframe/FormSelection.java b/designer-form/src/main/java/com/fr/design/mainframe/FormSelection.java index cbebbcba1..d1d0a2f83 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/FormSelection.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/FormSelection.java @@ -6,17 +6,21 @@ import com.fr.design.designer.beans.location.Direction; import com.fr.design.designer.creator.XComponent; import com.fr.design.designer.creator.XCreator; import com.fr.design.designer.creator.XCreatorUtils; +import com.fr.design.designer.creator.XElementCase; import com.fr.design.designer.creator.XLayoutContainer; import com.fr.design.designer.creator.XWAbsoluteLayout; import com.fr.design.designer.creator.XWFitLayout; import com.fr.design.designer.creator.XWParameterLayout; +import com.fr.design.designer.creator.XWTitleLayout; import com.fr.design.designer.creator.cardlayout.XWCardTagLayout; import com.fr.design.designer.creator.cardlayout.XWTabFitLayout; +import com.fr.design.file.HistoryTemplateListCache; import com.fr.design.utils.ComponentUtils; import com.fr.design.utils.gui.LayoutUtils; import com.fr.form.ui.Widget; import com.fr.log.FineLoggerFactory; +import java.awt.Component; import java.awt.LayoutManager; import java.awt.Rectangle; import java.util.ArrayList; @@ -270,16 +274,52 @@ public class FormSelection { LayoutAdapter layoutAdapter = AdapterBus.searchLayoutAdapter(designer, creator); if (layoutAdapter != null) { if (creator.acceptType(XWAbsoluteLayout.class) && recs.size() > i) { - creator.setBackupBound(recs.get(i)); + Rectangle rectangle = recs.get(i); + check4ParaPane(rectangle); + creator.setBackupBound(rectangle); } else { creator.setBackupBound(backupBounds); } layoutAdapter.fix(creator); + resetElementCaseImage(creator); } i++; } } + /** + * @Description 重置报表块缩略图 + * @param: creator + * @return void + * @Author Henry.Wang + * @Date 2021/5/21 14:59 + **/ + public void resetElementCaseImage(XCreator creator) { + if (creator instanceof XWTitleLayout) { + XWTitleLayout xwTitleLayout = (XWTitleLayout) creator; + for (int i = 0; i < xwTitleLayout.getComponentCount(); i++) { + Component component = xwTitleLayout.getComponent(i); + if (component instanceof XElementCase) { + XElementCase xElementCase = (XElementCase) component; + xElementCase.updateECImage(); + } + } + } + } + + /** + * 检查下有没有参数面板,如果存在,处理下参数面板造成的偏移量 + * @param rectangle + */ + private void check4ParaPane(Rectangle rectangle) { + int paraHeight = 0; + JTemplate jTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + if (jTemplate instanceof JForm) { + paraHeight = ((JForm) jTemplate).getFormDesign().getParaHeight(); + } + rectangle.y += paraHeight; + } + private void removeCreatorFromContainer(XCreator creator) { XLayoutContainer parent = XCreatorUtils.getParentXLayoutContainer(creator); if (parent == null) { diff --git a/designer-form/src/main/java/com/fr/design/mainframe/FormWidgetDetailPane.java b/designer-form/src/main/java/com/fr/design/mainframe/FormWidgetDetailPane.java index 311ea4cb7..f77e68e15 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/FormWidgetDetailPane.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/FormWidgetDetailPane.java @@ -1,45 +1,20 @@ package com.fr.design.mainframe; import com.fr.base.BaseUtils; -import com.fr.base.FRContext; -import com.fr.design.gui.ibutton.UIButton; -import com.fr.design.gui.icombobox.UIComboBox; -import com.fr.design.gui.icontainer.UIScrollPane; -import com.fr.design.gui.ifilechooser.UINativeFileChooser; -import com.fr.design.gui.ilable.UILabel; +import com.fr.design.dialog.BasicPane; +import com.fr.design.gui.ibutton.UIHeadGroup; import com.fr.design.layout.FRGUIPaneFactory; -import com.fr.design.os.impl.SupportOSImpl; -import com.fr.design.widget.FRWidgetFactory; -import com.fr.form.share.SharableWidgetProvider; -import com.fr.form.share.ShareLoader; -import com.fr.general.CloudCenter; -import com.fr.log.FineLoggerFactory; -import com.fr.share.ShareConstants; -import com.fr.stable.ArrayUtils; -import com.fr.stable.StringUtils; +import com.fr.design.mainframe.share.collect.ComponentCollector; +import com.fr.design.mainframe.share.ui.local.LocalWidgetRepoPane; +import com.fr.design.mainframe.share.ui.online.OnlineWidgetRepoPane; -import javax.swing.BorderFactory; -import javax.swing.DefaultComboBoxModel; import javax.swing.Icon; -import javax.swing.JFileChooser; -import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; -import javax.swing.SwingWorker; -import javax.swing.filechooser.FileNameExtensionFilter; import java.awt.BorderLayout; -import java.awt.Color; -import java.awt.Desktop; -import java.awt.Dimension; -import java.awt.FlowLayout; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.ItemEvent; -import java.awt.event.ItemListener; -import java.io.File; -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; +import java.awt.CardLayout; +import java.util.ArrayList; +import java.util.List; /** * Created with IntelliJ IDEA. @@ -48,19 +23,11 @@ import java.net.URISyntaxException; * Time: 下午8:18 */ public class FormWidgetDetailPane extends FormDockView{ - private static final int LOCAL_WIDGET_LABEL_WIDTH = 90; + private static final int ONLINE_TAB = 1; - private UIScrollPane downPane; - private JPanel reuWidgetPanel; - private UIComboBox comboBox; - private SharableWidgetProvider[] elCaseBindInfoList; - private UIButton deleteButton; - private JPanel editPanel; - private JPanel resetPanel; - private JPanel menutPanelNorthPane; - private SwingWorker sw; - //组件面板是否可以编辑 - private boolean isEdit; + private JPanel centerPane; + private UIHeadGroup headGroup; + private List paneList; public static FormWidgetDetailPane getInstance() { if (HOLDER.singleton == null) { @@ -99,349 +66,34 @@ public class FormWidgetDetailPane extends FormDockView{ public void refreshDockingView(){ FormDesigner designer = this.getEditingFormDesigner(); removeAll(); - if(designer == null){ + if (designer == null) { clearDockingView(); return; } - reuWidgetPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); - reuWidgetPanel.setBorder(null); - if (elCaseBindInfoList == null) { - if (sw != null) { - sw.cancel(true); - } - sw = new SwingWorker() { - @Override - protected Object doInBackground() throws Exception { - elCaseBindInfoList = ShareLoader.getLoader().getAllBindInfoList(); - refreshDownPanel(false); - return null; - } - }; - sw.execute(); - } - initReuWidgetPanel(); - initMenuPanel(); - - add(reuWidgetPanel, BorderLayout.CENTER); - - } - - /** - * 初始化组件共享和复用面板 - */ - private void initReuWidgetPanel() { - elCaseBindInfoList = ShareLoader.getLoader().getAllBindInfoList(); - downPane = new UIScrollPane(new ShareWidgetPane(elCaseBindInfoList, false)); - downPane.setBorder(null); - reuWidgetPanel.add(downPane); - } - - /** - * 初始化菜单栏面板 - */ - private void initMenuPanel() { - JPanel menutPanel = new JPanel(); - menutPanel.setLayout(FRGUIPaneFactory.createBorderLayout()); - menutPanel.setBorder(BorderFactory.createEmptyBorder(3, 10, 10, 15)); - - menutPanelNorthPane = new JPanel(new BorderLayout()); - UILabel localWidgetLabel = FRWidgetFactory.createLineWrapLabel( - com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Local_Widget"), - LOCAL_WIDGET_LABEL_WIDTH); - menutPanelNorthPane.add(localWidgetLabel, BorderLayout.WEST); - menutPanelNorthPane.add(initEditButtonPane(), BorderLayout.EAST); - menutPanelNorthPane.setBorder(BorderFactory.createEmptyBorder(0, 0, 5, 0)); - - menutPanel.add(menutPanelNorthPane, BorderLayout.NORTH); - comboBox = new UIComboBox(getFormCategories()); - comboBox.setPreferredSize(new Dimension(240, comboBox.getPreferredSize().height)); - initComboBoxSelectedListener(); - menutPanel.add(comboBox, BorderLayout.CENTER); - reuWidgetPanel.add(menutPanel, BorderLayout.NORTH); - - } - - /** - * 创建菜单栏按钮面板 - */ - private JPanel initEditButtonPane() { - editPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 0, 0)); - - editPanel.add(createRefreshButton()); - editPanel.add(createDownloadButton()); - editPanel.add(createInstallButton()); - editPanel.add(createDeleteButton()); - - return editPanel; - } - - /** - * 创建取消删除面板 - */ - private JPanel initResetButtonPane() { - resetPanel = new JPanel(); - UIButton resetButton = new UIButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Reset")); - resetPanel.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2)); - resetButton.setBackground(Color.white); - resetButton.setForeground(new Color(0x333334)); - resetButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - refreshDownPanel(false); - replaceButtonPanel(false); - reuWidgetPanel.remove(deleteButton); - } - }); - - deleteButton = new UIButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Remove_Item")); - deleteButton.setBackground(Color.white); - deleteButton.setForeground(new Color(0xeb1d1f)); - deleteButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - if (ShareLoader.getLoader().removeModulesFromList()) { - refreshShareMoudule(); - reuWidgetPanel.remove(deleteButton); - elCaseBindInfoList = ShareLoader.getLoader().getAllBindInfoList(); - JOptionPane.showMessageDialog(null, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Share_Module_Removed_Successful")); - refreshDownPanel(false); - replaceButtonPanel(false); - refreshComboxData(); - } else { - JOptionPane.showMessageDialog(null, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Share_Module_Removed_Failed")); - } - - } - }); - JPanel deletePane = new JPanel(new BorderLayout()); - deletePane.add(deleteButton, BorderLayout.CENTER); - deletePane.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5)); - - resetPanel.setLayout(FRGUIPaneFactory.createBorderLayout()); - resetPanel.add(resetButton, BorderLayout.CENTER); - resetPanel.add(deletePane, BorderLayout.WEST); - - refreshDownPanel(true); - - return resetPanel; - - } - - - private void initComboBoxSelectedListener() { - comboBox.addItemListener(new ItemListener() { - @Override - public void itemStateChanged(ItemEvent e) { - ShareLoader.getLoader().resetRemovedModuleList(); - int filterIndex = comboBox.getSelectedIndex(); - if (filterIndex == 0) { - elCaseBindInfoList = ShareLoader.getLoader().getAllBindInfoList(); - } else { - String filterName = comboBox.getSelectedItem().toString(); - elCaseBindInfoList = ShareLoader.getLoader().getFilterBindInfoList(filterName); - } - refreshDownPanel(isEdit); - - } - }); - } - - /** - * 创建工具条按钮 - */ - private UIButton createToolButton(Icon icon, String toolTip, ActionListener actionListener) { - UIButton toolButton = new UIButton(); - toolButton.setIcon(icon); - toolButton.setToolTipText(toolTip); - toolButton.set4ToolbarButton(); - toolButton.addActionListener(actionListener); - return toolButton; - - } - - /** - * 创建刷新按钮 - */ - private UIButton createRefreshButton() { - return createToolButton( - BaseUtils.readIcon("/com/fr/design/form/images/refresh.png"), - com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Refresh"), - new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - if (sw != null) { - sw.cancel(true); - } - sw = new SwingWorker() { - @Override - protected Object doInBackground() throws Exception { - ShareLoader.getLoader().refreshModule(); - elCaseBindInfoList = ShareLoader.getLoader().getAllBindInfoList(); - refreshComboxData(); - refreshDownPanel(false); - return null; - } - }; - sw.execute(); - } - } - ); - } - - private void refreshComboxData() { - comboBox.setSelectedIndex(0); - comboBox.setModel(new DefaultComboBoxModel(getFormCategories())); - } - - /** - * 创建下载模板的按钮 - */ - private UIButton createDownloadButton() { - UIButton downloadButton = new UIButton(); - downloadButton.setIcon(BaseUtils.readIcon("/com/fr/design/form/images/download icon.png")); - downloadButton.set4ToolbarButton(); - downloadButton.setToolTipText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Download_Template")); - downloadButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - String url = CloudCenter.getInstance().acquireUrlByKind("reuse.url"); - if (StringUtils.isEmpty(url)) { - FRContext.getLogger().info("The URL is empty!"); - return; - } - try { - Desktop.getDesktop().browse(new URI(url)); - } catch (IOException exp) { - JOptionPane.showMessageDialog(null, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Set_Default_Browser_Duplicate")); - FineLoggerFactory.getLogger().error(exp.getMessage(), exp); - } catch (URISyntaxException exp) { - FineLoggerFactory.getLogger().error(exp.getMessage(), exp); - } catch (Exception exp) { - FineLoggerFactory.getLogger().error(exp.getMessage(), exp); - FineLoggerFactory.getLogger().error("Can not open the browser for URL: " + url); - } - } - }); - return downloadButton; - } - - /** - * 创建安装模板的按钮 - */ - private UIButton createInstallButton() { - return createToolButton( - BaseUtils.readIcon("/com/fr/design/form/images/install icon.png"), - com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Install_Template"), - new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - if (SupportOSImpl.NATIVE_CHOOSER.support()) { - UINativeFileChooser nativeFileChooser = new UINativeFileChooser(); - nativeFileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); - nativeFileChooser.setMultiSelectionEnabled(true); - nativeFileChooser.setExtensionFilter("*.reu"); - nativeFileChooser.setDialogTitle(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Select")); - int returnValue = nativeFileChooser.showOpenDialog(new UILabel()); - if (returnValue == JFileChooser.APPROVE_OPTION) { - final File[] chosenFiles = nativeFileChooser.getSelectedFiles(); - for (File file : chosenFiles) { - installFromDiskZipFile(file); - } - } - } else { - JFileChooser fileChooser = new JFileChooser(); - fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); - fileChooser.setMultiSelectionEnabled(true); - fileChooser.setFileFilter(new FileNameExtensionFilter(".reu", "reu")); - int returnValue = fileChooser.showDialog(new UILabel(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Select")); - if (returnValue == JFileChooser.APPROVE_OPTION) { - final File[] chosenFiles = fileChooser.getSelectedFiles(); - for (File file : chosenFiles) { - installFromDiskZipFile(file); - } - } - } - } - } - ); - } - /** - * 创建删除模板的按钮 - */ - private UIButton createDeleteButton() { - return createToolButton( - BaseUtils.readIcon("/com/fr/design/form/images/delete icon.png"), - com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Delete_Template"), - new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - replaceButtonPanel(true); - } - } - ); - } - - private void replaceButtonPanel(boolean isEdit) { - this.isEdit = isEdit; - if (isEdit) { - menutPanelNorthPane.remove(editPanel); - menutPanelNorthPane.add(initResetButtonPane(), BorderLayout.EAST); - } else { - menutPanelNorthPane.remove(resetPanel); - menutPanelNorthPane.add(initEditButtonPane(), BorderLayout.EAST); - ShareLoader.getLoader().resetRemovedModuleList(); + initPaneList(); + this.setBorder(null); + final CardLayout cardLayout = new CardLayout(); + centerPane = new JPanel(cardLayout); + String[] paneNames = new String[paneList.size()]; + for (int i = 0; i < paneList.size(); i++) { + String title = paneList.get(i).getTitle(); + paneNames[i] = title; + centerPane.add(paneList.get(i), title); } - } - - private void installFromDiskZipFile(File chosenFile) { - if (chosenFile != null && chosenFile.getName().endsWith(ShareConstants.SUFFIX_MODULE)) { - try { - if (ShareLoader.getLoader().installModuleFromDiskZipFile(chosenFile)) { - refreshShareMoudule(); - elCaseBindInfoList = ShareLoader.getLoader().getAllBindInfoList(); - refreshDownPanel(false); - refreshComboxData(); - JOptionPane.showMessageDialog(null, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Share_Module_OK")); - } else { - JOptionPane.showMessageDialog(null, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Share_Module_Error")); + headGroup = new UIHeadGroup(paneNames) { + protected void tabChanged(int newSelectedIndex) { + if (newSelectedIndex == 1) { + ComponentCollector.getInstance().collectMarkerClick(); } - } catch (IOException e) { - JOptionPane.showMessageDialog(null, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Share_Module_Error")); - FineLoggerFactory.getLogger().error(e.getMessage(), e); + cardLayout.show(centerPane, paneList.get(newSelectedIndex).getTitle()); } - } - } - - private void refreshShareMoudule() { - try { - ShareLoader.getLoader().refreshModule(); - } catch (Exception e) { - FineLoggerFactory.getLogger().error(e.getMessage(), e); - } + }; + headGroup.setSelectedIndex(0); + this.add(headGroup, BorderLayout.NORTH); + this.add(centerPane, BorderLayout.CENTER); } - /** - * 获取报表块组件分类 - */ - public String[] getFormCategories() { - return ArrayUtils.addAll(new String[] {com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_AllCategories")}, ShareLoader.getLoader().getModuleCategory()); - } - - public void refreshDownPanel(boolean isEdit) { - reuWidgetPanel.remove(downPane); - downPane = new UIScrollPane(new ShareWidgetPane(elCaseBindInfoList, isEdit)); - downPane.setBorder(null); - reuWidgetPanel.add(downPane); - repaintContainer(); - - } - - public void repaintContainer() { - validate(); - repaint(); - revalidate(); - } /** * 清除数据 @@ -453,14 +105,26 @@ public class FormWidgetDetailPane extends FormDockView{ } + public void enterWidgetLib() { + EastRegionContainerPane.getInstance().switchTabTo(EastRegionContainerPane.KEY_WIDGET_LIB); + headGroup.setSelectedIndex(ONLINE_TAB); + ComponentReuseNotifyUtil.enterWidgetLibExtraAction(false); + } /** * 定位 - * @return 位置 + * + * @return 位置 */ + @Override public Location preferredLocation() { return Location.WEST_BELOW; } + private void initPaneList() { + paneList = new ArrayList<>(); + paneList.add(LocalWidgetRepoPane.getInstance()); + paneList.add(OnlineWidgetRepoPane.getInstance()); + } } diff --git a/designer-form/src/main/java/com/fr/design/mainframe/JForm.java b/designer-form/src/main/java/com/fr/design/mainframe/JForm.java index d39de1d44..a78c53270 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/JForm.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/JForm.java @@ -4,6 +4,7 @@ import com.fr.base.BaseUtils; import com.fr.base.PaperSize; import com.fr.base.Parameter; import com.fr.base.extension.FileExtension; +import com.fr.base.iofile.attr.ExtendSharableAttrMark; import com.fr.base.vcs.DesignerMode; import com.fr.design.DesignModelAdapter; import com.fr.design.DesignState; @@ -64,6 +65,11 @@ import com.fr.file.filter.ChooseFileFilter; import com.fr.form.FormElementCaseContainerProvider; import com.fr.form.FormElementCaseProvider; import com.fr.form.main.Form; +import com.fr.form.main.WidgetGatherAdapter; +import com.fr.form.share.SharableWidgetProvider; +import com.fr.form.share.editor.SharableEditorProvider; +import com.fr.form.share.utils.ShareUtils; +import com.fr.form.ui.AbstractBorderStyleWidget; import com.fr.form.ui.Widget; import com.fr.form.ui.container.WBorderLayout; import com.fr.form.ui.container.WLayout; @@ -77,6 +83,7 @@ import com.fr.report.worksheet.FormElementCase; import com.fr.stable.ArrayUtils; import com.fr.stable.Constants; import com.fr.stable.ProductConstants; +import com.fr.stable.StringUtils; import com.fr.stable.bridge.StableFactory; import com.fr.web.controller.ViewRequestConstants; @@ -96,6 +103,7 @@ import java.awt.event.ActionListener; import java.awt.image.BufferedImage; import java.util.ArrayList; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import javax.swing.tree.TreePath; @@ -127,6 +135,9 @@ public class JForm extends JTemplate implements BaseJForm implements BaseJForm implements BaseJForm jt) { + ReuseTriggerPointManager.getInstance().registerJForm(JForm.this); + } }); return tabCenterPane; @@ -679,6 +698,11 @@ public class JForm extends JTemplate implements BaseJForm implements BaseJForm map = new HashMap<>(); + + private List listeners = new ArrayList<>(); + + private ReuseTriggerPointManager() { + if (!hasNotifiedTwice()) { + List list = getTriggerPoints(); + for (TriggerPointProvider triggerPoint : list) { + Listener listener = new Listener() { + @Override + public void on(Event event, Null o) { + triggerPoint.triggerAction(); + } + }; + EventDispatcher.listen(triggerPoint.triggerEvent(), listener); + listeners.add(listener); + } + + } + } + + private List getTriggerPoints() { + List list = new ArrayList<>(); + list.add(new CellStyleTriggerPoint()); + list.add(new CellValueImageChangeTriggerPoint()); + return list; + } + + + public boolean hasNotifiedTwice() { + return ComponentReuseNotificationInfo.getInstance().getNotifiedNumber() >= 2; + } + + + private void reCount() { + //重新计次数 + Iterator> iterator = map.entrySet().iterator(); + while (iterator.hasNext()) { + iterator.next().getValue().reset(); + } + } + + private void writeTriggerInfo2xml() { + int number = ComponentReuseNotificationInfo.getInstance().getNotifiedNumber() + 1; + ComponentReuseNotificationInfo.getInstance().setNotifiedNumber(number); + ComponentReuseNotificationInfo.getInstance().setLastNotifyTime(System.currentTimeMillis()); + DesignerEnvManager.getEnvManager().saveXMLFile(); + //如果已经提示过两次了 + if (hasNotifiedTwice()) { + for (Listener listener : listeners) { + EventDispatcher.stopListen(listener); + } + this.map.clear(); + } + } + + public boolean needTrigger() { + boolean result = true; + if (ComponentReuseNotificationInfo.getInstance().getLastNotifyTime() > 0L) { + result = System.currentTimeMillis() - ComponentReuseNotificationInfo.getInstance().getLastNotifyTime() > ONE_WEEK_TIME; + } + return !hasNotifiedTwice() && result; + } + + + public void registerJForm(JForm jForm) { + if (!hasNotifiedTwice()) { + this.map.put(jForm, new ReuseNotifyInfo()); + } + + } + + public void removeJForm(JForm jForm) { + if (!hasNotifiedTwice()) { + this.map.remove(jForm); + } + } + + + public ReuseNotifyInfo getReuseNotifyInfo() { + JTemplate currentJTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + if (!(currentJTemplate instanceof JForm && hasUseReuseComponent((JForm) currentJTemplate)) + && !ReuseTriggerPointManager.getInstance().needTrigger()) { + return null; + } + return map.get(currentJTemplate); + } + + public void reuseNotify(ReuseNotifyInfo notifyInfo) { + if (notifyInfo.matchCondition()) { + ReuseTriggerPointManager.getInstance().reCount(); + //弹出提示框 + JTemplate currentJTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + DesignerToastMsgUtil.toastPrompt(createReusePrompt((JForm) currentJTemplate)); + ReuseTriggerPointManager.getInstance().writeTriggerInfo2xml(); + ComponentCollector.getInstance().collectPromptJumpWhenShow(); + } + } + + + private boolean hasUseReuseComponent(JForm jForm) { + Form form = jForm.getTarget(); + List extendSharableWidgetList = new ArrayList<>(); + Form.traversalWidget(form.getContainer(), new WidgetGather() { + @Override + public void dealWith(Widget widget) { + ExtendSharableAttrMark attrMark = ((AbstractBorderStyleWidget) widget).getWidgetAttrMark(ExtendSharableAttrMark.XML_TAG); + if (attrMark != null && StringUtils.isNotEmpty(attrMark.getShareId())) { + extendSharableWidgetList.add(widget); + } + } + + @Override + public boolean dealWithAllCards() { + return true; + } + }, AbstractBorderStyleWidget.class); + return extendSharableWidgetList.size() > 0; + } + + + private JPanel createReusePrompt(JForm jForm) { + JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + jPanel.add(new UILabel(Toolkit.i18nText("Fine-Design_Component_Reuse_Try_Prompt")), BorderLayout.WEST); + UILabel reuseLabel = new UILabel(Toolkit.i18nText("Fine-Design_Component_Reuse")); + reuseLabel.addMouseListener(new MouseListener() { + @Override + public void mouseClicked(MouseEvent e) { + jForm.tabChanged(0); + FormWidgetDetailPane.getInstance().enterWidgetLib(); + ComponentCollector.getInstance().collectPromptJumpWhenJump(); + } + + @Override + public void mousePressed(MouseEvent e) { + + } + + @Override + public void mouseReleased(MouseEvent e) { + + } + + @Override + public void mouseEntered(MouseEvent e) { + + } + + @Override + public void mouseExited(MouseEvent e) { + + } + }); + reuseLabel.setBorder(BorderFactory.createEmptyBorder(0, 3, 0, 0)); + reuseLabel.setForeground(Color.BLUE); + reuseLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + jPanel.add(reuseLabel, BorderLayout.CENTER); + return jPanel; + } + + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/ShareWidgetButton.java b/designer-form/src/main/java/com/fr/design/mainframe/ShareWidgetButton.java deleted file mode 100644 index cdfa095bf..000000000 --- a/designer-form/src/main/java/com/fr/design/mainframe/ShareWidgetButton.java +++ /dev/null @@ -1,314 +0,0 @@ -package com.fr.design.mainframe; - -import com.fr.base.iofile.attr.SharableAttrMark; -import com.fr.base.vcs.DesignerMode; -import com.fr.design.designer.creator.XCreator; -import com.fr.design.designer.creator.XCreatorUtils; -import com.fr.design.gui.ilable.UILabel; -import com.fr.form.share.SharableWidgetProvider; -import com.fr.form.share.ShareLoader; -import com.fr.form.ui.AbstractBorderStyleWidget; -import com.fr.form.ui.Widget; -import com.fr.form.ui.container.cardlayout.WCardMainBorderLayout; -import com.fr.general.ComparatorUtils; -import com.fr.general.IOUtils; -import com.fr.share.ShareConstants; -import com.fr.stable.StringUtils; -import org.jetbrains.annotations.NotNull; - -import javax.swing.Icon; -import javax.swing.ImageIcon; -import javax.swing.JComponent; -import javax.swing.JPanel; -import java.awt.AlphaComposite; -import java.awt.BorderLayout; -import java.awt.Color; -import java.awt.Component; -import java.awt.Composite; -import java.awt.Container; -import java.awt.Dimension; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.LayoutManager; -import java.awt.Rectangle; -import java.awt.datatransfer.DataFlavor; -import java.awt.datatransfer.Transferable; -import java.awt.datatransfer.UnsupportedFlavorException; -import java.awt.dnd.DnDConstants; -import java.awt.dnd.DragGestureEvent; -import java.awt.dnd.DragGestureListener; -import java.awt.dnd.DragSource; -import java.awt.dnd.DragSourceAdapter; -import java.awt.dnd.DragSourceDragEvent; -import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; -import java.awt.event.MouseMotionListener; -import java.io.IOException; -import java.io.Serializable; - -/** - * Coder: zack - * Date: 2016/10/9 - * Time: 16:14 - */ -public class ShareWidgetButton extends JPanel implements MouseListener, MouseMotionListener, Serializable { - - protected SharableWidgetProvider bindInfo; - protected MouseEvent lastPressEvent; - protected JPanel reportPane; - protected boolean isEdit; - protected boolean isMarked; - private ShareWidgetUI ui; - private Icon markedMode = IOUtils.readIcon("/com/fr/design/form/images/marked.png"); - private Icon unMarkedMode = IOUtils.readIcon("/com/fr/design/form/images/unmarked.png"); - private AlphaComposite composite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 60 / 100.0F); - private JComponent markedButton = new JComponent() { - protected void paintComponent(Graphics g) { - markedMode.paintIcon(this, g, 0, 0); - } - }; - private JComponent unMarkedButton = new JComponent() { - protected void paintComponent(Graphics g) { - unMarkedMode.paintIcon(this, g, 0, 0); - } - }; - - public ShareWidgetButton(SharableWidgetProvider bindInfo, ShareWidgetUI ui) { - - this.bindInfo = bindInfo; - this.ui = ui; - this.setPreferredSize(new Dimension(108, 68)); - initUI(); - this.setLayout(getCoverLayout()); - this.addMouseListener(this); - this.addMouseMotionListener(this); - new DragAndDropDragGestureListener(this, DnDConstants.ACTION_COPY_OR_MOVE); - } - - public ShareWidgetButton(SharableWidgetProvider bindInfo) { - - this(bindInfo, new ShareWidgetUI()); - } - - public void paint(Graphics g) { - Graphics2D g2d = (Graphics2D) g; - Composite oldComposite = g2d.getComposite(); - g2d.setComposite(composite); - g2d.setColor(Color.WHITE); - g2d.fillRect(0, 0, getWidth(), getHeight()); - g2d.setComposite(oldComposite); - super.paint(g); - } - - public void setElementCaseEdit(boolean isEdit) { - this.isEdit = isEdit; - if (isEdit) { - this.add(unMarkedButton, 0); - repaint(); - } - - - } - - private void initUI() { - - reportPane = new JPanel(new BorderLayout()); - reportPane.add(new UILabel(new ImageIcon(bindInfo.getCover())), BorderLayout.CENTER); - JPanel labelPane = new JPanel(new BorderLayout()); - UILabel label = new UILabel(bindInfo.getName(), UILabel.CENTER); - labelPane.setBackground(new Color(184, 220, 242)); - labelPane.add(label, BorderLayout.CENTER); - reportPane.add(labelPane, BorderLayout.SOUTH); - add(reportPane); - } - - protected LayoutManager getCoverLayout() { - return new LayoutManager() { - - @Override - public void removeLayoutComponent(Component comp) { - } - - @Override - public Dimension preferredLayoutSize(Container parent) { - return parent.getPreferredSize(); - } - - @Override - public Dimension minimumLayoutSize(Container parent) { - return null; - } - - @Override - public void layoutContainer(Container parent) { - int width = parent.getWidth(); - int height = parent.getHeight(); - markedButton.setBounds((width - 25), 0, 25, 25); - unMarkedButton.setBounds((width - 25), 0, 25, 25); - reportPane.setBounds(0, 0, width, height); - - - - } - - @Override - public void addLayoutComponent(String name, Component comp) { - } - }; - } - - public SharableWidgetProvider getBindInfo() { - return bindInfo; - } - - public void setBindInfo(SharableWidgetProvider bindInfo) { - this.bindInfo = bindInfo; - } - - public String getFileName() { - return bindInfo.getName() +"." + bindInfo.getId() + ShareConstants.SUFFIX_MODULE; - } - - @Override - public void mouseClicked(MouseEvent e) { - if (isEdit) { - if (isMarked) { - remove(markedButton); - ShareLoader.getLoader().removeModuleForList(getFileName()); - isMarked = false; - } else { - add(markedButton,0); - ShareLoader.getLoader().addModuleToList(getFileName()); - isMarked = true; - } - } - - repaint(); - } - - @Override - public void mousePressed(MouseEvent e) { - lastPressEvent = e; - } - - @Override - public void mouseReleased(MouseEvent e) { - - } - - @Override - public void mouseEntered(MouseEvent e) { - - } - - @Override - public void mouseExited(MouseEvent e) { - - } - - @Override - public void mouseDragged(MouseEvent e) { - if (DesignerMode.isAuthorityEditing()) { - return; - } - if (lastPressEvent == null) { - return; - } - Object source = e.getSource(); - Widget creatorSource = null; - String shareId = StringUtils.EMPTY; - if (source instanceof ShareWidgetButton) { - ShareWidgetButton no = (ShareWidgetButton) e.getSource(); - if (no == null) { - return; - } - shareId = no.getBindInfo().getId(); - creatorSource = ShareLoader.getLoader().getElCaseEditorById(shareId); - if (creatorSource != null) { - ((AbstractBorderStyleWidget)creatorSource).addWidgetAttrMark(new SharableAttrMark(true)); - //tab布局WCardMainBorderLayout通过反射出来的大小是960*480 - XCreator xCreator = ui.createXCreator(creatorSource, shareId, no.getBindInfo()); - WidgetToolBarPane.getTarget().startDraggingBean(xCreator); - lastPressEvent = null; - this.setBorder(null); - } - } - } - - @Override - public void mouseMoved(MouseEvent e) { - - } - - public class DragAndDropDragGestureListener extends DragSourceAdapter implements DragGestureListener { - private DragSource source; - - public DragAndDropDragGestureListener(ShareWidgetButton tt, int actions) { - source = new DragSource(); - source.createDefaultDragGestureRecognizer(tt, actions, this); - } - - public void dragGestureRecognized(DragGestureEvent dge) { - ShareWidgetButton shareWidgetButton = (ShareWidgetButton) dge.getComponent(); - if (shareWidgetButton != null) { - Widget widget = ShareLoader.getLoader().getElCaseEditorById(shareWidgetButton.getBindInfo().getId()); - DragAndDropTransferable dragAndDropTransferable = new DragAndDropTransferable(widget); - dge.startDrag(DragSource.DefaultCopyDrop, dragAndDropTransferable, this); - } - } - - @Override - public void dragEnter(DragSourceDragEvent dragSourceDragEvent) { - - } - } - - public class DragAndDropTransferable implements Transferable { - private Widget widget; - - public DragAndDropTransferable(Widget widget) { - this.widget = widget; - } - - DataFlavor[] flavors = {new DataFlavor(Widget.class, "Widget")}; - - public DataFlavor[] getTransferDataFlavors() { - return flavors; - } - - public boolean isDataFlavorSupported(DataFlavor flavor) { - for (DataFlavor df : flavors) { - if (ComparatorUtils.equals(df, flavor)) { - return true; - } - } - return false; - } - - public Object getTransferData(DataFlavor df) throws UnsupportedFlavorException, IOException { - return widget; - } - } - - /** - * 抽出来,专门为了创建 ui 来搞 - */ - public static class ShareWidgetUI { - - private static final Dimension TAB_DEFAULT_SIZE = new Dimension(500, 300); - - @NotNull - public XCreator createXCreator(Widget creatorSource, String shareId, SharableWidgetProvider provider) { - - XCreator xCreator = null; - if (creatorSource instanceof WCardMainBorderLayout) { - xCreator = XCreatorUtils.createXCreator(creatorSource, TAB_DEFAULT_SIZE); - } else { - xCreator = XCreatorUtils.createXCreator(creatorSource, new Dimension(provider.getWidth(), provider.getHeight())); - } - xCreator.setBackupBound(new Rectangle(provider.getWidth(), provider.getHeight())); - xCreator.setShareId(shareId); - return xCreator; - } - } -} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/ShareWidgetPane.java b/designer-form/src/main/java/com/fr/design/mainframe/ShareWidgetPane.java deleted file mode 100644 index 549a4b174..000000000 --- a/designer-form/src/main/java/com/fr/design/mainframe/ShareWidgetPane.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.fr.design.mainframe; - - - -import com.fr.form.share.SharableWidgetProvider; - -import javax.swing.*; -import java.awt.*; - - -/** - * Created by xiaxiang on 2016/10/10. - */ -public class ShareWidgetPane extends JPanel { - - public ShareWidgetPane(SharableWidgetProvider[] elCaseBindInfoList, boolean isEdit) { - this.setBorder(BorderFactory.createEmptyBorder(10, 3, 0, 0));// 设置面板的边框 ,距离上、左、下、右 的距离 - if (elCaseBindInfoList != null) { - int rowCount = (elCaseBindInfoList.length + 1) / 2; - this.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 10)); - for (SharableWidgetProvider rbModuleInfo : elCaseBindInfoList) { - ShareWidgetButton widgetButton = new ShareWidgetButton(rbModuleInfo); - widgetButton.setElementCaseEdit(isEdit); - this.add(widgetButton); - } - this.setPreferredSize(new Dimension(240, rowCount * 80)); - } - } -} \ No newline at end of file diff --git a/designer-form/src/main/java/com/fr/design/mainframe/ToolBarButton.java b/designer-form/src/main/java/com/fr/design/mainframe/ToolBarButton.java index f7558b07f..4c18ba475 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/ToolBarButton.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/ToolBarButton.java @@ -1,12 +1,13 @@ package com.fr.design.mainframe; -import com.fr.base.BaseUtils; import com.fr.base.vcs.DesignerMode; import com.fr.design.designer.creator.XCreator; +import com.fr.design.file.HistoryTemplateListCache; import com.fr.design.form.util.FormDesignerUtils; import com.fr.design.gui.ibutton.UIButton; import com.fr.design.gui.core.WidgetOption; import com.fr.design.designer.creator.XCreatorUtils; +import com.fr.design.gui.ibutton.UIForbiddenButtonUI; import com.fr.form.ui.Widget; import com.fr.general.ComparatorUtils; @@ -20,6 +21,7 @@ import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.io.IOException; import java.io.Serializable; +import javax.swing.plaf.ButtonUI; /* *august: 控件按钮 @@ -73,6 +75,10 @@ public class ToolBarButton extends UIButton implements MouseListener, MouseMotio @Override public void mouseDragged(MouseEvent e) { + if (!isEnabled()) { + return; + } + if (DesignerMode.isAuthorityEditing()) { return; } @@ -164,4 +170,19 @@ public class ToolBarButton extends UIButton implements MouseListener, MouseMotio @Override public void mouseExited(MouseEvent e) { } + + @Override + public ButtonUI getUI() { + return new UIForbiddenButtonUI(); + } + + @Override + public boolean isEnabled() { + JTemplate template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + boolean enable = true; + if (template != null) { + enable = super.isEnabled() && template.checkEnable(); + } + return enable; + } } diff --git a/designer-form/src/main/java/com/fr/design/mainframe/WidgetPropertyPane.java b/designer-form/src/main/java/com/fr/design/mainframe/WidgetPropertyPane.java index c37b4ba9a..fd64d3aab 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/WidgetPropertyPane.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/WidgetPropertyPane.java @@ -6,13 +6,12 @@ import com.fr.design.constants.UIConstants; import com.fr.design.designer.beans.events.DesignerEditListener; import com.fr.design.designer.beans.events.DesignerEvent; import com.fr.design.designer.creator.*; -import com.fr.design.designer.creator.cardlayout.XWCardMainBorderLayout; import com.fr.design.designer.creator.cardlayout.XWCardTagLayout; -import com.fr.design.designer.properties.EventPropertyTable; import com.fr.design.designer.properties.mobile.MobileBookMarkPropertyUI; import com.fr.design.designer.properties.mobile.MobileStylePropertyUI; import com.fr.design.form.util.FormDesignerUtils; import com.fr.design.fun.WidgetPropertyUIProvider; +import com.fr.design.gui.controlpane.EventPropertyPane; import com.fr.design.gui.ibutton.UIHeadGroup; import com.fr.design.gui.icontainer.UIScrollPane; import com.fr.design.gui.ilable.UILabel; @@ -38,7 +37,7 @@ public class WidgetPropertyPane extends FormDockView implements BaseWidgetProper private static final int PADDING = 10; private static final int PADDING_M = 12; private FormWidgetCardPane formWidgetCardPane; // 控件的属性表 - private EventPropertyTable eventTable; // 控件的事件表 + private EventPropertyPane eventTable; // 控件的事件表 private List widgetPropertyTables; // 这个变量应该是保存控件拓展的属性tab private List mobileExtraPropertyPanes; // 保存9.0设计器下移动端拓展的属性tab,舍弃JTable private FormDesigner designer; // 当前designer @@ -141,7 +140,7 @@ public class WidgetPropertyPane extends FormDockView implements BaseWidgetProper * 创建事件表(事件选项卡不是JTable) */ private void createEventTable() { - eventTable = new EventPropertyTable(designer); + eventTable = new EventPropertyPane(designer); designer.addDesignerEditListener(new EventPropertyDesignerAdapter(eventTable)); } @@ -337,9 +336,9 @@ public class WidgetPropertyPane extends FormDockView implements BaseWidgetProper * 事件表监听界面事件(编辑,选中) */ private class EventPropertyDesignerAdapter implements DesignerEditListener { - EventPropertyTable propertyTable; + EventPropertyPane propertyTable; - EventPropertyDesignerAdapter(EventPropertyTable eventTable) { + EventPropertyDesignerAdapter(EventPropertyPane eventTable) { this.propertyTable = eventTable; } diff --git a/designer-form/src/main/java/com/fr/design/mainframe/adaptve/config/ReuseNotifyInfo.java b/designer-form/src/main/java/com/fr/design/mainframe/adaptve/config/ReuseNotifyInfo.java new file mode 100644 index 000000000..17aa1a631 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/adaptve/config/ReuseNotifyInfo.java @@ -0,0 +1,30 @@ +package com.fr.design.mainframe.adaptve.config; + +/** + * Created by kerry on 5/7/21 + */ +public class ReuseNotifyInfo { + private static final int CELL_STYLE_MODIFY_MAX_NUMBER = 3; + private static final int CELL_IMAGE_VALUE_MODIFY_MAX_NUMBER = 1; + private int cellStyleModifiedNumber = 0; + private int cellImageValueNumber = 0; + + public void addCellStyleModify() { + cellStyleModifiedNumber++; + } + + + public void addCellImageValueModify() { + cellImageValueNumber++; + } + + public boolean matchCondition() { + return cellStyleModifiedNumber >= CELL_STYLE_MODIFY_MAX_NUMBER + || cellImageValueNumber >= CELL_IMAGE_VALUE_MODIFY_MAX_NUMBER; + } + + public void reset() { + this.cellImageValueNumber = 0; + this.cellStyleModifiedNumber = 0; + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/adaptve/config/TriggerPointProvider.java b/designer-form/src/main/java/com/fr/design/mainframe/adaptve/config/TriggerPointProvider.java new file mode 100644 index 000000000..5fa4db80f --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/adaptve/config/TriggerPointProvider.java @@ -0,0 +1,20 @@ +package com.fr.design.mainframe.adaptve.config; + + +import com.fr.event.Event; + +/** + * Created by kerry on 4/29/21 + */ +public interface TriggerPointProvider { + /** + * 触发后的操作 + */ + void triggerAction(); + + /** + * 触发事件 + * @return + */ + Event triggerEvent(); +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/adaptve/config/impl/CellStyleTriggerPoint.java b/designer-form/src/main/java/com/fr/design/mainframe/adaptve/config/impl/CellStyleTriggerPoint.java new file mode 100644 index 000000000..47055eec1 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/adaptve/config/impl/CellStyleTriggerPoint.java @@ -0,0 +1,28 @@ +package com.fr.design.mainframe.adaptve.config.impl; + +import com.fr.design.mainframe.DesignOperationEvent; +import com.fr.design.mainframe.ReuseTriggerPointManager; +import com.fr.design.mainframe.adaptve.config.ReuseNotifyInfo; +import com.fr.design.mainframe.adaptve.config.TriggerPointProvider; +import com.fr.event.Event; + +/** + * Created by kerry on 5/7/21 + */ +public class CellStyleTriggerPoint implements TriggerPointProvider { + @Override + public void triggerAction() { + ReuseNotifyInfo notifyInfo = ReuseTriggerPointManager.getInstance().getReuseNotifyInfo(); + if (notifyInfo == null) { + return; + } + notifyInfo.addCellStyleModify(); + ReuseTriggerPointManager.getInstance().reuseNotify(notifyInfo); + + } + + @Override + public Event triggerEvent() { + return DesignOperationEvent.CELL_STYLE_MODIFY; + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/adaptve/config/impl/CellValueImageChangeTriggerPoint.java b/designer-form/src/main/java/com/fr/design/mainframe/adaptve/config/impl/CellValueImageChangeTriggerPoint.java new file mode 100644 index 000000000..1429ebeab --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/adaptve/config/impl/CellValueImageChangeTriggerPoint.java @@ -0,0 +1,27 @@ +package com.fr.design.mainframe.adaptve.config.impl; + +import com.fr.design.mainframe.DesignOperationEvent; +import com.fr.design.mainframe.ReuseTriggerPointManager; +import com.fr.design.mainframe.adaptve.config.ReuseNotifyInfo; +import com.fr.design.mainframe.adaptve.config.TriggerPointProvider; +import com.fr.event.Event; + +/** + * Created by kerry on 5/7/21 + */ +public class CellValueImageChangeTriggerPoint implements TriggerPointProvider { + @Override + public void triggerAction() { + ReuseNotifyInfo notifyInfo = ReuseTriggerPointManager.getInstance().getReuseNotifyInfo(); + if (notifyInfo == null) { + return; + } + notifyInfo.addCellImageValueModify(); + ReuseTriggerPointManager.getInstance().reuseNotify(notifyInfo); + } + + @Override + public Event triggerEvent() { + return DesignOperationEvent.CELL_IMAGE_VALUE_MODIFY; + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/AbstractWidgetSelectPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/AbstractWidgetSelectPane.java new file mode 100644 index 000000000..96b321c93 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/AbstractWidgetSelectPane.java @@ -0,0 +1,62 @@ +package com.fr.design.mainframe.share; + +import com.fr.design.mainframe.share.ui.base.PopupPreviewPane; +import com.fr.design.mainframe.share.ui.block.PreviewWidgetBlock; +import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.general.ComparatorUtils; +import com.fr.stable.StringUtils; + +import javax.swing.JPanel; +import java.awt.Container; + +/** + * @Author: Yuan.Wang + * @Date: 2021/1/15 + */ +public abstract class AbstractWidgetSelectPane extends JPanel { + private static final int SCROLL_BAR_HEIGHT = 10; + private final PopupPreviewPane previewPane; + private String currentShowWidgetID; + + public AbstractWidgetSelectPane() { + this.previewPane = new PopupPreviewPane(); + } + + public void showPreviewPane(PreviewWidgetBlock comp, String showWidgetID) { + if (ComparatorUtils.equals(currentShowWidgetID, showWidgetID)) { + return; + } + popupPreviewPane(comp, showWidgetID); + } + + public void hidePreviewPane() { + if (previewPane != null && previewPane.isVisible()) { + previewPane.setVisible(false); + } + this.currentShowWidgetID = StringUtils.EMPTY; + } + + private void popupPreviewPane(PreviewWidgetBlock comp, String showWidgetID) { + if (previewPane.isVisible()) { + previewPane.setVisible(false); + } + + if (!previewPane.isVisible() && comp.getWidth() != 0 && comp.getHeight() != 0) { + //父容器是GroupPane,要获得的是GroupPane的父容器 + Container parentContainer =getParentContainer(); + previewPane.setComp(comp.getPreviewImage()); + int popupPosY = comp.getLocationOnScreen().y - parentContainer.getLocationOnScreen().y; + if (previewPane.getHeight() + popupPosY > parentContainer.getHeight() + SCROLL_BAR_HEIGHT) { + popupPosY -= (previewPane.getHeight() + popupPosY - parentContainer.getHeight() - SCROLL_BAR_HEIGHT); + } + int popupPosX = -previewPane.getPreferredSize().width; + if (parentContainer.getLocationOnScreen().x < previewPane.getPreferredSize().width) { + popupPosX = parentContainer.getWidth(); + } + GUICoreUtils.showPopupMenu(previewPane, parentContainer, popupPosX, popupPosY); + this.currentShowWidgetID = showWidgetID; + } + } + + abstract protected Container getParentContainer(); +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/Bean/ComponentGenerateInfo.java b/designer-form/src/main/java/com/fr/design/mainframe/share/Bean/ComponentGenerateInfo.java new file mode 100644 index 000000000..a5bd419a2 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/Bean/ComponentGenerateInfo.java @@ -0,0 +1,59 @@ +package com.fr.design.mainframe.share.Bean; + +import com.fr.design.mainframe.JTemplate; +import com.fr.form.share.DefaultSharableWidget; +import com.fr.form.ui.Widget; + +import java.util.Map; + +/** + * created by Harrison on 2020/04/13 + * + * 组件生成信息 + **/ +public class ComponentGenerateInfo { + + private boolean autoUpload; + + private JTemplate jt; + + private Map paraMap; + + private Widget widget; + + private DefaultSharableWidget info; + + public ComponentGenerateInfo(boolean autoUpload, JTemplate jt, Map paraMap, Widget widget, DefaultSharableWidget info) { + + this.autoUpload = autoUpload; + this.jt = jt; + this.paraMap = paraMap; + this.widget = widget; + this.info = info; + } + + public boolean isAutoUpload() { + + return autoUpload; + } + + public JTemplate getJt() { + + return jt; + } + + public Map getParaMap() { + + return paraMap; + } + + public Widget getWidget() { + + return widget; + } + + public DefaultSharableWidget getInfo() { + + return info; + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/Bean/LinkageChangeBean.java b/designer-form/src/main/java/com/fr/design/mainframe/share/Bean/LinkageChangeBean.java new file mode 100644 index 000000000..b286cfb41 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/Bean/LinkageChangeBean.java @@ -0,0 +1,114 @@ +package com.fr.design.mainframe.share.Bean; + +import com.fr.design.mainframe.share.constants.ComponentTypes; +import com.fr.form.share.bean.WidgetDeviceBean; +import com.fr.form.share.bean.WidgetTypeBean; +import com.fr.design.mainframe.share.constants.DisplayDevice; +import com.fr.stable.AssistUtils; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 下拉框与下拉复现框联动状态 + * @author hades + * @version 10.0 + * Created by hades on 2020/6/9 + */ +public class LinkageChangeBean { + + private static final Map> STATE_MAP = new HashMap<>(); + + static { + // all or default + STATE_MAP.put(new LinkageChangeBean(new WidgetDeviceBean(false, false), new WidgetTypeBean(false, false)), ComponentTypes.allTypes()); + STATE_MAP.put(new LinkageChangeBean(new WidgetDeviceBean(true, true), new WidgetTypeBean(true, true)), ComponentTypes.allTypes()); + STATE_MAP.put(new LinkageChangeBean(new WidgetDeviceBean(false, false), new WidgetTypeBean(true, true)), ComponentTypes.allTypes()); + STATE_MAP.put(new LinkageChangeBean(new WidgetDeviceBean(true, true), new WidgetTypeBean(false, false)), ComponentTypes.allTypes()); + + // pc + STATE_MAP.put(new LinkageChangeBean(new WidgetDeviceBean(false, true), new WidgetTypeBean(false, false)), ComponentTypes.allTypesByDevice(DisplayDevice.PC.getType())); + STATE_MAP.put(new LinkageChangeBean(new WidgetDeviceBean(false, true), new WidgetTypeBean(true, true)), ComponentTypes.allTypesByDevice(DisplayDevice.PC.getType())); + + // mobile + STATE_MAP.put(new LinkageChangeBean(new WidgetDeviceBean(true, false), new WidgetTypeBean(false, false)), ComponentTypes.allTypesByDevice(DisplayDevice.MOBILE.getType())); + STATE_MAP.put(new LinkageChangeBean(new WidgetDeviceBean(true, false), new WidgetTypeBean(true, true)), ComponentTypes.allTypesByDevice(DisplayDevice.MOBILE.getType())); + + // report + STATE_MAP.put(new LinkageChangeBean(new WidgetDeviceBean(false, false), new WidgetTypeBean(true, false)), ComponentTypes.REPORT.types()); + STATE_MAP.put(new LinkageChangeBean(new WidgetDeviceBean(true, true), new WidgetTypeBean(true, false)), ComponentTypes.REPORT.types()); + + // chart + STATE_MAP.put(new LinkageChangeBean(new WidgetDeviceBean(false, false), new WidgetTypeBean(false, true)), ComponentTypes.CHART.types()); + STATE_MAP.put(new LinkageChangeBean(new WidgetDeviceBean(true, true), new WidgetTypeBean(false, true)), ComponentTypes.CHART.types()); + + // pc-report + STATE_MAP.put(new LinkageChangeBean(new WidgetDeviceBean(false, true), new WidgetTypeBean(true, false)), ComponentTypes.REPORT.children(DisplayDevice.PC.getType())); + + // pc-chart + STATE_MAP.put(new LinkageChangeBean(new WidgetDeviceBean(false, true), new WidgetTypeBean(false, true)), ComponentTypes.CHART.children(DisplayDevice.PC.getType())); + + // mobile-report + STATE_MAP.put(new LinkageChangeBean(new WidgetDeviceBean(true, false), new WidgetTypeBean(true, false)), ComponentTypes.REPORT.children(DisplayDevice.MOBILE.getType())); + + // mobile-chart + STATE_MAP.put(new LinkageChangeBean(new WidgetDeviceBean(true, false), new WidgetTypeBean(false, true)), ComponentTypes.CHART.children(DisplayDevice.MOBILE.getType())); + + } + + public static List getComboBoxItems(LinkageChangeBean bean) { + return STATE_MAP.get(bean); + } + + private LinkageChangeBean(WidgetDeviceBean widgetDeviceBean, WidgetTypeBean widgetTypeBean) { + this.widgetDeviceBean = widgetDeviceBean; + this.widgetTypeBean = widgetTypeBean; + } + + private WidgetTypeBean widgetTypeBean; + private WidgetDeviceBean widgetDeviceBean; + + public static class Builder { + private boolean report; + private boolean chart; + private boolean mobile; + private boolean pc; + + public Builder setReport(boolean report) { + this.report = report; + return this; + } + + public Builder setChart(boolean chart) { + this.chart = chart; + return this; + } + + public Builder setMobile(boolean mobile) { + this.mobile = mobile; + return this; + } + + public Builder setPc(boolean pc) { + this.pc = pc; + return this; + } + + public LinkageChangeBean build() { + return new LinkageChangeBean(new WidgetDeviceBean(this.mobile, this.pc), new WidgetTypeBean(this.report, this.chart)); + } + } + + @Override + public boolean equals(Object o) { + return o instanceof LinkageChangeBean + && AssistUtils.equals(this.widgetDeviceBean, ((LinkageChangeBean) o).widgetDeviceBean) + && AssistUtils.equals(this.widgetTypeBean, ((LinkageChangeBean) o).widgetTypeBean); + } + + @Override + public int hashCode() { + return AssistUtils.hashCode(this.widgetDeviceBean, this.widgetTypeBean); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/action/CreateComponentAction.java b/designer-form/src/main/java/com/fr/design/mainframe/share/action/CreateComponentAction.java new file mode 100644 index 000000000..1baac868f --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/action/CreateComponentAction.java @@ -0,0 +1,398 @@ +package com.fr.design.mainframe.share.action; + +import com.fr.base.Parameter; +import com.fr.base.ParameterMapNameSpace; +import com.fr.base.TableData; +import com.fr.chart.chartattr.Chart; +import com.fr.chart.chartattr.ChartCollection; +import com.fr.chart.chartdata.TableDataDefinition; +import com.fr.data.impl.NameTableData; +import com.fr.data.impl.TableDataDictionary; +import com.fr.design.actions.UpdateAction; +import com.fr.design.data.DesignTableDataManager; +import com.fr.design.designer.creator.XCreator; +import com.fr.design.dialog.BasicPane; +import com.fr.design.dialog.DialogActionAdapter; +import com.fr.design.dialog.FineJOptionPane; +import com.fr.design.file.HistoryTemplateListPane; +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.DesignerFrame; +import com.fr.design.mainframe.FormSelection; +import com.fr.design.mainframe.JForm; +import com.fr.design.mainframe.JTemplate; +import com.fr.design.mainframe.share.constants.ShareEntryKey; +import com.fr.design.mainframe.share.select.ComponentTransformerFactory; +import com.fr.design.parameter.ParameterInputPane; +import com.fr.form.FormElementCaseProvider; +import com.fr.form.main.Form; +import com.fr.form.main.FormIO; +import com.fr.form.main.WidgetGather; +import com.fr.form.ui.BaseChartEditor; +import com.fr.form.ui.ChartEditor; +import com.fr.form.ui.DataControl; +import com.fr.form.ui.DictionaryContainer; +import com.fr.form.ui.ElementCaseEditor; +import com.fr.form.ui.Widget; +import com.fr.general.IOUtils; +import com.fr.log.FineLoggerFactory; +import com.fr.report.cell.DefaultTemplateCellElement; +import com.fr.report.cell.cellattr.core.group.DSColumn; +import com.fr.script.Calculator; +import com.fr.stable.ArrayUtils; +import com.fr.stable.Constants; +import com.fr.stable.CoreGraphHelper; +import com.fr.stable.DependenceProvider; +import com.fr.stable.ParameterProvider; +import com.fr.stable.StringUtils; +import com.fr.stable.bridge.StableFactory; +import com.fr.stable.script.CalculatorProvider; +import com.fr.stable.script.NameSpace; +import com.fr.third.guava.base.Preconditions; +import com.fr.third.org.apache.commons.lang3.tuple.ImmutableTriple; +import com.fr.third.org.apache.commons.lang3.tuple.Triple; + +import javax.swing.Action; +import javax.swing.UIManager; +import java.awt.Color; +import java.awt.Component; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.Rectangle; +import java.awt.event.ActionEvent; +import java.awt.image.BufferedImage; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Callable; +import java.util.concurrent.FutureTask; +import java.util.concurrent.TimeUnit; + +import static javax.swing.JOptionPane.ERROR_MESSAGE; + +/** + * @Author: Yuan.Wang + * @Date: 2020/11/3 + * 创建组件事件 + */ +public class CreateComponentAction extends UpdateAction { + ShareUIAspect aspect; + /** + * 等待时间 500 ms. + */ + private static final int WAIT_TIME = 500; + + private final HashMap parameterMap = new HashMap<>(); + private String[] widgetPara = new String[]{}; + + + public CreateComponentAction(ShareUIAspect aspect) { + this.putValue(Action.SMALL_ICON, null); + this.setName(Toolkit.i18nText("Fine-Design_Share_Create")); + this.aspect = aspect; + } + + @Override + public void actionPerformed(ActionEvent event) { + DesignerFrame designerFrame = DesignerContext.getDesignerFrame(); + // 停止编辑 + JTemplate jt = HistoryTemplateListPane.getInstance().getCurrentEditingTemplate(); + jt.stopEditing(); + Form form = null; + try { + form = (Form) jt.getTarget().clone(); + } catch (CloneNotSupportedException e1) { + FineLoggerFactory.getLogger().error(e1.getMessage(), e1); + } + FormSelection selection = ((JForm) jt).getFormDesign().getSelectionModel().getSelection(); + + // 获取选中的组件 + Triple sharedTriple = ComponentTransformerFactory.getInstance().transform(selection); + if (sharedTriple == null) { + FineJOptionPane.showMessageDialog(designerFrame, Toolkit.i18nText("Fine-Design_Share_Select_Error_Tip"), + Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"), ERROR_MESSAGE, IOUtils.readIcon("/com/fr/base/images/share/Information_Icon_warning_normal_32x32.png")); + return; + } + + Widget widget = sharedTriple.getLeft(); + + try { + + if (form == null) { + throw new NullPointerException("tpl get failed"); + } + //准备参数 + prepareParameter(widget, designerFrame); + + //准备的封面大小 + //组件大小 + Rectangle reportRec = FormIO.getContentRect(form); + Image coverImage = toCoverImage(form, sharedTriple, parameterMap, reportRec); + + Object[] compositeArg = new Object[]{jt, widget, sharedTriple.getRight(), coverImage, parameterMap, (ShareUIAspect)aspect}; + HashMap compoClass = new HashMap(); + compoClass.put(Constants.ARG_0, JTemplate.class); + compoClass.put(Constants.ARG_1, Widget.class); + compoClass.put(Constants.ARG_2, Rectangle.class); + compoClass.put(Constants.ARG_3, Image.class); + compoClass.put(Constants.ARG_4, HashMap.class); + compoClass.put(Constants.ARG_5, ShareUIAspect.class); + + BasicPane ShareGuidePane = StableFactory.getMarkedInstanceObjectFromClass(ShareEntryKey.SHARE_GENERATE, compositeArg, compoClass, BasicPane.class); +// ShareGuidePane moduleGuidePane = new ShareGuidePane(jt, widget, sharedTriple.getRight(), coverImage, parameterMap, aspect); + ShareGuidePane.show(); + } catch (Exception e) { + FineJOptionPane.showMessageDialog(designerFrame, Toolkit.i18nText("Fine-Design_Share_Create_Share_Pane_Failed"), + Toolkit.i18nText("Fine-Design_Basic_Error"), ERROR_MESSAGE, UIManager.getIcon("OptionPane.errorIcon")); + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + } + + /** + * 准备参数 + */ + private void prepareParameter(Widget widget, DesignerFrame designerFrame) { + + final Calculator ca = Calculator.createCalculator(); + Parameter[] tplParameters = ((Form)HistoryTemplateListPane.getInstance().getCurrentEditingTemplate().getTarget()).getParameters(); + widgetPara = new String[]{}; + calWidgetParameter(widget, ca); + List tplPList = new ArrayList(); + //只弹出使用到参数,其他的不要 + for (String wp : widgetPara) { + for (Parameter tplParameter : tplParameters) { + if (wp.length() > 0 && StringUtils.equals(wp, tplParameter.getName())) { + tplPList.add(tplParameter); + } else if (wp.contains("$") && StringUtils.equals(wp.substring(1, wp.length()), tplParameter.getName())){ + tplPList.add(tplParameter); + } + } + } + Parameter[] parameters = new Parameter[tplPList.size()]; + tplPList.toArray(parameters); + if (ArrayUtils.isNotEmpty(parameters)) {// 检查Parameter. + final ParameterInputPane pPane = new ParameterInputPane(parameters); + pPane.showSmallWindow(designerFrame, new DialogActionAdapter() { + + @Override + public void doOk() { + parameterMap.putAll(pPane.update()); + } + }).setVisible(true); + } + } + + private Triple prepareImageArgs(Triple pair, Rectangle reportRec) { + + Widget widget = pair.getLeft(); + XCreator xCreator = pair.getMiddle(); + Rectangle rectangle = pair.getRight(); + + if (widget instanceof ElementCaseEditor) { + rectangle = reportRec; + } + return new ImmutableTriple<>(widget, xCreator, rectangle); + } + + /** + * 准备封面 + *

+ * 操作可能会很耗时,所以加个时间限制 + */ + private Image toCoverImage(final Form form, + final Triple triple, + final Map parameterMap, + Rectangle reportRec) { + + final Triple imageArgs = prepareImageArgs(triple, reportRec); + FutureTask task = new FutureTask<>(new Callable() { + @Override + public Image call() throws Exception { + + Preconditions.checkNotNull(imageArgs); + Widget widget = imageArgs.getLeft(); + XCreator xCreator = imageArgs.getMiddle(); + Rectangle rectangle = imageArgs.getRight(); + if (widget instanceof ElementCaseEditor) { + return moduleToImage(form, (ElementCaseEditor) widget, parameterMap, rectangle); + } else { + return componentToImage(xCreator, rectangle); + } + } + }); + Thread imgThread = new Thread(task, "img-thread"); + try { + imgThread.start(); + //等待一段时间 + return task.get(WAIT_TIME, TimeUnit.MILLISECONDS); + } catch (Throwable throwable) { + + FineLoggerFactory.getLogger().debug("--- img generate failed ---"); + FineLoggerFactory.getLogger().debug(throwable.getMessage(), throwable); + FineLoggerFactory.getLogger().debug("--- prepare use default img ---"); + try (InputStream in = this.getClass().getResourceAsStream("/com/fr/base/images/share/default_cover.png")) { + //读取默认图表 + return IOUtils.readImage(in); + } catch (Throwable e) { + //随便画一个 + Rectangle realRec = triple.getRight(); + BufferedImage allInOne = CoreGraphHelper.createBufferedImage(realRec.width, realRec.height); + Graphics2D g2d = allInOne.createGraphics(); + g2d.setBackground(Color.white); + return allInOne; + } + } + } + + private Image componentToImage(Component comp, Rectangle rect) { + + BufferedImage im = new BufferedImage((int) rect.getWidth(), (int) rect.getHeight(), BufferedImage.TYPE_INT_ARGB); + comp.paint(im.getGraphics()); + return im; + } + + //画报表块的缩略图 + private Image moduleToImage(Form form, ElementCaseEditor editor, Map parameterMap, Rectangle rect) { + + if (editor == null) { + return new BufferedImage((int) rect.getWidth(), (int) rect.getHeight(), BufferedImage.TYPE_INT_ARGB); + } + FormElementCaseProvider provider = editor.getElementCase(); + provider.setName(editor.getWidgetName()); + provider.setTabledataSource(form); + final Calculator ca = Calculator.createCalculator(); + NameSpace ns = ParameterMapNameSpace.create(parameterMap); + ca.pushNameSpace(ns); + BufferedImage image = provider.toImage(ca, (int) rect.getWidth(), (int) rect.getHeight(), parameterMap, true); + return image; + + } + + //计算容器内使用到的参数 + private void calWidgetParameter(Widget widget, final Calculator ca) { + + Form.traversalWidget(widget, new WidgetGather() { + + @Override + public void dealWith(Widget widget) { + DataControl dc = (DataControl) widget; + TableData tableData = null; + try { + tableData = ((TableDataDictionary)(((DictionaryContainer) dc).getDictionary())).getTableData(); + } catch (Exception ignore) { + //ignore + } + widgetPara = ArrayUtils.addAll(widgetPara, getTableDataPara(tableData)); + + } + + @Override + public boolean dealWithAllCards() { + return true; + } + + }, DataControl.class); + + Form.traversalWidget(widget, new WidgetGather() { + + @Override + public void dealWith(Widget widget) { + ElementCaseEditor el = (ElementCaseEditor) widget; + widgetPara = ArrayUtils.addAll(widgetPara, getCellParameters(el.getElementCase(), ca)); + widgetPara = ArrayUtils.addAll(widgetPara, el.getElementCase().dependence(ca)); + } + + public boolean dealWithAllCards() { + return true; + } + + }, ElementCaseEditor.class); + + Form.traversalWidget(widget, new WidgetGather() { + + @Override + public void dealWith(Widget widget) { + //算的好麻烦,本来直接用dependence就好了,但是表单的selectedChart中的tabledata只有一个name,里面的_tableData是null、、所以从环境中重新取一下 + Chart selectedChart = ((ChartCollection) ((ChartEditor) widget).getChartCollection()).getSelectedChart(); + TableData tableData = null; + try { + tableData = ((TableDataDefinition)selectedChart.getFilterDefinition()).getTableData(); + } catch (Exception ignore) { + //ignore + } + widgetPara = ArrayUtils.addAll(widgetPara, getTableDataPara(tableData)); + } + + public boolean dealWithAllCards() { + return true; + } + + }, BaseChartEditor.class); + } + + private ArrayList getTableDataName(FormElementCaseProvider el, CalculatorProvider ca) { + Iterator it = el.cellIterator(); + ArrayList allECDepends = new ArrayList(); + while(it.hasNext()){ + DefaultTemplateCellElement ce = it.next(); + Object value = ce.getValue(); + //先处理单元格值(图表, 公式) + if(value instanceof DSColumn){ + String[] valueDep = ((DependenceProvider) value).dependence(ca); + allECDepends.addAll(Arrays.asList(valueDep)); + } + } + return allECDepends; + } + + private String[] getTableDataPara(TableData tableData) { + try { + return getTableParameters(((NameTableData) tableData).getName()); + } catch (Exception ignore) { + return new String[]{}; + } + } + + private String[] getCellParameters(FormElementCaseProvider formElementCase,Calculator ca) { + Iterator it = formElementCase.cellIterator(); + ArrayList allECDepends = new ArrayList(); + while(it.hasNext()){ + DefaultTemplateCellElement ce = it.next(); + Object value = ce.getValue(); + //处理单元格值(图表, 公式) + if(value instanceof DependenceProvider){ + String[] valueDep = ((DependenceProvider) value).dependence(ca); + allECDepends.addAll(Arrays.asList(valueDep)); + if (value instanceof DSColumn) { + String[] dsPara = getTableParameters(((DSColumn) value).getDSName()); + allECDepends.addAll(Arrays.asList(dsPara)); + } + } + } + //去掉重复的dependence + HashSet removeRepeat = new HashSet(allECDepends); + return removeRepeat.toArray(new String[removeRepeat.size()]); + } + + //通过tableName获取所用参数 + private String[] getTableParameters(String name) { + final Calculator ca = Calculator.createCalculator(); + ParameterProvider[] parameterProviders = new ParameterProvider[]{}; + TableData tableData = DesignTableDataManager.getEditingTableDataSource().getTableData(name); + //只使用自定义数据集的数据 + if (tableData == null) { + return new String[]{}; + } + parameterProviders = tableData.getParameters(ca); + String[] paras = new String[parameterProviders.length]; + for (int i = 0; i < parameterProviders.length; i++) { + paras[i] = parameterProviders[0].getName(); + } + return paras; + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/action/InstallComponentAction.java b/designer-form/src/main/java/com/fr/design/mainframe/share/action/InstallComponentAction.java new file mode 100644 index 000000000..d3173e36b --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/action/InstallComponentAction.java @@ -0,0 +1,163 @@ +package com.fr.design.mainframe.share.action; + +import com.fr.design.actions.UpdateAction; +import com.fr.design.dialog.BasicDialog; +import com.fr.design.dialog.DialogActionAdapter; +import com.fr.design.dialog.FineJOptionPane; +import com.fr.design.gui.ifilechooser.UINativeFileChooser; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.share.ui.base.FailureMessagePane; +import com.fr.design.mainframe.share.ui.local.LocalWidgetRepoPane; +import com.fr.design.mainframe.share.util.InstallUtils; +import com.fr.design.mainframe.share.util.ShareComponentUtils; +import com.fr.design.mainframe.share.util.ShareUIUtils; +import com.fr.design.os.impl.SupportOSImpl; +import com.fr.form.share.record.ShareWidgetInfoManager; +import com.fr.form.share.utils.ReuxUtils; +import com.fr.log.FineLoggerFactory; + +import javax.swing.Action; +import javax.swing.JFileChooser; +import javax.swing.SwingWorker; +import javax.swing.filechooser.FileNameExtensionFilter; +import java.awt.event.ActionEvent; +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ExecutionException; + +/** + * @Author: Yuan.Wang + * @Date: 2020/12/8 + */ + +public class InstallComponentAction extends UpdateAction { + + public InstallComponentAction() { + this.putValue(Action.SMALL_ICON, null); + this.setName(Toolkit.i18nText("Fine-Design_Share_Install")); + } + + @Override + public void actionPerformed(ActionEvent e) { + + if (SupportOSImpl.NATIVE_CHOOSER.support()) { + UINativeFileChooser nativeFileChooser = new UINativeFileChooser(); + nativeFileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); + nativeFileChooser.setMultiSelectionEnabled(true); + nativeFileChooser.setFileFilter(new FileNameExtensionFilter("reu reus", "reu", "reus")); + nativeFileChooser.setDialogTitle(Toolkit.i18nText("Fine-Design_Basic_Select")); + int returnValue = nativeFileChooser.showOpenDialog(new UILabel()); + installComponent(returnValue, nativeFileChooser.getSelectedFiles()); + } else { + JFileChooser fileChooser = new JFileChooser(); + fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); + fileChooser.setMultiSelectionEnabled(true); + fileChooser.setFileFilter(new FileNameExtensionFilter("reu reus", "reu", "reus")); + int returnValue = fileChooser.showDialog(new UILabel(), Toolkit.i18nText("Fine-Design_Basic_Select")); + installComponent(returnValue, fileChooser.getSelectedFiles()); + } + } + + private void installComponent(int returnValue, File[] selectedFiles) { + if (returnValue != JFileChooser.APPROVE_OPTION) { + return; + } + LocalWidgetRepoPane.getInstance().switch2InstallingPane(); + final File[] chosenFiles = selectedFiles; + new SwingWorker() { + @Override + protected InstallBackInfo doInBackground() { + return batchInstallZipFiles(chosenFiles); + } + + @Override + protected void done() { + try { + InstallBackInfo info = get(); + LocalWidgetRepoPane.getInstance().refreshAllGroupPane(); + showMessageDialog(info); + } catch (InterruptedException | ExecutionException e) { + FineLoggerFactory.getLogger().error(e, e.getMessage()); + } + } + }.execute(); + } + + private InstallBackInfo batchInstallZipFiles(File[] chosenFiles) { + try { + long installTime = System.currentTimeMillis(); + boolean installStatus = true; + //记录安装失败的组件 + List failureList = new ArrayList<>(); + for (File file : chosenFiles) { + installStatus &= installFromDiskZipFile(file, installTime, failureList); + } + ShareWidgetInfoManager.getInstance().saveXmlInfo(); + + boolean needShowMessage = (chosenFiles.length > 1 && chosenFiles.length != failureList.size()) || containRues(chosenFiles); + return new InstallBackInfo(installStatus, needShowMessage, failureList); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + return new InstallBackInfo(false, false, new ArrayList<>()); + } + } + + private void showMessageDialog(InstallBackInfo info) { + if (info.success) { + FineJOptionPane.showMessageDialog(null, Toolkit.i18nText("Fine-Design_Form_Share_Module_OK")); + return; + } + if (info.needShowMessage) { + final FailureMessagePane failureMessagePane = new FailureMessagePane(appendString(info.failureInfo)); + BasicDialog dialog = failureMessagePane.showSmallWindow(DesignerContext.getDesignerFrame(), new DialogActionAdapter() { + }); + dialog.setVisible(true); + } else { + ShareUIUtils.showErrorMessageDialog(Toolkit.i18nText("Fine-Design_Share_Share_Module_Install_Error")); + } + } + + private boolean containRues(File[] chosenFiles) { + for (File file : chosenFiles) { + if (file.getName().endsWith(ReuxUtils.REUS_SUFFIX)) + return true; + } + return false; + } + + private String appendString(List list) { + StringBuilder builder = new StringBuilder(); + for (String str : list) { + builder.append(str).append("\n"); + } + return builder.toString(); + } + + /** + * 安装选中文件 + */ + private boolean installFromDiskZipFile(File chosenFile, long installTime, List failList) { + if (chosenFile == null) { + return false; + } + ShareComponentUtils.checkReadMe(); + boolean isReus = chosenFile.getName().endsWith(ReuxUtils.REUS_SUFFIX); + return isReus ? InstallUtils.installReusFile(chosenFile, installTime, failList) : InstallUtils.installReuFile(chosenFile, installTime, failList); + } + + private static class InstallBackInfo { + final boolean success; + final boolean needShowMessage; + final List failureInfo; + + public InstallBackInfo(boolean success, boolean needShowMessage, List failureInfo) { + this.success = success; + this.needShowMessage = needShowMessage; + this.failureInfo = failureInfo; + } + } + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/action/ShareUIAspect.java b/designer-form/src/main/java/com/fr/design/mainframe/share/action/ShareUIAspect.java new file mode 100644 index 000000000..27643e06a --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/action/ShareUIAspect.java @@ -0,0 +1,9 @@ +package com.fr.design.mainframe.share.action; + +/** + * created by Harrison on 2020/04/22 + **/ +public interface ShareUIAspect { + + void afterOk(); +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/constants/ComponentType.java b/designer-form/src/main/java/com/fr/design/mainframe/share/constants/ComponentType.java new file mode 100644 index 000000000..bb1f1976d --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/constants/ComponentType.java @@ -0,0 +1,18 @@ +package com.fr.design.mainframe.share.constants; + +import java.util.List; + +/** + * created by Harrison on 2020/04/20 + **/ +public interface ComponentType { + + List children(int device); + + /** + * 返回子类型所有 + * + * @return + */ + List types(); +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/constants/ComponentTypes.java b/designer-form/src/main/java/com/fr/design/mainframe/share/constants/ComponentTypes.java new file mode 100644 index 000000000..e7f30c7a2 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/constants/ComponentTypes.java @@ -0,0 +1,193 @@ +package com.fr.design.mainframe.share.constants; + +import com.fr.design.i18n.Toolkit; + +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +/** + * created by Harrison on 2020/04/20 + **/ +public enum ComponentTypes implements ComponentType { + + CHART("Fine-Design_Share_Type_Basic_Element") { + @Override + public List children(int device) { + + return ChartChildTypes.support(device); + } + + @Override + public List types() { + List list = new ArrayList<>(); + for (ChartChildTypes types : ChartChildTypes.values()) { + list.add(types.getLocText()); + } + return list; + } + }, + + REPORT("Fine-Design_Share_Type_Report") { + @Override + public List children(int device) { + + if (DisplayDevice.supportMobile(device)) { + return ReportChildTypes.support(DisplayDevice.MOBILE.getType()); + } + return ReportChildTypes.support(DisplayDevice.PC.getType()); + } + + @Override + public List types() { + List list = new ArrayList<>(); + for (ReportChildTypes types : ReportChildTypes.values()) { + list.add(types.getLocText()); + } + return list; + } + }; + + /** + * 所有类型 + * + * @return + */ + public static List allTypes() { + List allTypes = new ArrayList<>(); + Set set = new LinkedHashSet<>(); + for (ComponentTypes types : values()) { + set.addAll(types.children(DisplayDevice.MOBILE.getType())); + set.addAll(types.children(DisplayDevice.PC.getType())); + } + allTypes.addAll(set); + return allTypes; + } + + /** + * 根据终端返回所有类型 + * + * @param device + * @return + */ + public static List allTypesByDevice(int device) { + List allTypes = new ArrayList<>(); + for (ComponentTypes types : values()) { + allTypes.addAll(types.children(device)); + } + return allTypes; + } + + private enum ReportChildTypes { + + INDICATOR_CARD("Fine-Design_Share_Type_Indicator_Card"), + + TITLE("Fine-Design_Share_Type_Title"), + + DIMENSION_CHANGE("Fine-Design_Share_Type_Dimension_Change"), + + FILL("Fine-Design_Share_Type_Fill", DisplayDevice.MOBILE), + + Directory_Navigation("Fine-Design_Share_Type_Mobile_Directory_Navigation", DisplayDevice.MOBILE), + + + SPECIAL_CARD("Fine-Design_Share_Type_Special_Card"); + + private String locale; + + /** + * @see DisplayDevice + */ + private int support; + + ReportChildTypes(String locale) { + this(locale, DisplayDevice.buildAll()); + } + + ReportChildTypes(String locale, DisplayDevice device) { + this(locale, device.getType()); + } + + ReportChildTypes(String locale, int support) { + this.locale = locale; + this.support = support; + } + + public static List support(int device) { + + List list = new ArrayList<>(); + ReportChildTypes[] values = ReportChildTypes.values(); + for (ReportChildTypes value : values) { + //支持当前设备 + if (DisplayDevice.supportDevice(device, value.support)) { + list.add(value.getLocText()); + } + } + return list; + } + + public String getLocText() { + + return Toolkit.i18nText(this.locale); + } + } + + private enum ChartChildTypes { + + COLUMN_CHART("Fine-Design_Share_Type_Chart_Column"), + + PIE_CHART("Fine-Design_Share_Type_Chart_Pie"), + + FOLD_LINE_CHART("Fine-Design_Share_Type_Chart_Fold_Line"), + + COMBINE_CHART("Fine-Design_Share_Type_Chart_Combine"), + + METER_CHART("Fine-Design_Share_Type_Chart_Meter"), + + MAP_CHART("Fine-Design_Share_Type_Chart_Map"), + + OTHERS("Fine-Design_Share_Type_Chart_Other"), + + DETAIL_LIST("Fine-Design_Share_Type_Detail_List"), + + BASIC_WIDGET("Fine-Design_Share_Type_Basic_Widget"); + + private String locale; + + ChartChildTypes(String locale) { + this.locale = locale; + } + + public static List support(int device) { + + List list = new ArrayList<>(); + ChartChildTypes[] values = ChartChildTypes.values(); + for (ChartChildTypes value : values) { + list.add(value.getLocText()); + } + return list; + } + + public String getLocText() { + + return Toolkit.i18nText(this.locale); + } + } + + private String locale; + + ComponentTypes(String locale) { + this.locale = locale; + } + + public String getLocText() { + + return Toolkit.i18nText(this.locale); + } + + @Override + public String toString() { + return getLocText(); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/constants/DisplayDevice.java b/designer-form/src/main/java/com/fr/design/mainframe/share/constants/DisplayDevice.java new file mode 100644 index 000000000..87f77241c --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/constants/DisplayDevice.java @@ -0,0 +1,66 @@ +package com.fr.design.mainframe.share.constants; + +/** + * created by Harrison on 2020/04/21 + **/ +public enum DisplayDevice { + + NONE(0), + + MOBILE(1), + + PC(2); + + private int type; + + DisplayDevice(int type) { + this.type = type; + } + + public int getType() { + return type; + } + + public static int buildAll() { + + int support = 0; + DisplayDevice[] values = DisplayDevice.values(); + for (DisplayDevice value : values) { + support |= value.getType(); + } + return support; + } + + public static int buildDevice(Iterable devices) { + + int support = 0; + if (devices == null) { + return support; + } + for (DisplayDevice device : devices) { + support |= device.type; + } + return support; + } + + public static boolean supportDevice(int device, int support) { + + return device == buildAll() || (support & device) == device; + } + + public static boolean supportMobile(int device) { + + return (device & MOBILE.getType()) == MOBILE.getType(); + } + + public static boolean supportPC(int device) { + + return (device & PC.getType()) == PC.getType(); + } + + private static int calVal(DisplayDevice device) { + + return 1 << device.type; + } + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/constants/ShareEntryKey.java b/designer-form/src/main/java/com/fr/design/mainframe/share/constants/ShareEntryKey.java new file mode 100644 index 000000000..a873325f5 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/constants/ShareEntryKey.java @@ -0,0 +1,6 @@ +package com.fr.design.mainframe.share.constants; + +public class ShareEntryKey { + static public final String SHARE_GENERATE = "ShareGeneratePane"; + static public final String SHARE_CONFIG = "ShareConfigPane"; +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/constants/StyleTheme.java b/designer-form/src/main/java/com/fr/design/mainframe/share/constants/StyleTheme.java new file mode 100644 index 000000000..1738eb5cb --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/constants/StyleTheme.java @@ -0,0 +1,81 @@ +package com.fr.design.mainframe.share.constants; + +import com.fr.design.i18n.Toolkit; +import com.fr.form.share.bean.StyleThemeBean; +import com.fr.form.share.bean.WidgetFilterInfo; +import com.fr.form.share.bean.WidgetFilterTypeInfo; +import com.fr.form.share.constants.ShareComponentConstants; +import com.fr.form.share.utils.ShareUtils; +import com.fr.general.ComparatorUtils; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * Created by kerry on 2020-12-09 + */ +public enum StyleTheme { + + SIMPLE_FRESH("Fine-Design_Share_Style_Theme_Simple", "1"), + BUSINESS_STABLE("Fine-Design_Share_Style_Theme_Business", "2"), + LIVE_GORGEOUS("Fine-Design_Share_Style_Theme_Live", "3"), + COOL_TECHNOLOGY("Fine-Design_Share_Style_Theme_Cool", "4"), + OTHER_THEME("Fine-Design_Share_Style_Theme_Other", "5"); + + + private final String local; + private final String id; + + StyleTheme(String name, String id) { + this.local = name; + this.id = id; + } + + public String getLocText() { + return Toolkit.i18nText(this.local); + } + + public String getId() { + return this.id; + } + + private static List types() { + List list = new ArrayList<>(); + for (StyleTheme type : StyleTheme.values()) { + list.add(new StyleThemeBean(type.getId(), type.getLocText())); + } + return list; + } + + /** + * 获取样式风格属性list + * + * @return List + */ + public static List getStyleThemeTypeInfo() { + List widgetFilterTypeInfos = ShareUtils.getWidgetFilterTypeInfos(); + if (widgetFilterTypeInfos.isEmpty()) { + return types(); + } + WidgetFilterTypeInfo styleThemeFilterInfo = new WidgetFilterTypeInfo(); + for (WidgetFilterTypeInfo typeInfo : widgetFilterTypeInfos) { + if (ComparatorUtils.equals(ShareComponentConstants.STYLE_THEME_KEY, typeInfo.getKey())) { + styleThemeFilterInfo = typeInfo; + break; + } + } + List resultList = new ArrayList<>(); + List filterInfoList = styleThemeFilterInfo.getFilterItems(); + Iterator infoIterator = filterInfoList.iterator(); + while (infoIterator.hasNext()) { + WidgetFilterInfo filterInfo = infoIterator.next(); + if (!ComparatorUtils.equals(ShareComponentConstants.ALL_STYLE_THEME, filterInfo.getId())) { + resultList.add(new StyleThemeBean(filterInfo.getId(), filterInfo.getName())); + } + } + return resultList; + } + + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/exception/LackOfValueException.java b/designer-form/src/main/java/com/fr/design/mainframe/share/exception/LackOfValueException.java new file mode 100644 index 000000000..53d0b1258 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/exception/LackOfValueException.java @@ -0,0 +1,14 @@ +package com.fr.design.mainframe.share.exception; + +import com.fr.design.i18n.Toolkit; + +/** + * created by Harrison on 2020/04/21 + **/ +public class LackOfValueException extends RuntimeException{ + + public LackOfValueException() { + + super(Toolkit.i18nText("Fine-Design_Share_Lack_Val")); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/generate/AbstractComponentTask.java b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/AbstractComponentTask.java new file mode 100644 index 000000000..0e88a5bf9 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/AbstractComponentTask.java @@ -0,0 +1,9 @@ +package com.fr.design.mainframe.share.generate; + +/** + * created by Harrison on 2020/04/23 + **/ +public abstract class AbstractComponentTask implements ComponentTask { + + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/generate/ComponentBanner.java b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/ComponentBanner.java new file mode 100644 index 000000000..aa812b82a --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/ComponentBanner.java @@ -0,0 +1,14 @@ +package com.fr.design.mainframe.share.generate; + +/** + * created by Harrison on 2020/04/13 + **/ +public interface ComponentBanner { + + /** + * 加载文字 + * + * @return 加载 + */ + String getLoadingText(); +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/generate/ComponentCreatorProcessor.java b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/ComponentCreatorProcessor.java new file mode 100644 index 000000000..4d38dc98a --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/ComponentCreatorProcessor.java @@ -0,0 +1,20 @@ +package com.fr.design.mainframe.share.generate; + +import com.fr.design.mainframe.JTemplate; +import com.fr.form.share.DefaultSharableWidget; +import com.fr.form.share.bean.ComponentReuBean; +import com.fr.form.ui.Widget; +import com.fr.stable.fun.mark.Immutable; + +import java.util.Map; + +/** + * Created by kerry on 2020-07-30 + */ +public interface ComponentCreatorProcessor extends ComponentBanner, Immutable { + + String MARK_STRING = "ComponentCreatorProcessor"; + int CURRENT_LEVEL = 1; + + ComponentReuBean create(JTemplate jt, Map paraMap, Widget widget, DefaultSharableWidget info) throws Exception; +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/generate/ComponentGenerator.java b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/ComponentGenerator.java new file mode 100644 index 000000000..5728f8fee --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/ComponentGenerator.java @@ -0,0 +1,22 @@ +package com.fr.design.mainframe.share.generate; + +/** + * created by Harrison on 2020/04/16 + **/ +public interface ComponentGenerator { + + /** + * 生成组件 + * + * @return 组件 + */ + boolean generate() throws Throwable; + + /** + * 耗时/速率 + * + * @return 时间 + */ + int speed(); + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/generate/ComponentGeneratorCenter.java b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/ComponentGeneratorCenter.java new file mode 100644 index 000000000..739ad2390 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/ComponentGeneratorCenter.java @@ -0,0 +1,68 @@ +package com.fr.design.mainframe.share.generate; + +import com.fr.design.mainframe.share.Bean.ComponentGenerateInfo; +import com.fr.design.mainframe.share.generate.impl.ComponentPureGenerator; +import com.fr.design.mainframe.share.generate.impl.ComponentUploadGenerator; +import com.fr.design.mainframe.share.ui.base.ShareProgressBar; +import com.fr.log.FineLoggerFactory; + +import java.util.concurrent.Future; + +/** + * created by Harrison on 2020/04/13 + **/ +public class ComponentGeneratorCenter { + + private ComponentGenerateInfo info; + + public ComponentGeneratorCenter(ComponentGenerateInfo info) { + + this.info = info; + } + + public boolean generate() throws Exception { + + try { + + return generate0(); + } catch (RuntimeException e) { + throw e; + } catch (Throwable throwable) { + FineLoggerFactory.getLogger().error(throwable.getMessage(), throwable); + return false; + } finally { + ShareProgressBar.getInstance().completeNow(); + } + } + + private boolean generate0() throws Throwable{ + + ComponentGenerator generator = innerGenerator(); + + //ui + ShareProgressBar progressBar = ShareProgressBar.getInstance(); + progressBar.prepare(generator.speed()); + progressBar.monitor(); + + return generator.generate(); + } + + private void waitComplete(Future complete) { + + try { + complete.get(); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + } + + private ComponentGenerator innerGenerator() { + + if (info.isAutoUpload()) { + return ComponentUploadGenerator.create(info); + } else { + return ComponentPureGenerator.create(info); + } + } + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/generate/ComponentTask.java b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/ComponentTask.java new file mode 100644 index 000000000..3fb8521f7 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/ComponentTask.java @@ -0,0 +1,13 @@ +package com.fr.design.mainframe.share.generate; + +/** + * created by Harrison on 2020/04/23 + **/ +public interface ComponentTask { + + T execute() throws Exception; + + double indicator(); + + String getLoadingText(); +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/generate/ComponentTaskAdaptor.java b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/ComponentTaskAdaptor.java new file mode 100644 index 000000000..16b8f9774 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/ComponentTaskAdaptor.java @@ -0,0 +1,26 @@ +package com.fr.design.mainframe.share.generate; + +/** + * created by Harrison on 2020/04/23 + **/ +public abstract class ComponentTaskAdaptor extends AbstractComponentTask { + + private double indicator; + + private String loadingText; + + public ComponentTaskAdaptor(double indicator, String loadingText) { + this.indicator = indicator; + this.loadingText = loadingText; + } + + @Override + public double indicator() { + return this.indicator; + } + + @Override + public String getLoadingText() { + return this.loadingText; + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/generate/impl/AbstractComponentCreatorProcessor.java b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/impl/AbstractComponentCreatorProcessor.java new file mode 100644 index 000000000..e0d17bfed --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/impl/AbstractComponentCreatorProcessor.java @@ -0,0 +1,24 @@ +package com.fr.design.mainframe.share.generate.impl; + +import com.fr.design.mainframe.share.generate.ComponentCreatorProcessor; +import com.fr.stable.fun.mark.API; + +/** + * Created by kerry on 2020-07-30 + */ +@API(level = ComponentCreatorProcessor.CURRENT_LEVEL) +public abstract class AbstractComponentCreatorProcessor implements ComponentCreatorProcessor { + + + @Override + public int currentAPILevel() { + return CURRENT_LEVEL; + } + + @Override + public int layerIndex() { + return DEFAULT_LAYER_INDEX; + } + + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/generate/impl/AbstractComponentGenerator.java b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/impl/AbstractComponentGenerator.java new file mode 100644 index 000000000..6fb514117 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/impl/AbstractComponentGenerator.java @@ -0,0 +1,161 @@ +package com.fr.design.mainframe.share.generate.impl; + +import com.fr.design.mainframe.share.Bean.ComponentGenerateInfo; +import com.fr.design.mainframe.share.generate.ComponentBanner; +import com.fr.design.mainframe.share.generate.ComponentCreatorProcessor; +import com.fr.design.mainframe.share.generate.ComponentGenerator; +import com.fr.design.mainframe.share.generate.ComponentTask; +import com.fr.design.mainframe.share.generate.task.ComponentCreator; +import com.fr.design.mainframe.share.ui.base.ShareProgressBar; +import com.fr.design.mainframe.share.util.ShareUIUtils; +import com.fr.log.FineLoggerFactory; +import com.fr.report.ExtraReportClassManager; +import com.fr.third.org.apache.commons.lang3.time.StopWatch; + +import javax.swing.SwingWorker; +import java.util.concurrent.BrokenBarrierException; +import java.util.concurrent.Callable; +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.FutureTask; +import java.util.concurrent.TimeUnit; + +/** + * created by Harrison on 2020/04/16 + **/ +public abstract class AbstractComponentGenerator implements ComponentGenerator { + + /** + * 默认 40 ms + */ + private static final int DEFAULT_SPEED = 40; + + /** + * 进度 100 + */ + private static final int PROGRESS = 100; + + /** + * 每一个任务平均耗时 2000 ms + */ + private static final int PER_TIME = 2000; + + private final int speed; + + private ComponentGenerateInfo info; + + public AbstractComponentGenerator(ComponentGenerateInfo info, ComponentBanner... banners) { + this.info = info; + this.speed = calSpeed(banners); + } + + public ComponentGenerateInfo getInfo() { + return info; + } + + private int calSpeed(ComponentBanner... banners) { + + if (banners == null || banners.length == 0) { + return DEFAULT_SPEED; + } + return PER_TIME / (PROGRESS / banners.length); + } + + /** + * 进度条 100 + * 目前有 n 个任务 + * 每个任务至少 2000 ms + *

+ * 则平均速度为 2000 / (100/n) + */ + @Override + public int speed() { + + return this.speed; + } + + @Override + public boolean generate() throws Throwable { + + try { + return generate0(); + } catch (ExecutionException e) { + //抛出根本原因 + throw e.getCause(); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + return false; + } + } + + protected abstract boolean generate0() throws InterruptedException, ExecutionException; + + protected T execute(final ComponentTask componentTask) throws InterruptedException, ExecutionException { + + final CyclicBarrier barrier = new CyclicBarrier(2); + Thread UIThread = new Thread(new FutureTask(new Callable() { + @Override + public Void call() throws Exception { + SwingWorker worker = new SwingWorker() { + @Override + protected Void doInBackground() throws Exception { + + StopWatch stopWatch = new StopWatch(); + stopWatch.start(); + + //ui更新 + doUIUpdate(); + + stopWatch.stop(); + long time = stopWatch.getTime(TimeUnit.MILLISECONDS); + if (time < 2000L) { + //不到 2 s + ShareUIUtils.wait((int) (2000L - time)); + } + + //完成更新 + finishUpdate(); + return null; + } + + private int finishUpdate() throws InterruptedException, BrokenBarrierException { + return barrier.await(); + } + + private void doUIUpdate() throws Exception { + ShareProgressBar.getInstance().updateProgress(componentTask.indicator(), componentTask.getLoadingText()); + } + }; + worker.execute(); + return null; + } + })); + UIThread.setName("Component-UIThread"); + + FutureTask task = new FutureTask<>(new Callable() { + @Override + public T call() throws Exception { + T result = componentTask.execute(); + barrier.await(); + return result; + } + }); + Thread workThread = new Thread(task); + workThread.setName("Component-WorkThread"); + parallel(UIThread, workThread); + return task.get(); + } + + private void parallel(Thread UIThread, Thread workThread) { + + UIThread.start(); + workThread.start(); + } + + + public static ComponentCreatorProcessor getComponentCreator(){ + ComponentCreatorProcessor processor = ExtraReportClassManager.getInstance().getSingle(ComponentCreatorProcessor.MARK_STRING, ComponentCreator.class); + return processor; + } + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/generate/impl/ComponentPureGenerator.java b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/impl/ComponentPureGenerator.java new file mode 100644 index 000000000..d03f55240 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/impl/ComponentPureGenerator.java @@ -0,0 +1,57 @@ +package com.fr.design.mainframe.share.generate.impl; + +import com.fr.design.mainframe.share.Bean.ComponentGenerateInfo; +import com.fr.design.mainframe.share.generate.ComponentCreatorProcessor; +import com.fr.design.mainframe.share.generate.ComponentTaskAdaptor; +import com.fr.design.mainframe.share.generate.task.ComponentGenerateComplete; +import com.fr.form.share.bean.ComponentReuBean; + +import java.util.concurrent.ExecutionException; + +/** + * created by Harrison on 2020/04/16 + **/ +public class ComponentPureGenerator extends AbstractComponentGenerator { + + private ComponentCreatorProcessor creator; + + private ComponentGenerateComplete complete; + + private ComponentPureGenerator(ComponentGenerateInfo info, ComponentCreatorProcessor creator, ComponentGenerateComplete complete) { + + super(info, creator, complete); + this.creator = creator; + this.complete = complete; + } + + public static ComponentPureGenerator create(ComponentGenerateInfo info) { + + ComponentCreatorProcessor creator = getComponentCreator(); + ComponentGenerateComplete complete = new ComponentGenerateComplete(); + return new ComponentPureGenerator(info, creator, complete); + } + + @Override + protected boolean generate0() throws InterruptedException, ExecutionException { + + final ComponentGenerateInfo info = getInfo(); + ComponentTaskAdaptor createTest = new ComponentTaskAdaptor(1.0, creator.getLoadingText()) { + @Override + public ComponentReuBean execute() throws Exception { + return creator.create(info.getJt(), info.getParaMap(), info.getWidget(), info.getInfo()); + } + }; + ComponentReuBean bean = execute(createTest); + + ComponentTaskAdaptor completeTask = new ComponentTaskAdaptor(1.0, complete.getLoadingText()) { + @Override + public Void execute() throws Exception { + complete.execute(); + return null; + } + }; + Void result = execute(completeTask); + return true; + } + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/generate/impl/ComponentUploadGenerator.java b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/impl/ComponentUploadGenerator.java new file mode 100644 index 000000000..58084c344 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/impl/ComponentUploadGenerator.java @@ -0,0 +1,99 @@ +package com.fr.design.mainframe.share.generate.impl; + +import com.fr.design.mainframe.share.Bean.ComponentGenerateInfo; +import com.fr.design.mainframe.share.generate.ComponentCreatorProcessor; +import com.fr.design.mainframe.share.generate.ComponentTaskAdaptor; +import com.fr.design.mainframe.share.generate.task.ComponentDesensitize; +import com.fr.design.mainframe.share.generate.task.ComponentEncrypt; +import com.fr.design.mainframe.share.generate.task.ComponentUploadComplete; +import com.fr.design.mainframe.share.generate.task.ComponentUploader; +import com.fr.form.share.bean.ComponentReuBean; + +import java.util.concurrent.ExecutionException; + +/** + * created by Harrison on 2020/04/16 + **/ +public class ComponentUploadGenerator extends AbstractComponentGenerator { + + private ComponentCreatorProcessor creator; + + private ComponentEncrypt encrypt; + + private ComponentDesensitize desensitize; + + private ComponentUploader uploader; + + private ComponentUploadComplete complete; + + private ComponentUploadGenerator(ComponentGenerateInfo info, ComponentCreatorProcessor creator, ComponentEncrypt encrypt, ComponentDesensitize desensitize, ComponentUploader uploader, ComponentUploadComplete complete) { + + super(info, creator, desensitize, encrypt, uploader); + this.creator = creator; + this.encrypt = encrypt; + this.desensitize = desensitize; + this.uploader = uploader; + this.complete = complete; + } + + public static ComponentUploadGenerator create(ComponentGenerateInfo info) { + + ComponentCreatorProcessor creator = getComponentCreator(); + ComponentUploader uploader = new ComponentUploader(); + ComponentEncrypt encrypt = new ComponentEncrypt(); + ComponentDesensitize desensitize = new ComponentDesensitize(); + ComponentUploadComplete complete = new ComponentUploadComplete(); + return new ComponentUploadGenerator(info, creator, encrypt, desensitize, uploader, complete); + } + + @Override + protected boolean generate0() throws InterruptedException, ExecutionException { + final ComponentGenerateInfo info = getInfo(); + //创建 + ComponentTaskAdaptor createTask = new ComponentTaskAdaptor(0.20, creator.getLoadingText()) { + @Override + public ComponentReuBean execute() throws Exception { + return creator.create(info.getJt(), info.getParaMap(), info.getWidget(), info.getInfo()); + } + }; + final ComponentReuBean plainBean = execute(createTask); + + //脱敏 + ComponentTaskAdaptor desensitizeTask = new ComponentTaskAdaptor(0.60, desensitize.getLoadingText()) { + @Override + public Object execute() throws Exception { + desensitize.execute(); + return null; + } + }; + execute(desensitizeTask); + + //加密 + ComponentTaskAdaptor encryptTask = new ComponentTaskAdaptor(0.85, encrypt.getLoadingText()) { + @Override + public ComponentReuBean execute() throws Exception { + return encrypt.execute(plainBean); + } + }; + final ComponentReuBean encryptBean = execute(encryptTask); + + //上传 + ComponentTaskAdaptor uploadTask = new ComponentTaskAdaptor(1.0, uploader.getLoadingText()) { + @Override + public Boolean execute() throws Exception { + return uploader.upload(encryptBean.getPath()); + } + }; + Boolean success = execute(uploadTask); + + //完成 + final ComponentTaskAdaptor completeTask = new ComponentTaskAdaptor(1.0, complete.getLoadingText()) { + @Override + public Boolean execute() throws Exception { + return complete.execute(); + } + }; + return success && execute(completeTask); + } + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/generate/task/ComponentCreator.java b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/task/ComponentCreator.java new file mode 100644 index 000000000..f93e28426 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/task/ComponentCreator.java @@ -0,0 +1,114 @@ +package com.fr.design.mainframe.share.generate.task; + +import com.fr.base.iofile.attr.ExtendSharableAttrMark; +import com.fr.base.iofile.attr.SharableAttrMark; +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.JTemplate; +import com.fr.design.mainframe.share.generate.impl.AbstractComponentCreatorProcessor; +import com.fr.form.main.Form; +import com.fr.form.main.WidgetGatherAdapter; +import com.fr.form.share.DefaultSharableWidget; +import com.fr.form.share.ShareEmbeddedConverter; +import com.fr.form.share.bean.ComponentReuBean; +import com.fr.form.share.editor.DefaultSharableEditor; +import com.fr.form.share.editor.PlainSharableEditor; +import com.fr.form.share.utils.ShareUtils; +import com.fr.form.ui.AbstractBorderStyleWidget; +import com.fr.form.ui.Widget; +import com.fr.log.FineLoggerFactory; +import com.fr.stable.fun.IOFileAttrMark; +import com.fr.workspace.WorkContext; +import org.jetbrains.annotations.NotNull; + +import java.util.HashMap; +import java.util.Map; + +/** + * created by Harrison on 2020/04/13 + **/ +public class ComponentCreator extends AbstractComponentCreatorProcessor { + + /** + * 生成组件 + * 返回组件的路径 + * + * @return 路径 + */ + @Override + public ComponentReuBean create(JTemplate jt, Map paraMap, Widget widget, DefaultSharableWidget info) throws Exception { + + + // 遍历判断是否存在共享组件 + checkOriginStatus(widget, info); + + // 导出内置数据集 + Form form = embeddedForm(jt, paraMap); + + // 创建组件 + DefaultSharableEditor editor = createSharableEditor(form, paraMap, widget, info); + + // 生成组件 + String generatePath = generate(editor, info); + + + return new ComponentReuBean(generatePath, editor, info); + } + + protected void checkOriginStatus(Widget widget, final DefaultSharableWidget info) { + + Form.traversalWidget(widget, new WidgetGatherAdapter() { + @Override + public void dealWith(Widget widget) { + + AbstractBorderStyleWidget borderStyleWidget = (AbstractBorderStyleWidget) widget; + IOFileAttrMark attrMark = borderStyleWidget.getWidgetAttrMark(SharableAttrMark.XML_TAG); + if (attrMark != null) { + info.setTransform(); + } + } + }, AbstractBorderStyleWidget.class); + } + + @Override + public String getLoadingText() { + + return Toolkit.i18nText("Fine-Design_Share_Generate_Ing"); + } + + /** + * 内置数据集处理 + * + * @return 返回 + */ + protected Form embeddedForm(JTemplate jt, Map paraMap) throws Exception { + + jt.stopEditing(); + + Form tpl = null; + try { + tpl = (Form) jt.getTarget().clone(); + } catch (CloneNotSupportedException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + +// //内置数据集 + ShareEmbeddedConverter embeddedConverter = WorkContext.getCurrent().get(ShareEmbeddedConverter.class); + embeddedConverter.convertToEmbeddedTableData(tpl, paraMap); + + return tpl; + } + + @NotNull + protected DefaultSharableEditor createSharableEditor(Form form, Map paraMap, Widget widget, DefaultSharableWidget info) { + + String uuid = info.getId(); + ((AbstractBorderStyleWidget) widget).addWidgetAttrMark(new SharableAttrMark()); + ((AbstractBorderStyleWidget) widget).addWidgetAttrMark(new ExtendSharableAttrMark(uuid)); + return new PlainSharableEditor(uuid, widget, form, (HashMap) paraMap); + } + + protected String generate(Widget editor, DefaultSharableWidget info) throws Exception { + + return ShareUtils.generateModule(editor, info); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/generate/task/ComponentDesensitize.java b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/task/ComponentDesensitize.java new file mode 100644 index 000000000..5c12877ee --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/task/ComponentDesensitize.java @@ -0,0 +1,44 @@ +package com.fr.design.mainframe.share.generate.task; + +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.share.generate.ComponentBanner; +import com.fr.form.share.exception.NetWorkFailedException; +import com.fr.general.http.HttpRequest; +import com.fr.general.http.HttpToolbox; +import com.fr.log.FineLoggerFactory; +import com.fr.third.org.apache.http.HttpStatus; +import com.fr.third.org.apache.http.client.methods.CloseableHttpResponse; + +/** + * created by Harrison on 2020/04/22 + **/ +public class ComponentDesensitize implements ComponentBanner { + + private static final String TEST_URL = "http://www.baidu.com"; + + public void execute() { + + if (!testNet()) { + throw new NetWorkFailedException(); + } + } + + private boolean testNet() { + + try { + HttpRequest httpRequest = HttpRequest.custom().url(TEST_URL).build(); + CloseableHttpResponse response = HttpToolbox.execute(httpRequest); + if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { + return true; + } + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + return false; + } + + @Override + public String getLoadingText() { + return Toolkit.i18nText("Fine-Design_Share_Desensitize"); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/generate/task/ComponentEncrypt.java b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/task/ComponentEncrypt.java new file mode 100644 index 000000000..b0cd6ef57 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/task/ComponentEncrypt.java @@ -0,0 +1,28 @@ +package com.fr.design.mainframe.share.generate.task; + +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.share.generate.ComponentBanner; +import com.fr.form.share.bean.ComponentReuBean; +import com.fr.workspace.WorkContext; + +/** + * created by Harrison on 2020/04/22 + **/ +public class ComponentEncrypt implements ComponentBanner { + + public ComponentReuBean execute(ComponentReuBean bean) throws Exception { + + try { + return bean; + } catch (Exception e) { + String path = bean.getPath(); + WorkContext.getWorkResource().delete(path); + throw e; + } + } + + @Override + public String getLoadingText() { + return Toolkit.i18nText("Fine-Design_Share_Encrypt"); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/generate/task/ComponentGenerateComplete.java b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/task/ComponentGenerateComplete.java new file mode 100644 index 000000000..47909b849 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/task/ComponentGenerateComplete.java @@ -0,0 +1,19 @@ +package com.fr.design.mainframe.share.generate.task; + +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.share.generate.ComponentBanner; + +/** + * created by Harrison on 2020/04/13 + **/ +public class ComponentGenerateComplete implements ComponentBanner { + + public void execute() throws InterruptedException { + } + + @Override + public String getLoadingText() { + + return Toolkit.i18nText("Fine-Design_Share_Generate_Success"); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/generate/task/ComponentUploadComplete.java b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/task/ComponentUploadComplete.java new file mode 100644 index 000000000..289e2074c --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/task/ComponentUploadComplete.java @@ -0,0 +1,19 @@ +package com.fr.design.mainframe.share.generate.task; + +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.share.generate.ComponentBanner; + +/** + * created by Harrison on 2020/06/16 + **/ +public class ComponentUploadComplete implements ComponentBanner { + + public boolean execute() throws InterruptedException { + return true; + } + + @Override + public String getLoadingText() { + return Toolkit.i18nText("Fine-Design_Share_Upload_Success"); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/generate/task/ComponentUploader.java b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/task/ComponentUploader.java new file mode 100644 index 000000000..ef74d3420 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/task/ComponentUploader.java @@ -0,0 +1,153 @@ +package com.fr.design.mainframe.share.generate.task; + +import com.fr.config.MarketConfig; +import com.fr.design.i18n.Toolkit; +import com.fr.form.share.config.ComponentReuseConfigManager; +import com.fr.design.mainframe.share.generate.ComponentBanner; +import com.fr.io.utils.ResourceIOUtils; +import com.fr.log.FineLoggerFactory; +import com.fr.third.org.apache.http.HttpEntity; +import com.fr.third.org.apache.http.HttpStatus; +import com.fr.third.org.apache.http.client.config.CookieSpecs; +import com.fr.third.org.apache.http.client.config.RequestConfig; +import com.fr.third.org.apache.http.client.entity.UrlEncodedFormEntity; +import com.fr.third.org.apache.http.client.methods.CloseableHttpResponse; +import com.fr.third.org.apache.http.client.methods.HttpPost; +import com.fr.third.org.apache.http.conn.ssl.NoopHostnameVerifier; +import com.fr.third.org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import com.fr.third.org.apache.http.entity.mime.HttpMultipartMode; +import com.fr.third.org.apache.http.entity.mime.MultipartEntityBuilder; +import com.fr.third.org.apache.http.entity.mime.content.ByteArrayBody; +import com.fr.third.org.apache.http.impl.client.BasicCookieStore; +import com.fr.third.org.apache.http.impl.client.CloseableHttpClient; +import com.fr.third.org.apache.http.impl.client.HttpClients; +import com.fr.third.org.apache.http.message.BasicNameValuePair; +import com.fr.third.org.apache.http.ssl.SSLContextBuilder; +import com.fr.third.org.apache.http.ssl.TrustStrategy; +import com.fr.workspace.WorkContext; +import org.jetbrains.annotations.NotNull; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLContext; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.List; + +/** + * 组件上传 + *

+ * created by Harrison on 2020/04/13 + **/ +public class ComponentUploader implements ComponentBanner { + + //private static final String MARKET_LOGIN = CloudCenter.getInstance().acquireUrlByKind("market.login", "https://market.fanruan.com/ShopServer?pg=login&_=1590635085629"); + //private static final String MARKET_REU_FILE_UPLOAD = CloudCenter.getInstance().acquireUrlByKind("market.reuses.upload", "https://market.fanruan.com/reuses/upload"); + + /** + * 先用临时的。 暂时不上线 + */ + private static final String URL_MARKET_LOGIN = ComponentReuseConfigManager.getInstance().getMarketLoginUrl(); + private static final String URL_MARKET_REU_FILE_UPLOAD = ComponentReuseConfigManager.getInstance().getComponentUploadUrl(); + + private static final String KEY_USERNAME = "username"; + private static final String KEY_PASSWORD = "password"; + private static final String KEY_FILE = "file"; + + public boolean upload(String path) { + + boolean success = false; + try { + success = upload0(path); + } catch (Exception e) { + WorkContext.getWorkResource().delete(path); + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + return success; + } + + @Override + public String getLoadingText() { + + return Toolkit.i18nText("Fine-Design_Share_Encrypt"); + } + + private boolean upload0(String path) throws Exception { + + CloseableHttpClient client = createClient(); + if (login(client)) { + HttpPost uploadRequest = new HttpPost(URL_MARKET_REU_FILE_UPLOAD); + byte[] bytes = WorkContext.getWorkResource().readFully(path); + String fileName = ResourceIOUtils.getName(path); + HttpEntity reqEntity = MultipartEntityBuilder.create() + .setCharset(StandardCharsets.UTF_8) + .setMode(HttpMultipartMode.BROWSER_COMPATIBLE) + // 相当于 + .addPart(KEY_FILE, new ByteArrayBody(bytes, fileName)) + .build(); + uploadRequest.setEntity(reqEntity); + + // 发起请求 并返回请求的响应 + CloseableHttpResponse uploadResponse = client.execute(uploadRequest); + FineLoggerFactory.getLogger().info(uploadResponse.toString()); + return uploadResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK; + } + return false; + } + + private boolean login(CloseableHttpClient client) throws IOException { + + String bbsUsername = MarketConfig.getInstance().getBbsUsername(); + String bbsPassword = MarketConfig.getInstance().getBbsPassword(); + List pairs = new ArrayList<>(); + pairs.add(new BasicNameValuePair(KEY_USERNAME, bbsUsername)); + pairs.add(new BasicNameValuePair(KEY_PASSWORD, bbsPassword)); + + HttpPost login = new HttpPost(URL_MARKET_LOGIN); + login.setEntity(new UrlEncodedFormEntity(pairs, StandardCharsets.UTF_8)); + login.addHeader("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36"); + login.addHeader("Connection", "keep-alive"); + CloseableHttpResponse loginResponse = client.execute(login); + FineLoggerFactory.getLogger().info(loginResponse.toString()); + return loginResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK; + } + + private static CloseableHttpClient createClient() throws Exception { + + SSLConnectionSocketFactory connectionFactory = createSSL(); + + BasicCookieStore cookieStore = new BasicCookieStore(); + return HttpClients.custom() + .setDefaultRequestConfig(RequestConfig.custom() + .setCookieSpec(CookieSpecs.STANDARD) + .setSocketTimeout(2000) + .setConnectTimeout(5000) + .setConnectionRequestTimeout(5000) + .setAuthenticationEnabled(false) + .build()) + .setDefaultCookieStore(cookieStore) + .setSSLSocketFactory(connectionFactory) + .build(); + } + + @NotNull + private static SSLConnectionSocketFactory createSSL() throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException { + SSLContext sslContext = SSLContextBuilder + .create() + .loadTrustMaterial(new TrustStrategy() { + @Override + public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { + return true; + } + }) + .build(); + HostnameVerifier allowAllHosts = new NoopHostnameVerifier(); + return new SSLConnectionSocketFactory(sslContext, allowAllHosts); + } + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/group/ui/BaseGroupDialog.java b/designer-form/src/main/java/com/fr/design/mainframe/share/group/ui/BaseGroupDialog.java new file mode 100644 index 000000000..e9d5d490b --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/group/ui/BaseGroupDialog.java @@ -0,0 +1,59 @@ +package com.fr.design.mainframe.share.group.ui; + +import com.fr.base.BaseUtils; +import com.fr.design.dialog.UIDialog; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.i18n.Toolkit; +import com.fr.design.utils.gui.GUICoreUtils; + +import javax.swing.JDialog; +import java.awt.Dimension; +import java.awt.Frame; + +/** + * @Author: Yuan.Wang + * @Date: 2020/12/9 + */ +abstract public class BaseGroupDialog extends UIDialog { + public BaseGroupDialog(Frame parent) { + super(parent); + } + + protected UIButton createConfirmButton() { + UIButton confirmButton; + + confirmButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Confirm")); + confirmButton.setPreferredSize(new Dimension(60, 25)); + confirmButton.setEnabled(false); + confirmButton.addActionListener(e -> confirmClose()); + return confirmButton; + } + + protected UIButton createCancelButton() { + UIButton cancelButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Cancel")); + cancelButton.setPreferredSize(new Dimension(60, 25)); + + cancelButton.addActionListener(e -> dispose()); + return cancelButton; + } + + /** + * 点击确定后的处理方法 + */ + abstract protected void confirmClose(); + + protected void initStyle() { + this.setSize(340, 180); + this.setResizable(false); + this.setAlwaysOnTop(true); + this.setIconImage(BaseUtils.readImage("/com/fr/base/images/oem/logo.png")); + this.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); + GUICoreUtils.centerWindow(this); + this.setVisible(true); + } + + @Override + public void checkValid() throws Exception { + // do nothing + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/group/ui/GroupFileDialog.java b/designer-form/src/main/java/com/fr/design/mainframe/share/group/ui/GroupFileDialog.java new file mode 100644 index 000000000..f4b79944e --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/group/ui/GroupFileDialog.java @@ -0,0 +1,173 @@ +package com.fr.design.mainframe.share.group.ui; + +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.gui.itextfield.UITextField; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.TableLayout; +import com.fr.design.layout.TableLayoutHelper; +import com.fr.stable.StringUtils; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.SwingConstants; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; + +/** + * @Author: Yuan.Wang + * @Date: 2020/10/29 + */ +abstract public class GroupFileDialog extends BaseGroupDialog { + + private UITextField nameField; + + private UILabel warnLabel; + + private final UIButton confirmButton; + + public GroupFileDialog(Frame frame, String title) { + this(frame, title, StringUtils.EMPTY); + + } + + public GroupFileDialog(Frame frame, String title, String defaultName) { + super(frame); + this.setLayout(new BorderLayout()); + this.setModal(true); + + setTitle(title); + // 标签 + UILabel newNameLabel = creteNewNameLabel(); + // 输入框 + createNameField(defaultName); + // 重名提示 + createWarnLabel(); + // 确认按钮 + confirmButton = createConfirmButton(); + // 取消按钮 + UIButton cancelButton = createCancelButton(); + + JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 5)); + topPanel.setBorder(BorderFactory.createEmptyBorder(15, 15, 0, 15)); + topPanel.add(newNameLabel); + topPanel.add(nameField); + + JPanel midPanel = new JPanel(new BorderLayout()); + midPanel.setBorder(BorderFactory.createEmptyBorder(0, 15, 0, 15)); + midPanel.add(warnLabel, BorderLayout.WEST); + + JPanel bottomPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); + bottomPanel.setBorder(BorderFactory.createEmptyBorder(0, 15, 0, 15)); + bottomPanel.add(confirmButton); + bottomPanel.add(cancelButton); + + this.add( + TableLayoutHelper.createTableLayoutPane( + new Component[][]{ + new Component[]{topPanel}, + new Component[]{midPanel}, + new Component[]{bottomPanel} + }, + new double[]{TableLayout.FILL, TableLayout.FILL, TableLayout.FILL}, + new double[]{TableLayout.FILL} + ), BorderLayout.CENTER); + initStyle(); + } + + protected String getFileName() { + return nameField.getText().trim(); + } + + protected void validInput() { + //抽成模板方法 + String userInput = getFileName(); + + if (StringUtils.isEmpty(userInput)) { + confirmButton.setEnabled(false); + return; + } + String name = nameField.getText().trim(); + + if (isDuplicate(name)) { + nameField.selectAll(); + // 如果文件名已存在,则灰掉确认按钮 + warnLabel.setText(Toolkit.i18nText("Fine-Design_Share_Group_Repeat_Name_Info")); + warnLabel.setVisible(true); + confirmButton.setEnabled(false); + } else { + warnLabel.setVisible(false); + confirmButton.setEnabled(true); + } + } + + /** + * 点击确定后的处理方法 + */ + abstract protected void confirmClose(); + + /** + * 是否重名 + */ + abstract protected boolean isDuplicate(String fileName); + + + private UILabel creteNewNameLabel() { + // 输入框前提示 + UILabel newNameLabel = new UILabel(Toolkit.i18nText("Fine-Design_Share_Group_Enter_New_Folder_Name")); + newNameLabel.setHorizontalAlignment(SwingConstants.RIGHT); + newNameLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 10)); + newNameLabel.setPreferredSize(new Dimension(84, 16)); + return newNameLabel; + } + + private void createNameField(String name) { + // 文件名输入框 + nameField = new UITextField(name); + nameField.getDocument().addDocumentListener(new DocumentListener() { + + public void changedUpdate(DocumentEvent e) { + validInput(); + } + + public void insertUpdate(DocumentEvent e) { + validInput(); + } + + public void removeUpdate(DocumentEvent e) { + validInput(); + } + }); + nameField.selectAll(); + nameField.setPreferredSize(new Dimension(200, 20)); + // 增加enter以及esc快捷键的支持 + nameField.addKeyListener(new KeyAdapter() { + @Override + public void keyPressed(KeyEvent e) { + if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { + dispose(); + } else if (e.getKeyCode() == KeyEvent.VK_ENTER) { + if (confirmButton.isEnabled()) { + confirmClose(); + } + } + } + }); + } + + private void createWarnLabel() { + warnLabel = new UILabel(); + warnLabel.setPreferredSize(new Dimension(300, 30)); + warnLabel.setHorizontalAlignment(SwingConstants.LEFT); + warnLabel.setForeground(Color.RED); + warnLabel.setVisible(false); + } +} \ No newline at end of file diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/group/ui/GroupMoveDialog.java b/designer-form/src/main/java/com/fr/design/mainframe/share/group/ui/GroupMoveDialog.java new file mode 100644 index 000000000..c39f195a0 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/group/ui/GroupMoveDialog.java @@ -0,0 +1,79 @@ +package com.fr.design.mainframe.share.group.ui; + +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.icombobox.UIComboBox; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.form.share.group.DefaultShareGroupManager; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.SwingConstants; +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Frame; + +/** + * @Author: Yuan.Wang + * @Date: 2020/12/9 + */ +abstract public class GroupMoveDialog extends BaseGroupDialog { + private UIComboBox selectGroupBox; + + public GroupMoveDialog(Frame frame) { + super(frame); + this.setLayout(new BorderLayout()); + this.setModal(true); + + setTitle(Toolkit.i18nText("Fine-Design_Share_Group_Move")); + // 标签 + UILabel newNameLabel = creteNewNameLabel(); + // 输入框 + createSwitchGroupBox(); + + // 确认按钮 + UIButton confirmButton = createConfirmButton(); + confirmButton.setEnabled(true); + // 取消按钮 + UIButton cancelButton = createCancelButton(); + + JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 5)); + topPanel.setBorder(BorderFactory.createEmptyBorder(15, 15, 0, 15)); + topPanel.add(newNameLabel); + topPanel.add(selectGroupBox); + + JPanel bottomPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); + bottomPanel.setBorder(BorderFactory.createEmptyBorder(0, 15, 0, 15)); + bottomPanel.setPreferredSize(new Dimension(340, 45)); + bottomPanel.add(confirmButton); + bottomPanel.add(cancelButton); + this.add(topPanel, BorderLayout.CENTER); + this.add(bottomPanel, BorderLayout.SOUTH); + + initStyle(); + + + } + + private void createSwitchGroupBox() { + // 文件名输入框 + selectGroupBox = new UIComboBox(DefaultShareGroupManager.getInstance().getAllGroup()); + selectGroupBox.setPreferredSize(new Dimension(225, 20)); + } + + + private UILabel creteNewNameLabel() { + // 输入框前提示 + UILabel newNameLabel = new UILabel(Toolkit.i18nText("Fine-Design_Share_Group_Select")); + newNameLabel.setHorizontalAlignment(SwingConstants.RIGHT); + newNameLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 10)); + newNameLabel.setPreferredSize(new Dimension(60, 16)); + return newNameLabel; + } + + protected UIComboBox getSelectGroupBox() { + return selectGroupBox; + } + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/select/ComponentTransformer.java b/designer-form/src/main/java/com/fr/design/mainframe/share/select/ComponentTransformer.java new file mode 100644 index 000000000..de61f29d2 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/select/ComponentTransformer.java @@ -0,0 +1,25 @@ +package com.fr.design.mainframe.share.select; + +import com.fr.design.designer.creator.XCreator; +import com.fr.design.mainframe.FormSelection; +import com.fr.form.ui.Widget; +import com.fr.third.org.apache.commons.lang3.tuple.Triple; + +import java.awt.Rectangle; + +/** + * 组件选择器 + *

+ * created by Harrison on 2020/06/11 + **/ +public interface ComponentTransformer { + + /** + * 获取选择到组件 + * + * @return 组件相关信息 + */ + Triple transform(FormSelection selection); + +} + diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/select/ComponentTransformerFactory.java b/designer-form/src/main/java/com/fr/design/mainframe/share/select/ComponentTransformerFactory.java new file mode 100644 index 000000000..bf9e6ea61 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/select/ComponentTransformerFactory.java @@ -0,0 +1,53 @@ +package com.fr.design.mainframe.share.select; + +import com.fr.design.designer.creator.XCreator; +import com.fr.design.mainframe.FormSelection; +import com.fr.form.ui.Widget; +import com.fr.stable.AssistUtils; +import com.fr.third.org.apache.commons.lang3.tuple.Triple; +import org.jetbrains.annotations.Nullable; + +import java.awt.Rectangle; + +/** + * created by Harrison on 2020/06/11 + **/ +public class ComponentTransformerFactory { + + private TransformerKey lastKey; + private Triple lastCache; + + private ComponentTransformer transformer = new ComponentTransformerImpl(); + + private static class InstanceHolder { + + private static ComponentTransformerFactory INSTANCE = new ComponentTransformerFactory(); + } + + public static ComponentTransformerFactory getInstance() { + + return InstanceHolder.INSTANCE; + } + + @Nullable + public Triple transform(FormSelection selection) { + + if (selection == null) { + return null; + } + TransformerKey transformerKey = new TransformerKey(selection); + if (AssistUtils.equals(lastKey, transformerKey)) { + return lastCache; + } + Triple triple = transformer.transform(selection); + //缓存一下。 + cache(transformerKey, triple); + return triple; + } + + private void cache(TransformerKey transformerKey, Triple triple) { + + this.lastKey = transformerKey; + this.lastCache = triple; + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/select/ComponentTransformerImpl.java b/designer-form/src/main/java/com/fr/design/mainframe/share/select/ComponentTransformerImpl.java new file mode 100644 index 000000000..af8612608 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/select/ComponentTransformerImpl.java @@ -0,0 +1,156 @@ +package com.fr.design.mainframe.share.select; + +import com.fr.base.FRContext; +import com.fr.design.designer.beans.adapters.component.CompositeComponentAdapter; +import com.fr.design.designer.creator.XCreator; +import com.fr.design.designer.creator.XLayoutContainer; +import com.fr.design.designer.creator.XWAbsoluteLayout; +import com.fr.design.dialog.FineJOptionPane; +import com.fr.design.file.HistoryTemplateListCache; +import com.fr.design.mainframe.FormSelection; +import com.fr.design.mainframe.JTemplate; +import com.fr.design.mainframe.WidgetPropertyPane; +import com.fr.form.main.Form; +import com.fr.form.share.bean.ShareLayoutWidget; +import com.fr.form.ui.AbstractBorderStyleWidget; +import com.fr.form.ui.Widget; +import com.fr.form.ui.container.WAbsoluteBodyLayout; +import com.fr.form.ui.container.WAbsoluteLayout; +import com.fr.form.ui.container.WBorderLayout; +import com.fr.form.ui.container.WFitLayout; +import com.fr.form.ui.container.WLayout; +import com.fr.form.ui.container.WParameterLayout; +import com.fr.form.ui.widget.CRBoundsWidget; +import com.fr.general.Inter; +import com.fr.log.FineLoggerFactory; +import com.fr.third.org.apache.commons.lang3.tuple.ImmutableTriple; +import com.fr.third.org.apache.commons.lang3.tuple.Triple; +import com.fr.web.FormCompVisibleUtils; +import org.jetbrains.annotations.Nullable; + +import java.awt.Dimension; +import java.awt.Rectangle; +import java.awt.Toolkit; +import java.util.Comparator; +import java.util.Map; +import java.util.TreeMap; + +/** + * created by Harrison on 2020/06/11 + **/ +public class ComponentTransformerImpl implements ComponentTransformer { + + @Override + @Nullable + public Triple transform(FormSelection selection) { + + XCreator selectedCreator; + Widget selectedWidget; + if (selection == null) { + return null; + } + Rectangle selectionBounds = selection.getSelctionBounds(); + Rectangle selectedTriple = new Rectangle(0, 0, selectionBounds.width, selectionBounds.height); + XCreator[] xCreators = selection.getSelectedCreators(); + if (xCreators.length == 1) { + selectedCreator = xCreators[0]; + selectedWidget = selectedCreator.toData(); + } else { + + WAbsoluteLayout wAbsoluteLayout = new WAbsoluteLayout("absolute"); + wAbsoluteLayout.setCompState(WAbsoluteLayout.STATE_FIT); + Map widgetMap = new TreeMap<>( + new Comparator() { + @Override + public int compare(Integer o1, Integer o2) { + return o2.compareTo(o1); + } + } + ); + //控件上下层关系需要继承下来 + for (XCreator xCreator : xCreators) { + XLayoutContainer container = (XLayoutContainer) xCreator.getParent(); + int i = container.getComponentZOrder(xCreator); + widgetMap.put(i, xCreator.toData()); + } + JTemplate jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + Form form = (Form) jt.getTarget(); + for (Widget innerWidget : widgetMap.values()) { + WLayout parentWLayout = getParentLayout(form, innerWidget); + if (parentWLayout == null){ + continue; + } + try { + CRBoundsWidget boundsWidget = (CRBoundsWidget) parentWLayout.getBoundsWidget(innerWidget).clone(); + adaptBounds(boundsWidget, selectionBounds); + wAbsoluteLayout.addWidget(boundsWidget); + } catch (CloneNotSupportedException e1) { + FRContext.getLogger().error(e1.getMessage(), e1); + } + } + wAbsoluteLayout.setDesigningResolution(Toolkit.getDefaultToolkit().getScreenSize()); + + selectedCreator = new XWAbsoluteLayout(wAbsoluteLayout, new Dimension(selectedTriple.width, selectedTriple.height)); + selectedWidget = selectedCreator.toData(); + + //将选中的类型初始化一下。 + CompositeComponentAdapter adapter = new CompositeComponentAdapter(WidgetPropertyPane.getInstance().getEditingFormDesigner(), selectedCreator); + adapter.initialize(); + //并且初始化一次。缓存一下值。 + selectedCreator.repaint(); + } + try { + if (!supportShared(selectedWidget)) { + return null; + } + if (!(selectedWidget instanceof AbstractBorderStyleWidget)) { + selectedWidget = new ShareLayoutWidget(selectedWidget); + } + selectedWidget = (Widget) selectedWidget.clone(); + } catch (CloneNotSupportedException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + FineJOptionPane.showMessageDialog(null, Inter.getLocText("Fine-Design_Share_Module_Failed")); + } + return new ImmutableTriple<>(selectedWidget, selectedCreator, selectedTriple); + } + + //先从body中找,如果找不到再从参数面板中找 + @Nullable + private WLayout getParentLayout(Form form, Widget innerWidget) { + WLayout bodyLayout = (WLayout) ((WBorderLayout) form.getContainer()).getLayoutWidget(WBorderLayout.CENTER); + WLayout paraLayout = (WLayout) ((WBorderLayout) form.getContainer()).getLayoutWidget(WBorderLayout.NORTH); + WLayout parentLayout = FormCompVisibleUtils.findFitLayout(bodyLayout, innerWidget); + if (parentLayout == null && paraLayout != null) { + parentLayout = FormCompVisibleUtils.findFitLayout(paraLayout, innerWidget); + } + return parentLayout; + } + + //组件集合产生绝对布局的时候,子组件的bounds需要去掉主框架的xy值,保证边界和绝对布局对齐 + private static void adaptBounds(CRBoundsWidget cRBoundsWidget, Rectangle delRec) { + Rectangle rec = cRBoundsWidget.getBounds(); + int originX = rec.x; + int originY = rec.y; + int delX = delRec.x; + int delY = delRec.y; + cRBoundsWidget.setBounds(new Rectangle(originX - delX, originY - delY, rec.width, rec.height)); + } + + private static boolean supportShared(Widget widget) { + + return notBody(widget) && notForm(widget); + } + + private static boolean notBody(Widget widget) { + return !(widget instanceof WAbsoluteBodyLayout || widget instanceof WFitLayout || widget instanceof WParameterLayout); + } + + private static boolean notForm(Widget widget) { + if (!(widget instanceof WBorderLayout)) { + return true; + } + Widget centerWidget = ((WBorderLayout) widget).getLayoutWidget(WBorderLayout.CENTER); + return notBody(centerWidget); + + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/select/TransformerKey.java b/designer-form/src/main/java/com/fr/design/mainframe/share/select/TransformerKey.java new file mode 100644 index 000000000..221870272 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/select/TransformerKey.java @@ -0,0 +1,112 @@ +package com.fr.design.mainframe.share.select; + +import com.fr.design.designer.creator.XCreator; +import com.fr.design.mainframe.FormSelection; +import com.fr.form.ui.Widget; +import com.fr.general.ComparatorUtils; +import com.fr.log.FineLoggerFactory; +import com.fr.stable.AssistUtils; +import org.jetbrains.annotations.Nullable; + +import java.awt.Rectangle; +import java.util.Arrays; +import java.util.Objects; +import java.util.UUID; + +/** + * created by Harrison on 2020/06/11 + **/ +public class TransformerKey { + + private Rectangle selectionBounds; + + private Widget[] widgets; + + public TransformerKey(FormSelection selection) { + this.selectionBounds = selection.getSelctionBounds(); + this.widgets = deepData(selection.getSelectedCreators()); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + TransformerKey that = (TransformerKey) o; + return Objects.equals(selectionBounds, that.selectionBounds) && + Arrays.equals(widgets, that.widgets); + } + + @Override + public int hashCode() { + int result = Objects.hash(selectionBounds); + result = 31 * result + + Arrays.hashCode(widgets); + return result; + } + + private Widget[] deepData(XCreator[] xCreators) { + if (xCreators == null) { + return new UniqueWidgetWrapper[0]; + } + Widget[] widgets = new Widget[xCreators.length]; + int i = 0; + for (XCreator xCreator : xCreators) { + widgets[i++] = new UniqueWidgetWrapper(cloneWidget(xCreator)); + } + return widgets; + } + + @Nullable + private Widget cloneWidget(XCreator xCreator) { + + try { + return xCreator.toData() != null ? (Widget) xCreator.toData().clone() : null; + } catch (CloneNotSupportedException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + return null; + } + } + + private static class UniqueWidgetWrapper extends Widget { + private String uuid; + private Widget widget; + + public UniqueWidgetWrapper(Widget widget) { + this.widget = widget; + this.uuid = UUID.randomUUID().toString(); + } + + @Override + public String getXType() { + return "UniqueWidgetWrapper"; + } + + @Override + public boolean isEditor() { + return false; + } + + @Override + public String[] supportedEvents() { + return new String[0]; + } + + /** + * hash码 + * + * @return 返回int + */ + @Override + public int hashCode() { + return 31 * super.hashCode() + AssistUtils.hashCode(this.uuid, this.widget); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof UniqueWidgetWrapper + && super.equals(obj) + && ComparatorUtils.equals(((UniqueWidgetWrapper) obj).uuid, this.uuid) + && ComparatorUtils.equals(((UniqueWidgetWrapper) obj).widget, this.widget); + } + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/sort/OnlineWidgetSortType.java b/designer-form/src/main/java/com/fr/design/mainframe/share/sort/OnlineWidgetSortType.java new file mode 100644 index 000000000..437835662 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/sort/OnlineWidgetSortType.java @@ -0,0 +1,153 @@ +package com.fr.design.mainframe.share.sort; + +import com.fr.design.i18n.Toolkit; +import com.fr.form.share.bean.OnlineShareWidget; +import com.fr.form.share.bean.SortParameter; +import com.fr.form.share.utils.ShareUtils; +import com.fr.general.ComparatorUtils; +import com.fr.general.GeneralContext; + +import java.text.Collator; +import java.util.Arrays; +import java.util.Comparator; +import java.util.Date; +import java.util.Map; + + +/** + * Created by kerry on 2020-10-22 + */ +public enum OnlineWidgetSortType implements SortType { + COMPOSITE { + @Override + public void sort(OnlineShareWidget[] widgetProviders) { + Map parameterMap = ShareUtils.getCompositeSortPara(); + Arrays.sort(widgetProviders, new Comparator() { + @Override + public int compare(OnlineShareWidget o1, OnlineShareWidget o2) { + double t1 = getSortValue(o1, parameterMap); + double t2 = getSortValue(o2, parameterMap); + return ComparatorUtils.compareCommonType(t2, t1); + } + }); + } + + private double getSortValue(OnlineShareWidget o, Map parameterMap) { + double a1 = getParaValue("a1", parameterMap), + a2 = getParaValue("a2", parameterMap), + a3 = getParaValue("a3", parameterMap), + b1 = getParaValue("b1", parameterMap), + b2 = getParaValue("b2", parameterMap), + k = getParaValue("k", parameterMap), + q1 = getParaValue("q1", parameterMap), + q2 = getParaValue("q2", parameterMap); + String[] hot2 = new String[]{"report-1", "report-2"}; + String[] hot1 = new String[]{"chart-1", "chart-2", "chart-3", "chart-4", "chart-5", "chart-6"}; + int commentNumber = o.getCommentNumber(), weight = o.getWeight(), downloadTimes = o.getDownloadTimes(); + + double hotValue = a3; + String cid = o.getCid(); + for (String str2 : hot2) { + if (ComparatorUtils.equals(str2, cid)) { + hotValue = a2; + break; + } + } + for (String str1 : hot1) { + if (ComparatorUtils.equals(str1, cid)) { + hotValue = a1; + break; + } + } + + double t = (new Date().getTime() - o.getUploadTime().getTime()) / (3600 * 1000 * 24D); + return q1 * hotValue * Math.pow(2.718, (0 - k) * t) + q2 * (b1 * commentNumber + b2 * downloadTimes) * Math.pow(2.718, (0 - k) * t) + weight; + } + + private double getParaValue(String parameter, Map parameterMap) { + SortParameter sortParameter = parameterMap.get(parameter); + if (sortParameter == null) { + return 0.0D; + } + return sortParameter.getValue(); + } + + + @Override + public String getDisplayName() { + return Toolkit.i18nText("Fine-Design_Share_Composite"); + } + }, + + + SALES { + @Override + public void sort(OnlineShareWidget[] widgetProviders) { + Arrays.sort(widgetProviders, new Comparator() { + @Override + public int compare(OnlineShareWidget o1, OnlineShareWidget o2) { + int t1 = o1.getDownloadTimes(); + int t2 = o2.getDownloadTimes(); + int result = ComparatorUtils.compareCommonType(t2, t1); + if (result == 0) { + result = Collator.getInstance(GeneralContext.getLocale()).compare(o1.getName(), o2.getName()); + } + return result; + } + }); + } + + @Override + public String getDisplayName() { + return Toolkit.i18nText("Fine-Design_Share_Sale"); + } + }, + + NEW_PRODUCT { + @Override + public void sort(OnlineShareWidget[] widgetProviders) { + Arrays.sort(widgetProviders, new Comparator() { + @Override + public int compare(OnlineShareWidget o1, OnlineShareWidget o2) { + long t1 = o1.getUploadTime().getTime(); + long t2 = o2.getUploadTime().getTime(); + int result = ComparatorUtils.compareCommonType(t2, t1); + if (result == 0) { + result = Collator.getInstance(GeneralContext.getLocale()).compare(o1.getName(), o2.getName()); + } + return result; + } + }); + } + + @Override + public String getDisplayName() { + return Toolkit.i18nText("Fine-Design_Share_New_Product"); + } + } + //现在不用,以后可能会用,先注释掉 + /*, + PRICE { + @Override + public void sort(OnlineShareWidget[] widgetProviders) { + Arrays.sort(widgetProviders, new Comparator() { + @Override + public int compare(OnlineShareWidget o1, OnlineShareWidget o2) { + double t1 = o1.getPrice(); + double t2 = o2.getPrice(); + int result = ComparatorUtils.compareCommonType(t2, t1); + if (result == 0) { + result = Collator.getInstance(GeneralContext.getLocale()).compare(o1.getName(), o2.getName()); + } + return result; + } + }); + } + + @Override + public String getDisplayName() { + return Toolkit.i18nText("Fine-Design_Share_Price"); + } + };*/ + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/sort/SortType.java b/designer-form/src/main/java/com/fr/design/mainframe/share/sort/SortType.java new file mode 100644 index 000000000..316bb3c10 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/sort/SortType.java @@ -0,0 +1,12 @@ +package com.fr.design.mainframe.share.sort; + +/** + * @Author: Yuan.Wang + * @Date: 2020/11/19 + */ +public interface SortType { + + void sort(T[] widgetProviders); + + String getDisplayName(); +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/sort/WidgetSortType.java b/designer-form/src/main/java/com/fr/design/mainframe/share/sort/WidgetSortType.java new file mode 100644 index 000000000..a6b8d49b2 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/sort/WidgetSortType.java @@ -0,0 +1,55 @@ +package com.fr.design.mainframe.share.sort; + +import com.fr.design.i18n.Toolkit; +import com.fr.form.share.SharableWidgetProvider; +import com.fr.form.share.record.ShareWidgetInfoManager; +import com.fr.general.ComparatorUtils; +import com.fr.general.GeneralContext; + +import java.text.Collator; +import java.util.Arrays; +import java.util.Comparator; + +/** + * Created by kerry on 2020-07-01 + */ +public enum WidgetSortType implements SortType { + INSTALL_TIME { + @Override + public void sort(SharableWidgetProvider[] widgetProviders) { + Arrays.sort(widgetProviders, new Comparator() { + @Override + public int compare(SharableWidgetProvider o1, SharableWidgetProvider o2) { + long t1 = ShareWidgetInfoManager.getInstance().getCompInstallTime(o1.getName() + "." + o1.getId()); + long t2 = ShareWidgetInfoManager.getInstance().getCompInstallTime(o2.getName() + "." + o2.getId()); + int result = ComparatorUtils.compareCommonType(t2, t1); + if (result == 0) { + result = Collator.getInstance(GeneralContext.getLocale()).compare(o1.getName(), o2.getName()); + } + return result; + } + }); + } + + @Override + public String getDisplayName() { + return Toolkit.i18nText("Fine-Design_Share_Install_Time"); + } + }, + COMPONENT_NAME { + @Override + public void sort(SharableWidgetProvider[] widgetProviders) { + Arrays.sort(widgetProviders, new Comparator() { + @Override + public int compare(SharableWidgetProvider o1, SharableWidgetProvider o2) { + return Collator.getInstance(GeneralContext.getLocale()).compare(o1.getName(), o2.getName()); + } + }); + } + + @Override + public String getDisplayName() { + return Toolkit.i18nText("Fine-Design_Share_Sort_Name"); + } + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/ChartIcon.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/ChartIcon.java new file mode 100644 index 000000000..b52916f9c --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/ChartIcon.java @@ -0,0 +1,91 @@ +package com.fr.design.mainframe.share.ui.base; + +import com.fr.base.chart.BaseChartCollection; +import com.fr.base.chart.BaseChartPainter; +import com.fr.base.chart.chartdata.CallbackEvent; +import com.fr.base.chart.result.WebChartIDInfo; +import com.fr.script.Calculator; + +import javax.swing.Icon; +import java.awt.Color; +import java.awt.Component; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Paint; + +public class ChartIcon implements Icon { + private BaseChartCollection chartCollection; + private CallbackEvent callbackEvent; + + private int width; + private int height; + + /** + * 构造Chart的缩略图Icon + */ + public ChartIcon(BaseChartCollection chartCollection, int width, int height) { + try { + this.chartCollection = (BaseChartCollection) chartCollection.clone(); + } catch (CloneNotSupportedException e) { + this.chartCollection = chartCollection; + } + this.width = width; + this.height = height; + } + + public void registerCallBackEvent(CallbackEvent callbackEvent) { + this.callbackEvent = callbackEvent; + } + + /** + * 画出缩略图Icon + * + * @param g 图形的上下文 + * @param c 所在的Component + * @param x 缩略图的起始坐标x + * @param y 缩略图的起始坐标y + */ + @Override + public void paintIcon(Component c, Graphics g, int x, int y) { + + BaseChartPainter chartPainter = getChartPainter(); + + Graphics2D g2d = (Graphics2D) g; + Paint oldPaint = g2d.getPaint(); + g.translate(x, y); + g2d.setPaint(Color.white); + g2d.fillRect(0, 0, getIconWidth(), getIconHeight()); + + chartPainter.paint(g2d, getIconWidth(), getIconHeight(), 0, null, callbackEvent); + + g.translate(-x, -y); + g2d.setPaint(oldPaint); + } + + protected BaseChartPainter getChartPainter() { + BaseChartPainter painter = chartCollection.createResultChartPainterWithOutDealFormula(Calculator.createCalculator(), + WebChartIDInfo.createEmptyDesignerInfo(), getIconWidth(), getIconHeight()); + return painter; + } + + + /** + * 返回缩略图的宽度 + * + * @return int 缩略图宽度 + */ + @Override + public int getIconWidth() { + return width; + } + + /** + * 返回缩略图的高度 + * + * @return int 缩略图高度 + */ + @Override + public int getIconHeight() { + return height; + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/DictionaryComboCheckBox.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/DictionaryComboCheckBox.java new file mode 100644 index 000000000..2a4fedddb --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/DictionaryComboCheckBox.java @@ -0,0 +1,92 @@ +package com.fr.design.mainframe.share.ui.base; + +import com.fr.design.gui.icombocheckbox.UIComboCheckBox; +import com.fr.design.gui.itextfield.UITextField; +import com.fr.design.i18n.Toolkit; +import com.fr.stable.StringUtils; + +import java.awt.Component; +import java.util.ArrayList; +import java.util.List; + +/** + * created by Harrison on 2020/04/21 + **/ +public class DictionaryComboCheckBox extends UIComboCheckBox { + + private static final String DEFAULT_VALUE_SEPARATOR = ","; + + private static final String EDITOR_FIELD = "editor"; + + private Object[] values; + + private Object[] displays; + + private String locale; + + private UITextField newEditor = null; + + public DictionaryComboCheckBox(Object[] values, String[] displays, String locale) { + super(displays); + init(values, displays); + this.locale = locale; + + installUI(); + } + + private void init(Object[] keys, String[] displays) { + + this.displays = displays; + this.values = keys; + } + + /** + * 这里是有问题的, 这里本身直接获取比较好。 + */ + @Deprecated + private void installUI() { + + Component[] components = getComponents(); + UITextField editor = (UITextField) components[0]; + editor.setPlaceholder(Toolkit.i18nText(locale)); + } + + @Override + public String getText() { + + Object[] selectedValues = getSelectedValues(); + StringBuilder builder = new StringBuilder(); + if (selectedValues != null) { + for (Object value : selectedValues) { + builder.append(value); + builder.append(DEFAULT_VALUE_SEPARATOR); + } + } + //去掉末尾多余的逗号 + return builder.length() > 0 ? builder.substring(0, builder.length() - 1) : StringUtils.EMPTY; + } + + @Override + public Object[] getSelectedValues() { + + Object[] selectedValues = super.getSelectedValues(); + List realValues = new ArrayList<>(); + for (Object selectedValue : selectedValues) { + Object realValue = matchValue(selectedValue); + if (realValue != null) { + realValues.add(realValue); + } + } + return realValues.toArray(); + } + + protected Object matchValue(Object key) { + + for (int i = 0; i < displays.length; i++) { + if (displays[i].equals(key)) { + return values[i]; + } + } + return null; + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/DownloadProgressPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/DownloadProgressPane.java new file mode 100644 index 000000000..c7f09f453 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/DownloadProgressPane.java @@ -0,0 +1,129 @@ +package com.fr.design.mainframe.share.ui.base; + +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.gui.iprogressbar.ModernUIProgressBarUI; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.general.IOUtils; + +import javax.swing.BorderFactory; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JProgressBar; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; + +/** + * @Author: Yuan.Wang + * @Date: 2020/12/24 + * 下载组件包的时候用到的进度条 + */ +public class DownloadProgressPane extends JPanel { + private static final int MAX_NUM = 1000; + + private final UILabel tipLabel; + private final UILabel closeLabel; + private final JProgressBar processBar; + + public DownloadProgressPane(MouseClickListener listener) { + this.setLayout(new BorderLayout()); + this.setBorder(BorderFactory.createEmptyBorder(200, 25, 0, 25)); + + processBar = createProgressBar(); + tipLabel = createTipLabel(); + + JPanel panel = new JPanel(new BorderLayout()); + panel.setOpaque(false); + panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); + panel.setPreferredSize(new Dimension(240, 60)); + panel.add(processBar, BorderLayout.CENTER); + + closeLabel = new UILabel(IOUtils.readIcon("/com/fr/base/images/share/close_small.png")); + closeLabel.addMouseListener(listener); + + JPanel labelPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + labelPane.setOpaque(false); + labelPane.add(tipLabel, BorderLayout.CENTER); + labelPane.add(closeLabel, BorderLayout.EAST); + labelPane.setBorder(BorderFactory.createEmptyBorder(0, 20, 0, 7)); + + UILabel downloadTipLabel = new UILabel(Toolkit.i18nText("Fine-Design_Share_Package_Downloading_Tip")); + downloadTipLabel.setPreferredSize(new Dimension(240, 90)); + downloadTipLabel.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5)); + downloadTipLabel.setForeground(Color.WHITE); + downloadTipLabel.setHorizontalTextPosition(UILabel.CENTER); + + + JPanel centerPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + centerPane.setPreferredSize(new Dimension(240, 138)); + centerPane.add(labelPane, BorderLayout.NORTH); + centerPane.add(panel, BorderLayout.CENTER); + centerPane.add(downloadTipLabel, BorderLayout.SOUTH); + centerPane.setOpaque(false); + + this.add(centerPane, BorderLayout.NORTH); + this.setSize(new Dimension(240, 800)); + this.setBackground(new Color(0, 0, 0, 0)); + this.setOpaque(false); + } + + private UILabel createTipLabel() { + UILabel label = new UILabel(ProcessState.DOWNLOADING.tip); + label.setPreferredSize(new Dimension(200, 20)); + label.setHorizontalAlignment(UILabel.CENTER); + label.setOpaque(false); + label.setForeground(Color.WHITE); + return label; + } + + private JProgressBar createProgressBar() { + JProgressBar jProgressBar = new JProgressBar(); + jProgressBar.setUI(new ModernUIProgressBarUI()); + jProgressBar.setBorderPainted(false); + jProgressBar.setOpaque(false); + jProgressBar.setBorder(null); + jProgressBar.setMaximum(MAX_NUM); + return jProgressBar; + } + + public void changeState() { + tipLabel.setText(ProcessState.INSTALLING.tip); + closeLabel.setVisible(false); + this.validate(); + this.repaint(); + } + + public void updateProgress(double process) { + if (process < 0 || process > 1) { + throw new IllegalArgumentException(); + } + processBar.setValue((int) (process * MAX_NUM)); + } + + + private enum ProcessState { + DOWNLOADING(Toolkit.i18nText("Fine-Design_Share_Package_Downloading")), + INSTALLING(Toolkit.i18nText("Fine-Design_Share_Package_Installing")); + + private final String tip; + + ProcessState(String tip) { + this.tip = tip; + } + } + + public static void main(String[] args) { + JFrame frame = new JFrame(); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setBounds(600, 200, 240, 500); + + DownloadProgressPane pane = new DownloadProgressPane(null); + pane.updateProgress(0.5); + frame.add(pane); + frame.setVisible(true); + + } +} + + diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/FailureMessagePane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/FailureMessagePane.java new file mode 100644 index 000000000..52a57ed4b --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/FailureMessagePane.java @@ -0,0 +1,58 @@ +package com.fr.design.mainframe.share.ui.base; + +import com.fr.design.dialog.BasicPane; +import com.fr.design.gui.frpane.UITextPane; +import com.fr.design.gui.icontainer.UIScrollPane; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.general.IOUtils; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.text.Style; +import javax.swing.text.StyleConstants; +import javax.swing.text.StyleContext; +import java.awt.BorderLayout; +import java.awt.FlowLayout; + +/** + * @Author: Yuan.Wang + * @Date: 2020/9/14 + */ +public class FailureMessagePane extends BasicPane { + public FailureMessagePane(String str) { + UILabel imageLabel = new UILabel(IOUtils.readIcon("/com/fr/base/images/share/error_icon.png")); + UILabel label = new UILabel(Toolkit.i18nText("Fine-Design_Share_Share_Modules_Error")); + UITextPane textPane = new UITextPane(); + UIScrollPane jScrollPane = new UIScrollPane(textPane); + JPanel panel = new JPanel(); + + Style style = new StyleContext().new NamedStyle(); + StyleConstants.setLineSpacing(style, 0.1f); + StyleConstants.setFontSize(style, 12); + textPane.setLogicalStyle(style); + textPane.setText(str); + textPane.setCaretPosition(0); + textPane.setEditable(false); + textPane.setBorder(BorderFactory.createEmptyBorder(3, 5, 3, 5)); + + jScrollPane.setBorder(BorderFactory.createEmptyBorder()); + label.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0)); + + setLayout(new BorderLayout()); + setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 8)); + + panel.add(imageLabel); + panel.add(label); + panel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0)); + panel.setBorder(BorderFactory.createEmptyBorder(4, 0, 4, 0)); + add(panel, BorderLayout.NORTH); + add(jScrollPane, BorderLayout.CENTER); + } + + @Override + protected String title4PopupWindow() { + return Toolkit.i18nText("Fine-Design_Share_Dialog_Message"); + } + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/FlexSearchFieldPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/FlexSearchFieldPane.java new file mode 100644 index 000000000..91b2ce358 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/FlexSearchFieldPane.java @@ -0,0 +1,172 @@ +package com.fr.design.mainframe.share.ui.base; + +import com.fr.base.BaseUtils; +import com.fr.design.event.ChangeEvent; +import com.fr.design.event.ChangeListener; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.gui.itextfield.UITextField; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.general.IOUtils; +import com.fr.stable.StringUtils; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import java.awt.BorderLayout; +import java.awt.CardLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.util.ArrayList; +import java.util.List; + +/** + * Created by kerry on 2020-10-19 + */ +public class FlexSearchFieldPane extends JPanel { + private static final String SEARCH = "SEARCH"; + private static final String OTHER = "OTHER"; + + private static final Color SEARCH_BORDER_COLOR = Color.decode("#F5F5F7"); + private static final Color SEARCH_BORDER_INPUT_COLOR = Color.decode("#419BF9"); + private UITextField searchTextField; + private CardLayout cardLayout; + private JPanel centerPane; + private List changeListenerList = new ArrayList<>(); + private List focusListeners = new ArrayList<>(); + private List deleteIconMouseListener = new ArrayList<>(); + private List fieldDocumentListener = new ArrayList<>(); + + public FlexSearchFieldPane(JPanel otherPane) { + JPanel searchFieldPane = createSearchField(); + JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + jPanel.add(otherPane, BorderLayout.CENTER); + jPanel.add(createSearchLabel(), BorderLayout.EAST); + cardLayout = new CardLayout(); + centerPane = new JPanel(cardLayout); + centerPane.add(searchFieldPane, SEARCH); + centerPane.add(jPanel, OTHER); + cardLayout.show(centerPane, OTHER); + this.add(centerPane, BorderLayout.CENTER); + } + + + private JPanel createSearchLabel() { + JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + UILabel label = new UILabel(IOUtils.readIcon("/com/fr/base/images/share/search_icon.png")); + label.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); + jPanel.add(label, BorderLayout.EAST); + label.addMouseListener(new MouseClickListener() { + @Override + public void mouseClicked(MouseEvent e) { + cardLayout.show(centerPane, SEARCH); + searchTextField.requestFocus(); + } + }); + return jPanel; + } + + private JPanel createSearchField() { + final JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + jPanel.setPreferredSize(new Dimension(228, 20)); + jPanel.setBorder(BorderFactory.createLineBorder(SEARCH_BORDER_COLOR)); + jPanel.setBackground(Color.WHITE); + UILabel label = new UILabel(IOUtils.readIcon("/com/fr/base/images/share/search_icon.png")); + label.setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 0)); + jPanel.add(label, BorderLayout.WEST); + this.searchTextField = new UITextField(); + this.searchTextField.setBorderPainted(false); + this.searchTextField.setPlaceholder(Toolkit.i18nText("Fine-Design_Basic_Plugin_Search")); + this.searchTextField.addFocusListener(new FocusListener() { + @Override + public void focusGained(FocusEvent e) { + jPanel.setBorder(BorderFactory.createLineBorder(SEARCH_BORDER_INPUT_COLOR)); + jPanel.repaint(); + for (FocusListener focusListener : focusListeners) { + focusListener.focusGained(e); + } + } + + @Override + public void focusLost(FocusEvent e) { + jPanel.setBorder(BorderFactory.createLineBorder(SEARCH_BORDER_COLOR)); + jPanel.repaint(); + for (FocusListener focusListener : focusListeners) { + focusListener.focusLost(e); + } + } + }); + this.searchTextField.getDocument().addDocumentListener(new DocumentListener() { + @Override + public void insertUpdate(DocumentEvent e) { + filterByName(); + for (DocumentListener listener : fieldDocumentListener) { + listener.insertUpdate(e); + } + } + + @Override + public void removeUpdate(DocumentEvent e) { + filterByName(); + for (DocumentListener listener : fieldDocumentListener) { + listener.removeUpdate(e); + } + } + + @Override + public void changedUpdate(DocumentEvent e) { + filterByName(); + for (DocumentListener listener : fieldDocumentListener) { + listener.changedUpdate(e); + } + } + }); + jPanel.add(this.searchTextField, BorderLayout.CENTER); + UILabel xLabel = new UILabel(BaseUtils.readIcon("/com/fr/design/images/buttonicon/close_icon.png")); + xLabel.addMouseListener(new MouseClickListener() { + @Override + public void mouseClicked(MouseEvent e) { + searchTextField.setText(StringUtils.EMPTY); + cardLayout.show(centerPane, OTHER); + for (MouseListener listener : deleteIconMouseListener) { + listener.mouseClicked(e); + } + } + }); + xLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); + jPanel.add(xLabel, BorderLayout.EAST); + + + return jPanel; + } + + private void filterByName() { + String text = searchTextField.getText(); + for (ChangeListener listener : changeListenerList) { + listener.fireChanged(new ChangeEvent(text)); + } + } + + public void registerChangeListener(ChangeListener changeListener) { + changeListenerList.add(changeListener); + } + + public void registerSearchTextFieldFocusListener(FocusListener focusListener) { + focusListeners.add(focusListener); + } + + public void registerDeleteIconMouseListener(MouseListener mouseListener) { + deleteIconMouseListener.add(mouseListener); + } + + public void registerFieldDocumentListener(DocumentListener documentListener) { + fieldDocumentListener.add(documentListener); + } + + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/ImageBackgroundPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/ImageBackgroundPane.java new file mode 100644 index 000000000..073dee103 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/ImageBackgroundPane.java @@ -0,0 +1,226 @@ +package com.fr.design.mainframe.share.ui.base; + +import com.fr.base.Style; +import com.fr.base.background.ImageBackground; +import com.fr.base.background.ImageFileBackground; +import com.fr.design.gui.frpane.ImgChooseWrapper; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.ibutton.UIRadioButton; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.style.background.BackgroundDetailPane; +import com.fr.design.style.background.image.ImageFileChooser; +import com.fr.design.style.background.image.ImagePreviewPane; +import com.fr.general.Background; +import com.fr.stable.Constants; + +import javax.swing.BorderFactory; +import javax.swing.ButtonGroup; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import java.awt.BorderLayout; +import java.awt.GridLayout; +import java.awt.Image; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/** + * Image background pane. + */ +public class ImageBackgroundPane extends BackgroundDetailPane { + + protected ImagePreviewPane previewPane = null; + private Style imageStyle = null; + private ChangeListener changeListener = null; + private ImageFileChooser imageFileChooser = null; + protected UILabel imageSizeLabel = new UILabel(); + + protected UIRadioButton defaultRadioButton = null; + protected UIRadioButton tiledRadioButton = null; + private UIRadioButton extendRadioButton = null; + private UIRadioButton adjustRadioButton = null; + + public ImageBackgroundPane() { + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + + // preview pane + JPanel previewContainerPane = FRGUIPaneFactory.createBorderLayout_L_Pane(); + this.add(previewContainerPane, BorderLayout.CENTER); + + JPanel previewOwnerPane = FRGUIPaneFactory.createTitledBorderPane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Preview")); + previewOwnerPane.setLayout(new BorderLayout()); + previewContainerPane.add(previewOwnerPane, BorderLayout.CENTER); + previewContainerPane.add(initSelectFilePane(), BorderLayout.EAST); + previewPane = new ImagePreviewPane(); + previewOwnerPane.add(new JScrollPane(previewPane)); + previewPane.addChangeListener(imageSizeChangeListener); + + + // init image file chooser. + imageFileChooser = new ImageFileChooser(); + imageFileChooser.setMultiSelectionEnabled(false); + } + + public JPanel initSelectFilePane() { + JPanel selectFilePane = FRGUIPaneFactory.createBorderLayout_L_Pane(); + + selectFilePane.setBorder(BorderFactory.createEmptyBorder(8, 2, 4, 0)); + + UIButton selectPictureButton = new UIButton( + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Background_Image_Select")); + selectFilePane.add(selectPictureButton, BorderLayout.NORTH); + selectPictureButton.setMnemonic('S'); + selectPictureButton.addActionListener(selectPictureActionListener); + JPanel layoutPane = FRGUIPaneFactory.createMediumHGapHighTopFlowInnerContainer_M_Pane(); + selectFilePane.add(layoutPane, BorderLayout.CENTER); + + //布局 + defaultRadioButton = new UIRadioButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Layout_Default")); + tiledRadioButton = new UIRadioButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Layout_Image_Titled")); + extendRadioButton = new UIRadioButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Layout_Image_Extend")); + adjustRadioButton = new UIRadioButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Layout_Image_Adjust")); + + defaultRadioButton.addActionListener(layoutActionListener); + tiledRadioButton.addActionListener(layoutActionListener); + extendRadioButton.addActionListener(layoutActionListener); + adjustRadioButton.addActionListener(layoutActionListener); + + JPanel jp = new JPanel(new GridLayout(4, 1, 15, 15)); + for (UIRadioButton button : imageLayoutButtons()) { + jp.add(button); + } + layoutPane.add(jp); + + ButtonGroup layoutBG = new ButtonGroup(); + layoutBG.add(defaultRadioButton); + layoutBG.add(tiledRadioButton); + layoutBG.add(extendRadioButton); + layoutBG.add(adjustRadioButton); + + defaultRadioButton.setSelected(true); + return selectFilePane; + } + + protected UIRadioButton[] imageLayoutButtons() { + return new UIRadioButton[]{ + defaultRadioButton, + tiledRadioButton, + extendRadioButton, + adjustRadioButton + }; + } + + /** + * Select picture. + */ + ActionListener selectPictureActionListener = new ActionListener() { + + public void actionPerformed(ActionEvent evt) { + int returnVal = imageFileChooser.showOpenDialog(ImageBackgroundPane.this); + setImageStyle(); + ImgChooseWrapper.getInstance(previewPane, imageFileChooser, imageStyle, changeListener).dealWithImageFile(returnVal); + } + }; + + protected void setImageStyle() { + if (tiledRadioButton.isSelected()) { + imageStyle = Style.DEFAULT_STYLE.deriveImageLayout(Constants.IMAGE_TILED); + } else if (adjustRadioButton.isSelected()) { + imageStyle = Style.DEFAULT_STYLE.deriveImageLayout(Constants.IMAGE_ADJUST); + } else if (extendRadioButton.isSelected()) { + imageStyle = Style.DEFAULT_STYLE.deriveImageLayout(Constants.IMAGE_EXTEND); + } else { + imageStyle = Style.DEFAULT_STYLE.deriveImageLayout(Constants.IMAGE_CENTER); + } + } + + ActionListener layoutActionListener = new ActionListener() { + + @Override + public void actionPerformed(ActionEvent evt) { + setImageStyle(); + changeImageStyle(); + } + + private void changeImageStyle() { + previewPane.setImageStyle(ImageBackgroundPane.this.imageStyle); + previewPane.repaint(); + } + }; + + @Override + public void populate(Background background) { + + if (background instanceof ImageBackground) { + ImageBackground imageBackground = (ImageBackground) background; + + if (imageBackground.getLayout() == Constants.IMAGE_CENTER) { + defaultRadioButton.setSelected(true); + imageStyle = Style.DEFAULT_STYLE.deriveImageLayout(Constants.IMAGE_CENTER); + } else if (imageBackground.getLayout() == Constants.IMAGE_EXTEND) { + extendRadioButton.setSelected(true); + imageStyle = Style.DEFAULT_STYLE.deriveImageLayout(Constants.IMAGE_EXTEND); + } else if (imageBackground.getLayout() == Constants.IMAGE_ADJUST) { + adjustRadioButton.setSelected(true); + imageStyle = Style.DEFAULT_STYLE.deriveImageLayout(Constants.IMAGE_ADJUST); + } else { + tiledRadioButton.setSelected(true); + imageStyle = Style.DEFAULT_STYLE.deriveImageLayout(Constants.IMAGE_TILED); + } + + previewPane.setImageStyle(ImageBackgroundPane.this.imageStyle); + if (imageBackground.getImage() != null) { + previewPane.setImageWithSuffix(imageBackground.getImageWithSuffix()); + imageSizeLabel.setText(previewPane.getImage().getWidth(null) + + " X " + previewPane.getImage().getHeight(null)); + } + + if (imageBackground.getImage() != null) { + previewPane.setImage(imageBackground.getImage()); + } + } else { + previewPane.setImage(null); + tiledRadioButton.setSelected(true); + + imageSizeLabel.setText(""); + } + + fireChagneListener(); + } + + @Override + public Background update() throws Exception { + ImageBackground imageBackground = new ImageFileBackground(previewPane.getImageWithSuffix()); + setImageStyle(); + imageBackground.setLayout(imageStyle.getImageLayout()); + return imageBackground; + } + + @Override + public void addChangeListener(ChangeListener changeListener) { + this.changeListener = changeListener; + } + + private void fireChagneListener() { + if (this.changeListener != null) { + ChangeEvent evt = new ChangeEvent(this); + this.changeListener.stateChanged(evt); + } + } + + ChangeListener imageSizeChangeListener = new ChangeListener() { + + @Override + public void stateChanged(ChangeEvent evt) { + Image image = ((ImagePreviewPane) evt.getSource()).getImage(); + + if (image == null) { + imageSizeLabel.setText(""); + } else { + imageSizeLabel.setText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Size_Detail", image.getWidth(null) + "x" + image.getHeight(null))); + } + } + }; +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/ImagePanel.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/ImagePanel.java new file mode 100644 index 000000000..a9bc8b787 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/ImagePanel.java @@ -0,0 +1,28 @@ +package com.fr.design.mainframe.share.ui.base; + +import javax.swing.JPanel; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.Toolkit; + +/** + * Created by kerry on 2020-10-23 + */ +public class ImagePanel extends JPanel { + + + private Image image; + + public ImagePanel(String imagePath) { + image = Toolkit.getDefaultToolkit().createImage(ImagePanel.class + .getResource(imagePath)); + } + + @Override + public void paintComponent(Graphics g) { + super.paintComponent(g); + if (image != null) { + g.drawImage(image, 0, 0, 45, 45, this); + } + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/ImitationProgress.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/ImitationProgress.java new file mode 100644 index 000000000..062ca9293 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/ImitationProgress.java @@ -0,0 +1,129 @@ +package com.fr.design.mainframe.share.ui.base; + + +import java.util.concurrent.atomic.AtomicReference; + +/** + * @Author: Yuan.Wang + * @Date: 2020/12/23 + */ +public class ImitationProgress { + private final com.fr.design.extra.Process process; + private static final double TOTAL_NUM = 1000; + private static final double FIRST_STAGE_RATE = 0.8; + private static final int SLEEP_TIME = 600; + + private final AtomicReference state = new AtomicReference<>(ImitationState.NEW); + + private final int num; + private final double initSpeed; + private int currentProgressRate = 0; + + public ImitationProgress(com.fr.design.extra.Process process, int num) { + this.process = process; + this.num = num; + initSpeed = TOTAL_NUM * FIRST_STAGE_RATE / num; + } + + public void start() { + if (!state.compareAndSet(ImitationState.NEW, ImitationState.FIRST_STAGE)) { + return; + } + firstState(); + if (state.compareAndSet(ImitationState.FIRST_STAGE, ImitationState.SECOND_STATE)) { + secondState(); + } + if (state.get() == ImitationState.COMPLETE) { + thirdState(); + } + } + + /** + * 按照预先估计的速度跑完80% + */ + private void firstState() { + int i = 0; + for (; i < num; i++) { + try { + Thread.sleep(SLEEP_TIME); + currentProgressRate += initSpeed; + process.process(currentProgressRate / TOTAL_NUM); + if (state.get() != ImitationState.FIRST_STAGE) { + return; + } + } catch (InterruptedException ignore) { + } + } + } + + /** + * 第一阶段结束但是还没有下载完,则减慢速度跑第二阶段 + */ + private void secondState() { + double speed = TOTAL_NUM * 0.1 / 30; + //70%-90%,30s + int i = 0; + for (; i < 30; i++) { + try { + Thread.sleep(1000); + currentProgressRate += speed; + process.process(currentProgressRate / (TOTAL_NUM)); + if (state.get() != ImitationState.SECOND_STATE) { + return; + } + } catch (InterruptedException ignore) { + return; + } + } + //90%-95%,三分钟 + speed = TOTAL_NUM * 0.05 / 60; + for (i = 0; i < 60; i++) { + try { + Thread.sleep(3000); + currentProgressRate += speed; + process.process(currentProgressRate / (TOTAL_NUM)); + } catch (InterruptedException ignore) { + return; + } + } + //线程睡眠1h + try { + Thread.sleep(1000 * 3600); + } catch (InterruptedException ignore) { + } + } + + + /** + * 下载完,则跑第三阶段,即1s内跑完剩下所有进度 + */ + private void thirdState() { + int localSpeed = (int) (TOTAL_NUM - currentProgressRate) / 10; + for (int i = 0; i < 10; i++) { + try { + Thread.sleep(100); + currentProgressRate += localSpeed; + process.process((currentProgressRate) / TOTAL_NUM); + } catch (InterruptedException ignore) { + return; + } + } + + } + + public void completed() { + state.set(ImitationState.COMPLETE); + } + + public void stop() { + state.set(ImitationState.STOP); + } + + private enum ImitationState { + NEW, + FIRST_STAGE, + SECOND_STATE, + COMPLETE, + STOP + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/LeftWordsTextArea.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/LeftWordsTextArea.java new file mode 100644 index 000000000..df9dd8aac --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/LeftWordsTextArea.java @@ -0,0 +1,44 @@ +package com.fr.design.mainframe.share.ui.base; + +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.RenderingHints; + +/** + * created by Harrison on 2020/04/21 + **/ +public class LeftWordsTextArea extends PlaceholderTextArea { + + /** + * 默认值 200 + */ + private int limitedLen = 200; + + public LeftWordsTextArea() { + } + + public LeftWordsTextArea(String s, String placeholder) { + super(s, placeholder); + } + + public void setLimitedLen(int len) { + this.limitedLen = len; + } + + @Override + protected void paintComponent(Graphics pG) { + super.paintComponent(pG); + + char[] text = getText().toCharArray(); + int currentLen = text.length; + int leftLen = limitedLen - currentLen; + String leftWordsLen = String.valueOf(leftLen); + + final Graphics2D g = (Graphics2D) pG; + g.setRenderingHint( + RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + g.setColor(getDisabledTextColor()); + g.drawString(leftWordsLen, getWidth() - getInsets().right - leftWordsLen.length() * 8 - 5, getHeight() - getInsets().bottom - 5); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/LoadingPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/LoadingPane.java new file mode 100644 index 000000000..ee0f37774 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/LoadingPane.java @@ -0,0 +1,49 @@ +package com.fr.design.mainframe.share.ui.base; + +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.SwingConstants; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; + +/** + * Created by kerry on 2020-10-23 + */ +public class LoadingPane extends JPanel { + + public LoadingPane() { + this(Toolkit.i18nText("Fine-Design_Share_Online_Loading")); + } + + public LoadingPane(String message) { + JPanel panel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + JPanel borderPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + borderPane.setPreferredSize(new Dimension(120, 120)); + ImagePanel imagePanel = new ImagePanel("/com/fr/base/images/share/loading.gif"); + imagePanel.setPreferredSize(new Dimension(45, 45)); + borderPane.setBorder(BorderFactory.createEmptyBorder(150, 95, 5, 75)); + borderPane.add(imagePanel); + + panel.add(borderPane, BorderLayout.CENTER); + + JPanel labelPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + UILabel topLabel = new UILabel(Toolkit.i18nText(message), SwingConstants.CENTER); + topLabel.setForeground(Color.GRAY); + labelPanel.add(topLabel, BorderLayout.CENTER); + labelPanel.setPreferredSize(new Dimension(240, 20)); + panel.add(labelPanel, BorderLayout.SOUTH); + + panel.setPreferredSize(new Dimension(240, 230)); + + + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + this.setBorder(BorderFactory.createEmptyBorder(100, 0, 0, 0)); + this.add(panel, BorderLayout.NORTH); + } + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/MouseClickListener.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/MouseClickListener.java new file mode 100644 index 000000000..ae5247d21 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/MouseClickListener.java @@ -0,0 +1,34 @@ +package com.fr.design.mainframe.share.ui.base; + +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; + +/** + * Created by kerry on 2020-10-22 + */ +public abstract class MouseClickListener implements MouseListener { + @Override + public void mouseClicked(MouseEvent e) { + + } + + @Override + public void mousePressed(MouseEvent e) { + + } + + @Override + public void mouseReleased(MouseEvent e) { + + } + + @Override + public void mouseEntered(MouseEvent e) { + + } + + @Override + public void mouseExited(MouseEvent e) { + + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/NoMatchPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/NoMatchPane.java new file mode 100644 index 000000000..856bfd299 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/NoMatchPane.java @@ -0,0 +1,41 @@ +package com.fr.design.mainframe.share.ui.base; + +import com.fr.base.BaseUtils; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.layout.FRGUIPaneFactory; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.SwingConstants; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.FlowLayout; + +/** + * @Author: Yuan.Wang + * @Date: 2021/1/14 + */ +public class NoMatchPane extends JPanel { + public NoMatchPane() { + init(); + } + + private void init() { + JPanel panel = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, FlowLayout.LEADING, 0, 5); + UILabel picLabel = new UILabel(); + picLabel.setIcon(BaseUtils.readIcon("com/fr/base/images/share/no_match_icon.png")); + picLabel.setHorizontalAlignment(SwingConstants.CENTER); + picLabel.setPreferredSize(new Dimension(240, 100)); + UILabel label = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Share_No_Match_Result"), SwingConstants.CENTER); + label.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0)); + label.setForeground(Color.gray); + label.setPreferredSize(new Dimension(240, 20)); + label.setHorizontalAlignment(SwingConstants.CENTER); + panel.add(picLabel); + panel.add(label); + panel.setBorder(BorderFactory.createEmptyBorder(250, 0, 0, 0)); + this.setLayout(new BorderLayout()); + this.add(panel, BorderLayout.CENTER); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/PageableButton.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/PageableButton.java new file mode 100644 index 000000000..781797e07 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/PageableButton.java @@ -0,0 +1,128 @@ +package com.fr.design.mainframe.share.ui.base; + +import javax.swing.SwingConstants; +import javax.swing.plaf.ColorUIResource; +import javax.swing.plaf.basic.BasicArrowButton; +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Shape; +import java.awt.geom.Path2D; +import java.awt.geom.RoundRectangle2D; + +public class PageableButton extends BasicArrowButton { + + static final private Color BORDER_COLOR = new ColorUIResource(198, 198, 198); + static final private Color ARROW_DISABLED_COLOR = new ColorUIResource(193, 193, 193); + static final private Color ARROW_COLOR = new ColorUIResource(112, 112, 112); + static final private Color BUTTON_COLOR = new ColorUIResource(255, 255, 255); + static final private Color BUTTON_DISABLED_COLOR = new ColorUIResource(242, 242, 242); + static final private Color BUTTON_PRESS_COLOR = new ColorUIResource(96, 189, 246); + static final private Color BUTTON_ROLLOVER_COLOR = new ColorUIResource(0xd2d2d2); + static final private int CONNER = 2; + + + public PageableButton(int direction) { + super(direction); + } + + public void paint(Graphics g) { + paintButton(g); + paintArrow(g); + paintButtonBorder(g); + } + + private void paintButton(Graphics g) { + + int width = this.getWidth(); + int height = this.getHeight(); + if (!isEnabled()) { + g.setColor(PageableButton.BUTTON_DISABLED_COLOR); + } else if (getModel().isPressed()) { + g.setColor(PageableButton.BUTTON_PRESS_COLOR); + } else if (getModel().isRollover()){ + g.setColor(PageableButton.BUTTON_ROLLOVER_COLOR); + } else { + g.setColor(PageableButton.BUTTON_COLOR); + } + + g.fillRoundRect(1, 1, width -2, height - 2, PageableButton.CONNER, PageableButton.CONNER); + } + + private void paintArrow(Graphics g) { + if (!this.isEnabled()) { + g.setColor(PageableButton.ARROW_DISABLED_COLOR); + } else { + g.setColor(PageableButton.ARROW_COLOR); + } + switch (direction) { + case SwingConstants.NORTH: + g.drawLine(8, 5, 8, 5); + g.drawLine(7, 6, 9, 6); + g.drawLine(6, 7, 10, 7); + g.drawLine(5, 8, 7, 8); + g.drawLine(9, 8, 11, 8); + g.drawLine(4, 9, 6, 9); + g.drawLine(10, 9, 12, 9); + g.drawLine(5, 10, 5, 10); + g.drawLine(11, 10, 11, 10); + break; + case SwingConstants.SOUTH: + g.drawLine(5, 6, 5, 6); + g.drawLine(11, 6, 11, 6); + g.drawLine(4, 7, 6, 7); + g.drawLine(10, 7, 12, 7); + g.drawLine(5, 8, 7, 8); + g.drawLine(9, 8, 11, 8); + g.drawLine(6, 9, 10, 9); + g.drawLine(7, 10, 9, 10); + g.drawLine(8, 11, 8, 11); + break; + case SwingConstants.EAST: + g.drawLine(6, 5, 6, 5); + g.drawLine(6, 11, 6, 11); + g.drawLine(7, 4, 7, 6); + g.drawLine(7, 10, 7, 12); + g.drawLine(8, 5, 8, 7); + g.drawLine(8, 9, 8, 11); + g.drawLine(9, 6, 9, 10); + g.drawLine(10, 7, 10, 9); + g.drawLine(11, 8, 11, 8); + break; + case SwingConstants.WEST: + g.drawLine(4, 8, 4, 8); + g.drawLine(5, 7, 5, 9); + g.drawLine(6, 6, 6, 10); + g.drawLine(7, 5, 7, 7); + g.drawLine(7, 9, 7, 11); + g.drawLine(8, 4, 8, 6); + g.drawLine(8, 10, 8, 12); + g.drawLine(9, 5, 9, 5); + g.drawLine(9, 11, 9, 11); + break; + } + } + + private void paintButtonBorder(Graphics g) { + int offs = 1; + int width = this.getWidth(); + int height = this.getHeight(); + + Graphics2D g2d = (Graphics2D) g; + Color oldColor = g2d.getColor(); + g2d.setColor(PageableButton.BORDER_COLOR); + + Shape outer; + Shape inner; + int size = offs + offs; + + outer = new RoundRectangle2D.Float(0, 0, width, height, offs, offs); + inner = new RoundRectangle2D.Float(offs, offs, width - size, height - size, PageableButton.CONNER, PageableButton.CONNER); + + Path2D path = new Path2D.Float(Path2D.WIND_EVEN_ODD); + path.append(outer, false); + path.append(inner, false); + g2d.fill(path); + g2d.setColor(oldColor); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/PagingFiledPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/PagingFiledPane.java new file mode 100644 index 000000000..b5cfcd53a --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/PagingFiledPane.java @@ -0,0 +1,213 @@ +package com.fr.design.mainframe.share.ui.base; + +import com.fr.base.BaseUtils; +import com.fr.design.event.ChangeEvent; +import com.fr.design.event.ChangeListener; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.gui.itextfield.UINumberField; +import com.fr.stable.ArrayUtils; + +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JSeparator; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Insets; +import java.awt.Toolkit; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; + +/** + * Created by kerry on 2020-10-20 + */ +public class PagingFiledPane extends JPanel { + private static final Dimension PAGING_BTN_SIZE = new Dimension(20, 20); + private int currentPageNum = 1; + private int totalPageNum; + private int numPerPage; + + private ChangeListener changeListener; + + private UIButton lastPageBtn; + private UIButton nextPageBtn; + private UINumberField pagingEditField; + + public PagingFiledPane(int totalItems, int numPerPage) { + this.setOpaque(false); + this.numPerPage = numPerPage; + this.totalPageNum = totalItems / numPerPage + ((totalItems % numPerPage) == 0 ? 0 : 1); + this.totalPageNum = this.totalPageNum > 0 ? this.totalPageNum : 1; + initPane(totalPageNum); + } + + private void initPane(int totalPageNum) { + + this.setLayout(new FlowLayout(FlowLayout.RIGHT, 5, 15)); + initLastPageBtn(); + + JSeparator jSeparator1 = new JSeparator(); + + pagingEditField = new UINumberField(); + registerPagingEditFieldListener(); + pagingEditField.canFillNegativeNumber(false); + pagingEditField.setMinValue(1); + pagingEditField.setMaxValue(totalPageNum); + pagingEditField.setPreferredSize(new Dimension(50, 20)); + + UILabel totalPageLabel = new UILabel("/" + totalPageNum); + + JSeparator jSeparator2 = new JSeparator(); + + initNextPageBtn(); + + checkPageStatus(); + + this.add(lastPageBtn); + this.add(jSeparator1); + this.add(pagingEditField); + this.add(totalPageLabel); + this.add(jSeparator2); + this.add(nextPageBtn); + } + + public void setEnable(boolean enable) { + lastPageBtn.setEnabled(enable); + nextPageBtn.setEnabled(enable); + pagingEditField.setEnabled(enable); + } + + private void initLastPageBtn() { + lastPageBtn = new UIButton(BaseUtils.readIcon("/com/fr/base/images/share/left_page_normal.png")); + lastPageBtn.setRolloverEnabled(true); + lastPageBtn.setFocusPainted(false); + lastPageBtn.setContentAreaFilled(true); + lastPageBtn.setMargin(new Insets(0, 0, 0, 0)); + lastPageBtn.setPressedIcon(BaseUtils.readIcon("/com/fr/base/images/share/left_page_click.png")); + lastPageBtn.setRolloverIcon(BaseUtils.readIcon("/com/fr/base/images/share/left_page_hover.png")); + lastPageBtn.setDisabledIcon(BaseUtils.readIcon("/com/fr/base/images/share/left_page_disable.png")); + lastPageBtn.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + clickLastPage(); + } + }); + lastPageBtn.setPreferredSize(PAGING_BTN_SIZE); + + } + + private void initNextPageBtn() { + nextPageBtn = new UIButton(BaseUtils.readIcon("/com/fr/base/images/share/right_page_normal.png")); + nextPageBtn.setRolloverEnabled(true); + nextPageBtn.setFocusPainted(false); + nextPageBtn.setContentAreaFilled(true); + nextPageBtn.setMargin(new Insets(0, 0, 0, 0)); + nextPageBtn.setPressedIcon(BaseUtils.readIcon("/com/fr/base/images/share/right_page_click.png")); + nextPageBtn.setRolloverIcon(BaseUtils.readIcon("/com/fr/base/images/share/right_page_hover.png")); + nextPageBtn.setDisabledIcon(BaseUtils.readIcon("/com/fr/base/images/share/right_page_disable.png")); + nextPageBtn.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + clickNextPage(); + } + }); + nextPageBtn.setPreferredSize(PAGING_BTN_SIZE); + + } + + private void registerPagingEditFieldListener() { + pagingEditField.addKeyListener(new KeyListener() { + @Override + public void keyTyped(KeyEvent e) { + + } + + @Override + public void keyPressed(KeyEvent e) { + + } + + @Override + public void keyReleased(KeyEvent evt) { + int code = evt.getKeyCode(); + if (code == KeyEvent.VK_ENTER) { + jumpPage((int) pagingEditField.getValue()); + } + } + }); + pagingEditField.addFocusListener(new FocusListener() { + @Override + public void focusGained(FocusEvent e) { + + } + + @Override + public void focusLost(FocusEvent e) { + jumpPage((int) pagingEditField.getValue()); + } + }); + } + + public int getCurrentPageNum() { + return currentPageNum; + } + + public void registerChangeListener(ChangeListener changeListener) { + this.changeListener = changeListener; + } + + private void checkPageStatus() { + lastPageBtn.setEnabled(currentPageNum > 1); + nextPageBtn.setEnabled(currentPageNum < totalPageNum); + pagingEditField.setText(String.valueOf(currentPageNum)); + if (changeListener != null) { + changeListener.fireChanged(new ChangeEvent(currentPageNum)); + } + } + + private void clickNextPage() { + if (currentPageNum < totalPageNum) { + currentPageNum++; + checkPageStatus(); + } + } + + private void clickLastPage() { + if (currentPageNum > 1) { + currentPageNum--; + checkPageStatus(); + } + } + + private void jumpPage(int pageNum) { + if (pageNum > 0 && pageNum <= totalPageNum) { + currentPageNum = pageNum; + checkPageStatus(); + } + } + + public T[] getShowItems(T[] items) { + int startIndex = Math.max(0, currentPageNum - 1); + T[] resultArr = ArrayUtils.subarray(items, startIndex * this.numPerPage, this.currentPageNum * this.numPerPage); + return resultArr; + } + + + /** + * 测试程序 + */ + public static void main(String[] args) { + JFrame frame = new JFrame(""); + frame.setSize(400, 320); + Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); + frame.setLocation((d.width - frame.getSize().width) / 2, (d.height - frame.getSize().height) / 2); + PagingFiledPane tt = new PagingFiledPane(10, 3); + frame.getContentPane().add(tt); + frame.setVisible(true); + } + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/PlaceholderTextArea.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/PlaceholderTextArea.java new file mode 100644 index 000000000..c463a4903 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/PlaceholderTextArea.java @@ -0,0 +1,42 @@ +package com.fr.design.mainframe.share.ui.base; + +import com.fr.design.gui.itextarea.UITextArea; + +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.RenderingHints; + +/** + * created by Harrison on 2020/04/21 + **/ +public class PlaceholderTextArea extends UITextArea { + + private String placeholder; + + public PlaceholderTextArea() { + } + + public PlaceholderTextArea(String s, String placeholder) { + super(s); + this.placeholder = placeholder; + } + + public void setPlaceholder(String placeholder) { + + this.placeholder = placeholder; + } + + @Override + protected void paintComponent(final Graphics pG) { + super.paintComponent(pG); + if (placeholder.length() == 0 || getText().length() > 0) { + return; + } + final Graphics2D g = (Graphics2D) pG; + g.setRenderingHint( + RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + g.setColor(getDisabledTextColor()); + g.drawString(placeholder, getInsets().left, pG.getFontMetrics() + .getMaxAscent() + getInsets().top + 1); + }} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/PopupMenuItem.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/PopupMenuItem.java new file mode 100644 index 000000000..4ef1cffc6 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/PopupMenuItem.java @@ -0,0 +1,31 @@ +package com.fr.design.mainframe.share.ui.base; + +import com.fr.design.constants.UIConstants; +import com.fr.design.mainframe.share.ui.base.ui.SharePopupMenuItemUI; +import com.fr.stable.StringUtils; + +import javax.swing.Action; +import javax.swing.JMenuItem; +import java.awt.Dimension; + +/** + * @Author: Yuan.Wang + * @Date: 2020/10/30 + * 弹窗菜单项 + */ +public class PopupMenuItem extends JMenuItem { + + public PopupMenuItem(Action action) { + super(StringUtils.EMPTY, null); + setBackground(UIConstants.DEFAULT_BG_RULER); + setAction(action); + setUI(new SharePopupMenuItemUI()); + this.setPreferredSize(new Dimension(60, 21)); + } + + @Override + public String getText() { + return StringUtils.EMPTY + super.getText(); + } + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/PopupPreviewPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/PopupPreviewPane.java new file mode 100644 index 000000000..91b1eae89 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/PopupPreviewPane.java @@ -0,0 +1,83 @@ +package com.fr.design.mainframe.share.ui.base; + +import com.fr.design.constants.UIConstants; +import com.fr.general.IOUtils; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.JPopupMenu; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.Toolkit; + +/** + * Created by kerry on 2020-06-23 + */ +public class PopupPreviewPane extends JPopupMenu { + private Container contentPane; + private Image compImage; + private static final int WIDTH = 400; + private static final int STANDARD_DPI = 128; + private static final int MAX_HEIGHT = 400; + private static final int HEIGHT = 210; + + public PopupPreviewPane() { + setFocusable(false); + contentPane = new JPanel(); + contentPane.setBackground(Color.white); + this.setLayout(new BorderLayout()); + this.add(contentPane, BorderLayout.CENTER); + this.setOpaque(false); + setPreferredSize(new Dimension(WIDTH, MAX_HEIGHT)); + setBorder(BorderFactory.createLineBorder(UIConstants.LINE_COLOR)); + } + + public void setComp(Image compImage) { + try { + this.compImage = compImage; + this.updateSize(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Override + public void paint(Graphics g) { + super.paint(g); + if (compImage != null) { + g.drawImage(compImage, 0, 0, getWidth(), getHeight(), null); + } + } + + @Override + public void setVisible(boolean visible) { + super.setVisible(visible); + } + + public void menuSelectionChanged(boolean isIncluded) { + } + + + // 根据控件内容,更新弹出框大小 + private void updateSize() { + int dpi = Toolkit.getDefaultToolkit().getScreenResolution(); + int width; + int height; + if (compImage == null) { + compImage = IOUtils.readImage("com/fr/base/images/share/component_error.png"); + width = WIDTH; + height = HEIGHT; + } else { + width = compImage.getWidth(null); + height = compImage.getHeight(null); + } + double aspectRatio = (double) width / height; + width = (WIDTH * dpi) / STANDARD_DPI; + height = (int) (width / aspectRatio); + this.setPreferredSize(new Dimension(width, height)); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/ShareProgressBar.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/ShareProgressBar.java new file mode 100644 index 000000000..49fd3173b --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/ShareProgressBar.java @@ -0,0 +1,231 @@ +package com.fr.design.mainframe.share.ui.base; + +import com.fr.concurrent.NamedThreadFactory; +import com.fr.design.gui.iprogressbar.ProgressDialog; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.ui.util.UIUtil; +import com.fr.stable.StringUtils; + +import java.util.concurrent.Callable; +import java.util.concurrent.Executors; +import java.util.concurrent.FutureTask; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +public class ShareProgressBar { + + private static final int STEP = 20; + + private ProgressDialog progressBar = null; + + private LimitProgress loadingProgress = new LimitProgress(); + + /** + * 默认 40 ms更新进度 + */ + private int stepHeartbeat = 40; + + private volatile int progress = 0; + + private final AtomicBoolean TERMINATE = new AtomicBoolean(false); + + private final AtomicBoolean RUNNING = new AtomicBoolean(false); + + private ShareProgressBar() { + } + + private static class InstanceHolder { + + private static final ShareProgressBar INSTANCE = new ShareProgressBar(); + } + + public static ShareProgressBar getInstance() { + + return InstanceHolder.INSTANCE; + } + + public void prepare(int stepHeartbeat) { + + this.progressBar = createNewBar(); + this.stepHeartbeat = stepHeartbeat; + } + + public void updateProgress(double rate, String loadingText) throws Exception { + int maximum = progressBar.getProgressMaximum(); + double progress = maximum * rate; + int maxProgress = (int) Math.floor(progress); + loadingProgress.lock(maxProgress, loadingText); + + RUNNING.compareAndSet(false, true); + //终止条件 + TERMINATE.compareAndSet(true, false); + + loadingProgress.get(); + + } + + public void monitor() { + + final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1, + new NamedThreadFactory("ShareProgressMonitor", true)); + scheduler.scheduleAtFixedRate(new Runnable() { + @Override + public void run() { + if (!isRunning()) { + return; + } + if (isComplete()) { + shutdown(scheduler); + return; + } + updateUI(); + } + }, 0, stepHeartbeat, TimeUnit.MILLISECONDS); + } + + + /** + * 延迟关闭 + */ + public void complete(String loadingText) throws Exception { + + updateProgress(1.0, loadingText); + } + + /** + * 立刻关闭 + */ + public void completeNow() { + + if (RUNNING.get()) { + this.progress = progressBar.getProgressMaximum(); + this.TERMINATE.compareAndSet(false, true); + } + } + + /** + * 完成条件。不只是达到目标值,还要确保当前已经可以终止了。 + * + * @return 是否终止了。 + */ + public boolean isComplete() { + + return this.progress >= progressBar.getProgressMaximum() && this.TERMINATE.get(); + } + + private ProgressDialog createNewBar() { + return new ProgressDialog(DesignerContext.getDesignerFrame()); + } + + /** + * 小于当前最大时, 每次递增 1 + * 大于等于时, 停止 + * + * @return 当前最大值 + */ + private int incrementProgress() { + if (progress >= loadingProgress.getLimitKey()) { + progress = loadingProgress.getLimitKey(); + loadingProgress.release(); + return progress; + } else { + progress += STEP; + return progress; + } + } + + private String getLoadingText() { + + return loadingProgress.getLimitText(); + } + + + private boolean isRunning() { + + return RUNNING.get(); + } + + + private void shutdown(ScheduledExecutorService scheduler) { + + //停止运行 + RUNNING.compareAndSet(true, false); + reset(); + scheduler.shutdown(); + } + + private void reset() { + + this.progress = 0; + this.loadingProgress.reset(); + this.progressBar.setVisible(false); + this.progressBar.dispose(); + this.progressBar = null; + } + + private void updateUI() { + String text = getLoadingText(); + int value = incrementProgress(); + UIUtil.invokeLaterIfNeeded(new Runnable() { + @Override + public void run() { + if (!progressBar.isVisible()) { + progressBar.setVisible(true); + } + progressBar.updateLoadingText(text); + progressBar.setProgressValue(value); + } + }); + } + + private static class LimitProgress { + + private int limitKey = 0; + + private String limitText = StringUtils.EMPTY; + + private FutureTask lock; + + public void lock(int key, String loadingText) { + + this.limitKey = key; + this.limitText = loadingText; + this.lock = new FutureTask<>(new Callable() { + @Override + public Void call() throws Exception { + return null; + } + }); + } + + public void release() { + + this.lock.run(); + } + + public void get() throws Exception { + + this.lock.get(); + } + + public void reset() { + + this.limitKey = 0; + this.limitText = StringUtils.EMPTY; + //防止卡住。 + this.lock.run(); + } + + public int getLimitKey() { + return limitKey; + } + + public String getLimitText() { + return limitText; + } + + + } + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/SortPopupMenuItem.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/SortPopupMenuItem.java new file mode 100644 index 000000000..2b3c5703c --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/SortPopupMenuItem.java @@ -0,0 +1,104 @@ +package com.fr.design.mainframe.share.ui.base; + +import com.fr.design.constants.UIConstants; +import com.fr.design.utils.gui.GUIPaintUtils; +import com.fr.stable.Constants; +import com.fr.stable.StringUtils; +import sun.swing.SwingUtilities2; + +import javax.swing.Action; +import javax.swing.ButtonModel; +import javax.swing.JMenu; +import javax.swing.JMenuItem; +import javax.swing.UIManager; +import javax.swing.plaf.basic.BasicMenuItemUI; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Rectangle; + +/** + * Created by kerry on 2020-06-30 + */ +public class SortPopupMenuItem extends JMenuItem { + + + public SortPopupMenuItem(Action action) { + super(StringUtils.EMPTY, null); + setBackground(UIConstants.DEFAULT_BG_RULER); + setAction(action); + setUI(new SortPopupMenuItemUI()); + this.setPreferredSize(new Dimension(60, 21)); + } + + @Override + public String getText() { + return StringUtils.EMPTY + super.getText(); + } + + + private class SortPopupMenuItemUI extends BasicMenuItemUI { + + @Override + protected void paintBackground(Graphics g, JMenuItem menuItem, Color bgColor) { + if (menuItem.getIcon() == null) { + super.paintBackground(g, menuItem, bgColor); + return; + } + ButtonModel model = menuItem.getModel(); + Color oldColor = g.getColor(); + int menuWidth = menuItem.getWidth(); + int menuHeight = menuItem.getHeight(); + + g.setColor(UIConstants.DEFAULT_BG_RULER); + g.fillRect(0, 0, menuWidth, menuHeight); + if (menuItem.isOpaque()) { + if (model.isArmed() || (menuItem instanceof JMenu && model.isSelected())) { + GUIPaintUtils.fillPaint((Graphics2D) g, 0, 0, menuWidth, menuHeight, true, Constants.NULL, UIConstants.FLESH_BLUE, 7); + } else { + GUIPaintUtils.fillPaint((Graphics2D) g, 0, 0, menuWidth, menuHeight, true, Constants.NULL, menuItem.getBackground(), 7); + } + g.setColor(oldColor); + } else if (model.isArmed() || (menuItem instanceof JMenu && + model.isSelected())) { + GUIPaintUtils.fillPaint((Graphics2D) g, 0, 0, menuWidth, menuHeight, true, Constants.NULL, UIConstants.FLESH_BLUE, 7); + g.setColor(oldColor); + } + } + + protected void paintText(Graphics g, JMenuItem menuItem, Rectangle textRect, String text) { + ButtonModel model = menuItem.getModel(); + FontMetrics fm = SwingUtilities2.getFontMetrics(menuItem, g); + int mnemIndex = menuItem.getDisplayedMnemonicIndex(); + + if (!model.isEnabled()) { + // *** paint the text disabled + if (UIManager.get("MenuItem.disabledForeground") instanceof Color) { + g.setColor(UIManager.getColor("MenuItem.disabledForeground")); + SwingUtilities2.drawStringUnderlineCharAt(menuItem, g, text, + -1, textRect.x, textRect.y + fm.getAscent()); + } else { + g.setColor(menuItem.getBackground().brighter()); + SwingUtilities2.drawStringUnderlineCharAt(menuItem, g, text, + -1, textRect.x, textRect.y + fm.getAscent()); + g.setColor(menuItem.getBackground().darker()); + SwingUtilities2.drawStringUnderlineCharAt(menuItem, g, text, + -1, textRect.x - 1, textRect.y + + fm.getAscent() - 1); + } + } else { + // *** paint the text normally + if (model.isArmed() || (menuItem instanceof JMenu && model.isSelected())) { + g.setColor(Color.WHITE); // Uses protected field. + } + SwingUtilities2.drawStringUnderlineCharAt(menuItem, g, text, + -1, textRect.x, textRect.y + fm.getAscent()); + } + } + + } + + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/ui/PlaceHolderUI.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/ui/PlaceHolderUI.java new file mode 100644 index 000000000..5c4c39eae --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/ui/PlaceHolderUI.java @@ -0,0 +1,48 @@ +package com.fr.design.mainframe.share.ui.base.ui; + +import javax.swing.JComponent; +import javax.swing.plaf.ComponentUI; +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.RenderingHints; + +/** + * created by Harrison on 2020/04/22 + **/ +public abstract class PlaceHolderUI extends ComponentUI { + + private static final Color DEFAULT_COLOR = new Color(143, 142, 139); + + private String placeholder; + + + public PlaceHolderUI(String placeholder) { + this.placeholder = placeholder; + } + + @Override + public void paint(Graphics pG, JComponent c) { + @SuppressWarnings("unchecked") T realType = (T) c; + if (placeholder.length() == 0 || validate(realType)) { + return; + } + final Graphics2D g = (Graphics2D) pG; + g.setRenderingHint( + RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + g.setColor(getDisabledTextColor()); + g.drawString(placeholder, c.getInsets().left + 10, pG.getFontMetrics() + .getMaxAscent() + c.getInsets().top + 3); + + } + + + protected abstract boolean validate(T t); + + protected Color getDisabledTextColor() { + + return DEFAULT_COLOR; + }; + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/ui/SharePopupMenuItemUI.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/ui/SharePopupMenuItemUI.java new file mode 100644 index 000000000..16a5a58bd --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/ui/SharePopupMenuItemUI.java @@ -0,0 +1,82 @@ +package com.fr.design.mainframe.share.ui.base.ui; + +import com.fr.design.constants.UIConstants; +import com.fr.design.utils.gui.GUIPaintUtils; +import com.fr.stable.Constants; +import sun.swing.SwingUtilities2; + +import javax.swing.ButtonModel; +import javax.swing.JMenu; +import javax.swing.JMenuItem; +import javax.swing.UIManager; +import javax.swing.plaf.basic.BasicMenuItemUI; +import java.awt.Color; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Rectangle; + +/** + * @Author: Yuan.Wang + * @Date: 2020/10/30 + */ +public class SharePopupMenuItemUI extends BasicMenuItemUI { + + @Override + protected void paintBackground(Graphics g, JMenuItem menuItem, Color bgColor) { + if (menuItem.getIcon() == null) { + super.paintBackground(g, menuItem, bgColor); + return; + } + ButtonModel model = menuItem.getModel(); + Color oldColor = g.getColor(); + int menuWidth = menuItem.getWidth(); + int menuHeight = menuItem.getHeight(); + + g.setColor(UIConstants.DEFAULT_BG_RULER); + g.fillRect(0, 0, menuWidth, menuHeight); + if (menuItem.isOpaque()) { + if (model.isArmed() || (menuItem instanceof JMenu && model.isSelected())) { + GUIPaintUtils.fillPaint((Graphics2D) g, 0, 0, menuWidth, menuHeight, true, Constants.NULL, UIConstants.FLESH_BLUE, 7); + } else { + GUIPaintUtils.fillPaint((Graphics2D) g, 0, 0, menuWidth, menuHeight, true, Constants.NULL, menuItem.getBackground(), 7); + } + g.setColor(oldColor); + } else if (model.isArmed() || (menuItem instanceof JMenu && + model.isSelected())) { + GUIPaintUtils.fillPaint((Graphics2D) g, 0, 0, menuWidth, menuHeight, true, Constants.NULL, UIConstants.FLESH_BLUE, 7); + g.setColor(oldColor); + } + } + + protected void paintText(Graphics g, JMenuItem menuItem, Rectangle textRect, String text) { + ButtonModel model = menuItem.getModel(); + FontMetrics fm = SwingUtilities2.getFontMetrics(menuItem, g); + + if (!model.isEnabled()) { + // *** paint the text disabled + if (UIManager.get("MenuItem.disabledForeground") instanceof Color) { + g.setColor(UIManager.getColor("MenuItem.disabledForeground")); + SwingUtilities2.drawStringUnderlineCharAt(menuItem, g, text, + -1, textRect.x, textRect.y + fm.getAscent()); + } else { + g.setColor(menuItem.getBackground().brighter()); + SwingUtilities2.drawStringUnderlineCharAt(menuItem, g, text, + -1, textRect.x, textRect.y + fm.getAscent()); + g.setColor(menuItem.getBackground().darker()); + SwingUtilities2.drawStringUnderlineCharAt(menuItem, g, text, + -1, textRect.x - 1, textRect.y + + fm.getAscent() - 1); + } + } else { + g.setColor(Color.BLACK); + // *** paint the text normally + if (model.isArmed() || (menuItem instanceof JMenu && model.isSelected())) { + g.setColor(Color.WHITE); // Uses protected field. + } + + SwingUtilities2.drawStringUnderlineCharAt(menuItem, g, text, + -1, textRect.x, textRect.y + fm.getAscent()); + } + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/AbstractOnlineWidgetBlock.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/AbstractOnlineWidgetBlock.java new file mode 100644 index 000000000..06e513b80 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/AbstractOnlineWidgetBlock.java @@ -0,0 +1,94 @@ +package com.fr.design.mainframe.share.ui.block; + +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.mainframe.share.ui.online.OnlineResourceManager; +import com.fr.design.mainframe.share.ui.online.OnlineWidgetSelectPane; +import com.fr.design.mainframe.share.ui.online.ResourceLoader; +import com.fr.form.share.bean.OnlineShareWidget; +import com.fr.form.share.constants.ShareComponentConstants; +import com.fr.log.FineLoggerFactory; +import com.fr.stable.EncodeConstants; +import com.fr.third.springframework.web.util.UriUtils; +import org.jetbrains.annotations.NotNull; + +import javax.imageio.ImageIO; +import javax.swing.ImageIcon; +import java.awt.Dimension; +import java.awt.Image; +import java.io.IOException; +import java.net.URL; + +/** + * Created by kerry on 2020-11-22 + */ +public abstract class AbstractOnlineWidgetBlock extends PreviewWidgetBlock implements ResourceLoader { + + private final OnlineWidgetSelectPane parentPane; + private UILabel coverLabel; + + public AbstractOnlineWidgetBlock(OnlineShareWidget widget, OnlineWidgetSelectPane parentPane) { + super(widget); + this.parentPane = parentPane; + } + + protected UILabel initCoverLabel(Image image) { + coverLabel = new UILabel(new ImageIcon(image)); + return coverLabel; + } + + @Override + protected String getWidgetUuid() { + return widget.getUuid(); + } + + protected void showPreview(OnlineShareWidget widget) { + parentPane.showPreviewPane(this, widget.getId()); + } + + protected void hidePreview() { + parentPane.hidePreviewPane(); + } + + @Override + @NotNull + protected Image getCoverImage() { + OnlineResourceManager.getInstance().addLoader(this); + return getDefaultDisplayImage(); + } + + public Image getPreviewImage() { + try { + return ImageIO.read(new URL(UriUtils.encodePath(widget.getPicPath(), EncodeConstants.ENCODING_UTF_8))); + } catch (IOException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + return getDefaultDisplayImage(); + } + } + + public void load() { + Image image; + try { + + Dimension coverDimension = getCoverDimension(); + String previewURI = UriUtils.encodePath(widget.getPicPath(), EncodeConstants.ENCODING_UTF_8) + "?x-oss-process=image/resize,m_fixed," + "w_" + coverDimension.width + + ",h_" + coverDimension.height; + image = ImageIO.read(new URL(previewURI)); + } catch (IOException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + image = getDefaultDisplayImage(); + } + resetCover(image); + } + + private Image getDefaultDisplayImage(){ + return ShareComponentConstants.DEFAULT_COVER; + } + + + public void resetCover(Image image) { + coverLabel.setIcon(new ImageIcon(image)); + this.parentPane.validate(); + this.parentPane.repaint(); + } + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/DragAndDropDragGestureListener.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/DragAndDropDragGestureListener.java new file mode 100644 index 000000000..3fe0fc388 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/DragAndDropDragGestureListener.java @@ -0,0 +1,72 @@ +package com.fr.design.mainframe.share.ui.block; + +import com.fr.form.share.utils.ShareUtils; +import com.fr.form.ui.Widget; +import com.fr.general.ComparatorUtils; +import org.jetbrains.annotations.NotNull; + +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.dnd.DragGestureEvent; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragSource; +import java.awt.dnd.DragSourceAdapter; +import java.awt.dnd.DragSourceDragEvent; + +/** + * @Author: Yuan.Wang + * @Date: 2021/1/15 + */ +public class DragAndDropDragGestureListener extends DragSourceAdapter implements DragGestureListener { + private final PreviewWidgetBlock block; + + public DragAndDropDragGestureListener(PreviewWidgetBlock tt, int actions) { + block = tt; + DragSource source = new DragSource(); + source.createDefaultDragGestureRecognizer(tt, actions, this); + } + + public void dragGestureRecognized(DragGestureEvent dge) { + PreviewWidgetBlock onlineWidgetBlock = (PreviewWidgetBlock) dge.getComponent(); + if (onlineWidgetBlock != null) { + String uuid = block.getWidgetUuid(); + Widget widget = ShareUtils.getElCaseEditorById(uuid); + if (widget != null) { + DragAndDropTransferable dragAndDropTransferable = new DragAndDropTransferable(widget); + dge.startDrag(DragSource.DefaultCopyDrop, dragAndDropTransferable, this); + } + } + } + + @Override + public void dragEnter(DragSourceDragEvent dragSourceDragEvent) { + + } + + private static class DragAndDropTransferable implements Transferable { + private final Widget widget; + + public DragAndDropTransferable(Widget widget) { + this.widget = widget; + } + + DataFlavor[] flavors = {new DataFlavor(Widget.class, "Widget")}; + + public DataFlavor[] getTransferDataFlavors() { + return flavors; + } + + public boolean isDataFlavorSupported(DataFlavor flavor) { + for (DataFlavor df : flavors) { + if (ComparatorUtils.equals(df, flavor)) { + return true; + } + } + return false; + } + @NotNull + public Object getTransferData(DataFlavor df) { + return widget; + } + } +} \ No newline at end of file diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/LocalWidgetBlock.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/LocalWidgetBlock.java new file mode 100644 index 000000000..911ff7b77 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/LocalWidgetBlock.java @@ -0,0 +1,315 @@ +package com.fr.design.mainframe.share.ui.block; + +import com.fr.base.GraphHelper; +import com.fr.base.iofile.attr.SharableAttrMark; +import com.fr.design.actions.UpdateAction; +import com.fr.design.base.mode.DesignModeContext; +import com.fr.design.constants.UIConstants; +import com.fr.design.designer.creator.XCreator; +import com.fr.design.dialog.FineJOptionPane; +import com.fr.design.form.util.XCreatorConstants; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.gui.imenu.UIPopupMenu; +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.WidgetToolBarPane; +import com.fr.design.mainframe.share.collect.ComponentCollector; +import com.fr.design.mainframe.share.group.ui.GroupMoveDialog; +import com.fr.design.mainframe.share.ui.base.PopupMenuItem; +import com.fr.design.mainframe.share.ui.local.LocalWidgetRepoPane; +import com.fr.design.mainframe.share.ui.local.LocalWidgetSelectPane; +import com.fr.design.mainframe.share.ui.local.WidgetSelectedManager; +import com.fr.design.mainframe.share.util.ShareComponentUtils; +import com.fr.design.mainframe.share.util.ShareUIUtils; +import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.form.share.DefaultSharableWidget; +import com.fr.form.share.SharableWidgetProvider; +import com.fr.form.share.constants.ShareComponentConstants; +import com.fr.form.share.Group; +import com.fr.form.share.record.ShareWidgetInfoManager; +import com.fr.form.ui.AbstractBorderStyleWidget; +import com.fr.form.ui.Widget; +import com.fr.general.ComparatorUtils; +import com.fr.general.IOUtils; +import com.fr.stable.Constants; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.Action; +import javax.swing.Icon; +import javax.swing.JPanel; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Cursor; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.Rectangle; +import java.awt.dnd.DnDConstants; +import java.awt.event.ActionEvent; +import java.awt.event.MouseEvent; +import java.util.UUID; + +/** + * created by Harrison on 2020/06/12 + * 本地组件块 + **/ +public class LocalWidgetBlock extends PreviewWidgetBlock { + private static final int MARK_START_X = 83; + + private boolean mouseHover = false; + private final LocalWidgetSelectPane parentPane; + + private MouseEvent lastPressEvent; + private boolean isEdit; + private boolean isMarked; + private boolean pressed; + private boolean hover; + private final Icon markedMode = IOUtils.readIcon("/com/fr/base/images/share/marked.png"); + private final Icon unMarkedMode = IOUtils.readIcon("/com/fr/base/images/share/unmarked.png"); + + public LocalWidgetBlock(DefaultSharableWidget provider, LocalWidgetSelectPane parentPane) { + super(provider); + this.parentPane = parentPane; + new DragAndDropDragGestureListener(this, DnDConstants.ACTION_COPY_OR_MOVE); + initUI(); + } + + + private void initUI() { + JPanel labelPane = new JPanel(new BorderLayout()); + UILabel label = new UILabel(this.getBindInfo().getName(), UILabel.CENTER); + label.setPreferredSize(new Dimension(ShareComponentConstants.SHARE_THUMB_WIDTH, ShareComponentConstants.SHARE_BLOCK_LABEL_HEIGHT)); + labelPane.setBackground(Color.WHITE); + labelPane.add(label, BorderLayout.CENTER); + this.add(labelPane, BorderLayout.SOUTH); + } + + public void setElementCaseEdit(boolean isEdit) { + this.isEdit = isEdit; + if (isEdit) { + isMarked = WidgetSelectedManager.getInstance().isSelected(getGroup().getGroupName(), this.getWidget().getId()); + } + repaint(); + } + + public String getFileName() { + //插件里面, 所有的值都是插件值。可以强转的。 + DefaultSharableWidget provider = (DefaultSharableWidget) getBindInfo(); + return provider.getFileName(); + } + + public SharableWidgetProvider getBindInfo() { + return this.getWidget(); + } + + @Override + protected void showPreview(DefaultSharableWidget widget) { + this.parentPane.showPreviewPane(this, widget.getId()); + } + + @Override + protected void hidePreview() { + this.parentPane.hidePreviewPane(); + } + + @Override + @NotNull + public Image getCoverImage() { + return this.getWidget().getCover(); + } + + @Override + protected String getWidgetUuid() { + return widget.getId(); + } + + @Nullable + public Image getPreviewImage() { + String id = this.getWidget().getId(); + return getGroup().getPreviewImage(id); + } + + @Override + public void mouseClicked(MouseEvent e) { + super.mouseClicked(e); + if (e.getButton() == MouseEvent.BUTTON3 && !isEdit) { + this.parentPane.hidePreviewPane(); + UIPopupMenu popupMenu = new UIPopupMenu(); + popupMenu.setOnlyText(true); + popupMenu.setBackground(UIConstants.DEFAULT_BG_RULER); + popupMenu.add(new PopupMenuItem(new MoveGroupAction())); + popupMenu.add(new PopupMenuItem(new RemoveAction())); + GUICoreUtils.showPopupMenu(popupMenu, this, e.getX(), e.getY()); + } + + } + + @Override + public void mousePressed(MouseEvent e) { + super.mousePressed(e); + lastPressEvent = e; + pressed = true; + } + + @Override + public void mouseReleased(MouseEvent e) { + super.mouseReleased(e); + if (pressed && hover) { + dealClickAction(e); + } + pressed = false; + } + + @Override + public void mouseMoved(MouseEvent e) { + super.mouseMoved(e); + this.mouseHover = true; + if (!isEdit) { + setCursor(new Cursor(Cursor.MOVE_CURSOR)); + } + this.repaint(); + } + + @Override + public void mouseEntered(MouseEvent e) { + super.mouseEntered(e); + hover = true; + } + + @Override + public void mouseExited(MouseEvent e) { + super.mouseExited(e); + this.mouseHover = false; + setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); + hover = false; + this.repaint(); + } + + + @Override + public void mouseDragged(MouseEvent e) { + if (DesignModeContext.isAuthorityEditing() || lastPressEvent == null || isEdit) { + return; + } + hidePreview(); + ComponentCollector.getInstance().collectPopupJump(); + Object source = e.getSource(); + Widget creatorSource; + String shareId; + if (source instanceof LocalWidgetBlock) { + LocalWidgetBlock no = (LocalWidgetBlock) e.getSource(); + if (no == null) { + return; + } + shareId = no.getBindInfo().getId(); + creatorSource = getGroup().getElCaseEditorById(shareId); + if (creatorSource == null) { + ShareUIUtils.showErrorMessageDialog(Toolkit.i18nText("Fine-Design_Share_Drag_Error_Info")); + return; + } + creatorSource.setWidgetID(UUID.randomUUID().toString()); + ((AbstractBorderStyleWidget) creatorSource).addWidgetAttrMark(new SharableAttrMark(true)); + //tab布局WCardMainBorderLayout通过反射出来的大小是960*480 + XCreator xCreator = ShareComponentUtils.createXCreator(creatorSource, shareId, no.getBindInfo()); + WidgetToolBarPane.getTarget().startDraggingBean(xCreator); + lastPressEvent = null; + this.setBorder(null); + } + } + + @Override + public void paint(Graphics g) { + super.paint(g); + //绘制删除标志 + if (isEdit) { + Icon icon = isMarked ? markedMode : unMarkedMode; + icon.paintIcon(this, g, MARK_START_X, 0); + } + if (ComparatorUtils.equals(this, this.parentPane.getSelectedBlock()) || this.mouseHover) { + g.setColor(XCreatorConstants.FORM_BORDER_COLOR); + Rectangle rectangle = new Rectangle(); + rectangle.width = this.getWidth(); + rectangle.height = this.getHeight(); + GraphHelper.draw(g, rectangle, Constants.LINE_LARGE); + } + } + + /** + * 由鼠标释放时调用该方法来触发左键点击事件 + */ + private void dealClickAction(MouseEvent e) { + this.parentPane.setSelectBlock(this); + if (e.getButton() == MouseEvent.BUTTON1) { + if (isEdit) { + if (isMarked) { + WidgetSelectedManager.getInstance().removeSelect(getGroup().getGroupName(), this.getWidget().getId()); + isMarked = false; + } else { + WidgetSelectedManager.getInstance().addSelect(getGroup().getGroupName(), this.getWidget().getId()); + isMarked = true; + } + } + //没有组件被选择则禁用按钮 + LocalWidgetRepoPane.getInstance().setManageButtonEnable(hasComponentSelected()); + repaint(); + } + } + + private Group getGroup() { + return parentPane.getGroup(); + } + + private boolean hasComponentSelected() { + return !WidgetSelectedManager.getInstance().isSelectEmpty(); + } + + private class MoveGroupAction extends UpdateAction { + public MoveGroupAction() { + this.putValue(Action.SMALL_ICON, null); + this.setName(Toolkit.i18nText("Fine-Design_Share_Group_Move")); + } + + @Override + public void actionPerformed(ActionEvent e) { + new GroupMoveDialog(DesignerContext.getDesignerFrame()) { + @Override + protected void confirmClose() { + this.dispose(); + Group group = (Group) getSelectGroupBox().getSelectedItem(); + assert group != null; + if (WidgetSelectedManager.getInstance().moveSelect(getGroup().getGroupName(), group.getGroupName(), getWidget().getId())) { + ShareWidgetInfoManager.getInstance().saveXmlInfo(); + LocalWidgetRepoPane.getInstance().refreshShowPanel(false); + } else { + ShareUIUtils.showErrorMessageDialog(Toolkit.i18nText("Fine-Design_Share_Group_Move_Fail_Message")); + } + } + + }; + } + } + + private class RemoveAction extends UpdateAction { + public RemoveAction() { + this.putValue(Action.SMALL_ICON, null); + this.setName(Toolkit.i18nText("Fine-Design_Share_Remove")); + } + + @Override + public void actionPerformed(ActionEvent e) { + int rv = FineJOptionPane.showConfirmDialog(DesignerContext.getDesignerFrame(), + Toolkit.i18nText("Fine-Design_Share_Remove_Info"), + Toolkit.i18nText("Fine-Design_Share_Group_Confirm"), + FineJOptionPane.YES_NO_OPTION + ); + if (rv == FineJOptionPane.YES_OPTION) { + if (!WidgetSelectedManager.getInstance().unInstallSelect(getGroup().getGroupName(), getWidget().getId())) { + FineJOptionPane.showMessageDialog(null, Toolkit.i18nText("Fine-Design_Share_Remove_Failure")); + } + LocalWidgetRepoPane.getInstance().refreshShowPanel(getGroup()); + } + } + } + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/OnlineWidgetBlock.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/OnlineWidgetBlock.java new file mode 100644 index 000000000..4b5c9c0cb --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/OnlineWidgetBlock.java @@ -0,0 +1,304 @@ +package com.fr.design.mainframe.share.ui.block; + +import com.fr.base.iofile.attr.SharableAttrMark; +import com.fr.config.MarketConfig; +import com.fr.design.base.mode.DesignModeContext; +import com.fr.design.designer.creator.XCreator; +import com.fr.design.extra.WebViewDlgHelper; +import com.fr.design.form.util.XCreatorConstants; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.WidgetToolBarPane; +import com.fr.design.mainframe.share.collect.ComponentCollector; +import com.fr.form.share.group.DefaultShareGroup; +import com.fr.design.mainframe.share.ui.local.LocalWidgetRepoPane; +import com.fr.design.mainframe.share.ui.online.OnlineWidgetRepoPane; +import com.fr.design.mainframe.share.ui.online.OnlineWidgetSelectPane; +import com.fr.design.mainframe.share.util.DownloadUtils; +import com.fr.design.mainframe.share.util.ShareComponentUtils; +import com.fr.design.mainframe.share.util.ShareUIUtils; +import com.fr.design.ui.util.UIUtil; +import com.fr.form.share.SharableWidgetProvider; +import com.fr.form.share.bean.OnlineShareWidget; +import com.fr.form.share.constants.ShareComponentConstants; +import com.fr.form.share.group.DefaultShareGroupManager; +import com.fr.form.share.Group; +import com.fr.form.share.utils.ShareUtils; +import com.fr.form.ui.AbstractBorderStyleWidget; +import com.fr.form.ui.Widget; +import com.fr.general.IOUtils; +import com.fr.log.FineLoggerFactory; +import com.fr.stable.StableUtils; +import com.fr.stable.StringUtils; + +import javax.swing.JPanel; +import javax.swing.SwingConstants; +import javax.swing.SwingWorker; +import java.awt.AlphaComposite; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Composite; +import java.awt.Cursor; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.RenderingHints; +import java.awt.Stroke; +import java.awt.dnd.DnDConstants; +import java.awt.event.MouseEvent; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.util.UUID; +import java.util.concurrent.ExecutionException; + +/** + * Created by kerry on 2020-10-19 + * 商城组件块 + */ +public class OnlineWidgetBlock extends AbstractOnlineWidgetBlock { + private boolean isMouseEnter = false; + private boolean downloading = false; + private static final Color COVER_COLOR = Color.decode("#333334"); + protected MouseEvent lastPressEvent; + private double process = 0D; + private static final BufferedImage WIDGET_INSTALLED_ICON = IOUtils.readImage("/com/fr/base/images/share/widget_installed.png"); + private static final BufferedImage WIDGET_DOWNLOAD_ICON = IOUtils.readImage("/com/fr/base/images/share/download.png"); + private static final BufferedImage WIDGET_DOWNLOADING_ICON = IOUtils.readImage("/com/fr/base/images/share/downloading.png"); + + public OnlineWidgetBlock(OnlineShareWidget widget, OnlineWidgetSelectPane parentPane) { + super(widget, parentPane); + this.add(createSouthPane(widget), BorderLayout.SOUTH); + new DragAndDropDragGestureListener(this, DnDConstants.ACTION_COPY_OR_MOVE); + } + + protected JPanel createSouthPane(OnlineShareWidget widget) { + JPanel southPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + UILabel label = new UILabel(widget.getName(), UILabel.CENTER); + label.setToolTipText(widget.getName()); + label.setHorizontalTextPosition(SwingConstants.LEFT); + southPane.add(label, BorderLayout.CENTER); + UILabel emptyLabel = new UILabel(); + emptyLabel.setPreferredSize(new Dimension(25, 20)); + southPane.add(emptyLabel, BorderLayout.EAST); + southPane.setBackground(Color.WHITE); + return southPane; + } + + @Override + public void mouseEntered(MouseEvent e) { + super.mouseEntered(e); + this.isMouseEnter = true; + this.repaint(); + } + + @Override + public void mouseExited(MouseEvent e) { + super.mouseExited(e); + this.isMouseEnter = false; + this.repaint(); + } + + @Override + public void mousePressed(MouseEvent e) { + super.mousePressed(e); + this.lastPressEvent = e; + } + + @Override + public void mouseClicked(MouseEvent e) { + super.mouseClicked(e); + if (!checkWidgetInstalled() && getDownloadIconRec().contains(e.getX(), e.getY())) { + downLoadWidget(); + } + } + + @Override + public void mouseDragged(MouseEvent e) { + if (DesignModeContext.isAuthorityEditing() || !checkWidgetInstalled()) { + return; + } + if (lastPressEvent == null) { + return; + } + ComponentCollector.getInstance().collectPopupJump(); + Object source = e.getSource(); + Widget creatorSource; + String shareId; + if (source instanceof OnlineWidgetBlock) { + OnlineWidgetBlock no = (OnlineWidgetBlock) e.getSource(); + if (no == null) { + return; + } + shareId = widget.getUuid(); + creatorSource = ShareUtils.getElCaseEditorById(shareId); + if (creatorSource == null) { + ShareUIUtils.showErrorMessageDialog(Toolkit.i18nText("Fine-Design_Share_Drag_Error_Info")); + return; + } + creatorSource.setWidgetID(UUID.randomUUID().toString()); + ((AbstractBorderStyleWidget) creatorSource).addWidgetAttrMark(new SharableAttrMark(true)); + SharableWidgetProvider bindInfo = ShareUtils.getElCaseBindInfoById(shareId); + //tab布局WCardMainBorderLayout通过反射出来的大小是960*480 + XCreator xCreator = ShareComponentUtils.createXCreator(creatorSource, shareId, bindInfo); + WidgetToolBarPane.getTarget().startDraggingBean(xCreator); + lastPressEvent = null; + this.setBorder(null); + } + } + + private void downLoadWidget() { + if (OnlineWidgetRepoPane.getInstance().isShowPackagePanel()) { + ComponentCollector.getInstance().collectDownloadPktNum(); + } + final WidgetDownloadProcess process = new WidgetDownloadProcess(); + downloading = true; + process.process(0.0D); + String userName = MarketConfig.getInstance().getBbsUsername(); + if (StringUtils.isEmpty(userName)) { + WebViewDlgHelper.createLoginDialog(); + downloading = false; + return; + } + + new SwingWorker() { + + @Override + protected Boolean doInBackground() { + String filePath; + try { + filePath = DownloadUtils.download(widget.getId(), widget.getName() + "." + widget.getUuid(), process); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + return false; + } + ShareComponentUtils.checkReadMe(); + //安装 + File file = new File(filePath); + try { + if (file.exists() && getDefaultGroup().installModule(file)) { + ShareUtils.recordInstallTime(file.getName(), System.currentTimeMillis()); + ComponentCollector.getInstance().collectCmpDownLoad(widget.getUuid()); + } + } catch (IOException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } finally { + //删掉下载组件的目录 + StableUtils.deleteFile(file); + } + return true; + + } + + @Override + protected void done() { + downloading = false; + OnlineWidgetBlock.this.process = 0.0D; + try { + if (get()) { + LocalWidgetRepoPane.getInstance().refreshShowPanel(); + } else { + ShareUIUtils.showErrorMessageDialog(Toolkit.i18nText("Fine-Design_Share_Download_Failed")); + } + } catch (InterruptedException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + Thread.currentThread().interrupt(); + } catch (ExecutionException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + } + }.execute(); + + + } + + + @Override + public void mouseMoved(MouseEvent e) { + super.mouseMoved(e); + if (checkWidgetInstalled()) { + this.setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR)); + } else if (getDownloadIconRec().contains(e.getX(), e.getY())) { + this.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + } else { + this.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + } + } + + private Rectangle getDownloadIconRec() { + return new Rectangle(ShareComponentConstants.SHARE_THUMB_WIDTH / 2 - 12, ShareComponentConstants.SHARE_BLOCK_HEIGHT / 2 - 16, 24, 24); + } + + private boolean checkWidgetInstalled() { + return ShareUtils.getElCaseBindInfoById(widget.getUuid()) != null; + } + + private Group getDefaultGroup() { + return DefaultShareGroupManager.getInstance().getGroup(DefaultShareGroup.GROUP_NAME); + } + + public void paint(Graphics g) { + super.paint(g); + ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB); + int x = 0; + int y = 0; + int w = getWidth(); + int h = getHeight(); + if (process == 1 || checkWidgetInstalled()) { + Graphics2D g2d = (Graphics2D) g; + g2d.drawImage( + WIDGET_INSTALLED_ICON, + w - 20, + h - 20, + WIDGET_INSTALLED_ICON.getWidth(), + WIDGET_INSTALLED_ICON.getHeight(), + null, + this + ); + return; + } + //如果鼠标移动到布局内且布局不可编辑,画出编辑蒙层 + if (isMouseEnter || downloading) { + Graphics2D g2d = (Graphics2D) g; + Composite oldComposite = g2d.getComposite(); + //画白色的编辑层 + g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 20 / 100.0F)); + g2d.setColor(COVER_COLOR); + g2d.fillRect(x, y, w, h); + g2d.setComposite(oldComposite); + //画编辑按钮图标 + BufferedImage image = (process > 0 || downloading) ? WIDGET_DOWNLOADING_ICON : WIDGET_DOWNLOAD_ICON; + g2d.drawImage( + image, + (x + w / 2 - 12), + (y + h / 2 - 16), + image.getWidth(), + image.getHeight(), + null, + this + ); + Stroke oldStroke = g2d.getStroke(); + g2d.setStroke(XCreatorConstants.STROKE); + g2d.setColor(Color.decode("#419BF9")); + double arcAngle = downloading ? (36 + 360 * 0.9 * process) : 0.0; + g2d.drawArc(x + w / 2 - 12, y + h / 2 - 16, 24, 24, 90, -(int) arcAngle); + g2d.setColor(Color.WHITE); + g2d.setStroke(oldStroke); + } + } + + + class WidgetDownloadProcess implements com.fr.design.extra.Process { + + @Override + public void process(Double aDouble) { + OnlineWidgetBlock.this.process = aDouble; + final Dimension dimension = OnlineWidgetBlock.this.getSize(); + UIUtil.invokeAndWaitIfNeeded(() -> OnlineWidgetBlock.this.paintImmediately(0, 0, dimension.width, dimension.height)); + } + } + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/OnlineWidgetPackageBlock.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/OnlineWidgetPackageBlock.java new file mode 100644 index 000000000..4b8458594 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/OnlineWidgetPackageBlock.java @@ -0,0 +1,57 @@ +package com.fr.design.mainframe.share.ui.block; + +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.share.ui.base.MouseClickListener; +import com.fr.design.mainframe.share.ui.online.widgetpackage.OnlineWidgetPackageSelectPane; +import com.fr.form.share.bean.OnlineShareWidget; +import com.fr.form.share.constants.ShareComponentConstants; + +import javax.swing.JPanel; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Cursor; +import java.awt.Dimension; +import java.awt.event.MouseEvent; + +/** + * Created by kerry on 2020-10-21 + * 商城组件包块 + */ +public class OnlineWidgetPackageBlock extends AbstractOnlineWidgetBlock { + private static final int IMAGE_HEIGHT = 167; + private static final Color TEXT_COLOR = Color.decode("#419BF9"); + + protected JPanel createSouthPane(final OnlineShareWidget widget, final OnlineWidgetPackageSelectPane parentPane) { + JPanel southPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + southPane.setBackground(Color.WHITE); + UILabel label = new UILabel(widget.getName(), UILabel.CENTER); + label.setToolTipText(widget.getName()); + southPane.add(label, BorderLayout.CENTER); + UILabel detailLabel = new UILabel(Toolkit.i18nText("Fine-Design_Share_Online_Package_Detail")); + detailLabel.setForeground(TEXT_COLOR); + detailLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + detailLabel.addMouseListener(new MouseClickListener() { + @Override + public void mouseClicked(MouseEvent e) { + parentPane.showWidgetDetailPane(widget.getId()); + } + }); + southPane.add(detailLabel, BorderLayout.EAST); + return southPane; + } + + protected Dimension getCoverDimension() { + return new Dimension(ShareComponentConstants.SHARE_PACKAGE_BLOCK_WIDTH, IMAGE_HEIGHT); + } + + public OnlineWidgetPackageBlock(OnlineShareWidget widget, OnlineWidgetPackageSelectPane parentPane) { + super(widget, parentPane); + this.setPreferredSize(new Dimension(ShareComponentConstants.SHARE_PACKAGE_BLOCK_WIDTH, ShareComponentConstants.SHARE_PACKAGE_BLOCK_HEIGHT)); + this.add(createSouthPane(widget, parentPane), BorderLayout.SOUTH); + } + +} + + diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/PreviewWidgetBlock.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/PreviewWidgetBlock.java new file mode 100644 index 000000000..8ad9e2b11 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/PreviewWidgetBlock.java @@ -0,0 +1,138 @@ +package com.fr.design.mainframe.share.ui.block; + +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.form.share.constants.ShareComponentConstants; +import org.jetbrains.annotations.NotNull; + +import javax.swing.ImageIcon; +import javax.swing.JPanel; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.Rectangle; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; +import java.io.Serializable; + +/** + * Created by kerry on 2020-10-21 + */ +public abstract class PreviewWidgetBlock extends JPanel implements MouseListener, MouseMotionListener, Serializable { + protected T widget; + private boolean showing = false; + + public PreviewWidgetBlock(T widget) { + this.widget = widget; + initPane(); + this.addMouseListener(this); + this.addMouseMotionListener(this); + } + + protected void initPane() { + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + this.setPreferredSize(new Dimension(ShareComponentConstants.SHARE_THUMB_WIDTH, ShareComponentConstants.SHARE_BLOCK_HEIGHT)); + JPanel labelPane = new JPanel(new BorderLayout()); + Image image = getCoverImage(); + labelPane.add(initCoverLabel(image)); + labelPane.setBackground(Color.WHITE); + this.add(labelPane, BorderLayout.CENTER); + } + + protected UILabel initCoverLabel(Image image) { + return new UILabel(new ImageIcon(image)); + } + + public T getWidget() { + return widget; + } + + + @NotNull + protected abstract Image getCoverImage(); + + protected Dimension getCoverDimension() { + return new Dimension(ShareComponentConstants.SHARE_THUMB_WIDTH, ShareComponentConstants.SHARE_THUMB_HEIGHT); + } + + private void showPreviewPane() { + synchronized (this) { + if (!showing) { + showPreview(widget); + showing = true; + } + } + } + protected abstract String getWidgetUuid(); + + protected abstract void showPreview(T widget); + + protected abstract void hidePreview(); + + private void hidePreviewPane() { + if (showing) { + hidePreview(); + showing = false; + } + } + + public abstract Image getPreviewImage(); + + @Override + public void mouseClicked(MouseEvent e) { + this.hidePreviewPane(); + } + + @Override + public void mousePressed(MouseEvent e) { + + } + + @Override + public void mouseReleased(MouseEvent e) { + + } + + @Override + public void mouseEntered(MouseEvent e) { + + } + + @Override + public void mouseExited(MouseEvent e) { + this.hidePreviewPane(); + } + + @Override + public void mouseDragged(MouseEvent e) { + + } + + @Override + public void mouseMoved(MouseEvent e) { + Dimension dimension = getCoverDimension(); + Rectangle containerRec = new Rectangle(0, 0, dimension.width, dimension.height); + if (containerRec.contains(e.getX(), e.getY())) { + this.showPreviewPane(); + } else { + this.hidePreviewPane(); + } + } + + @Override + public void paint(Graphics g) { + Graphics2D g2d = (Graphics2D) g; + g2d.setColor(Color.WHITE); + g2d.fillRect(0, 0, getWidth(), getHeight()); + super.paint(g); + } + + protected void removeListener() { + this.removeMouseListener(this); + this.removeMouseMotionListener(this); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/SimpleWidgetBlock.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/SimpleWidgetBlock.java new file mode 100644 index 000000000..cf5e948de --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/SimpleWidgetBlock.java @@ -0,0 +1,17 @@ +package com.fr.design.mainframe.share.ui.block; + +import com.fr.design.mainframe.share.ui.online.OnlineWidgetSelectPane; +import com.fr.form.share.bean.OnlineShareWidget; + +/** + * @Author: Yuan.Wang + * @Date: 2020/12/22 + * 只能显示,无其他功能的组件块 + */ +public class SimpleWidgetBlock extends OnlineWidgetBlock { + public SimpleWidgetBlock(OnlineShareWidget widget, OnlineWidgetSelectPane parentPane) { + super(widget, parentPane); + this.removeListener(); + this.setFocusable(false); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/GroupPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/GroupPane.java new file mode 100644 index 000000000..bfa6343e0 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/GroupPane.java @@ -0,0 +1,383 @@ +package com.fr.design.mainframe.share.ui.local; + +import com.fr.design.actions.UpdateAction; +import com.fr.design.constants.UIConstants; +import com.fr.design.dialog.FineJOptionPane; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.gui.imenu.UIPopupMenu; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.share.group.ui.GroupFileDialog; +import com.fr.design.mainframe.share.sort.SortType; +import com.fr.design.mainframe.share.sort.WidgetSortType; +import com.fr.design.mainframe.share.ui.base.PopupMenuItem; +import com.fr.design.mainframe.share.ui.widgetfilter.LocalWidgetFilter; +import com.fr.design.mainframe.share.util.ShareUIUtils; +import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.form.share.SharableWidgetProvider; +import com.fr.form.share.group.DefaultShareGroupManager; +import com.fr.form.share.Group; +import com.fr.general.IOUtils; +import com.fr.stable.StringUtils; + +import javax.swing.Action; +import javax.swing.BorderFactory; +import javax.swing.Icon; +import javax.swing.JPanel; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.event.ActionEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.ArrayList; +import java.util.List; + +/** + * @Author: Yuan.Wang + * @Date: 2020/11/5 + */ +class GroupPane extends JPanel { + private static final Icon downIcon = IOUtils.readIcon("/com/fr/base/images/share/arrow_down.png"); + private static final Icon rightIcon = IOUtils.readIcon("/com/fr/base/images/share/arrow_right.png"); + private static final int DEFAULT_HEIGHT = 24; + private final Group group; + private LocalWidgetSelectPane contentPanel; + private UIHeaderPane headerPanel; + private final int headHeight; + //是否展开 + private boolean expendStatus; + private SharableWidgetProvider[] elCaseBindInfoList; + private SortType sortType = WidgetSortType.INSTALL_TIME; + + private GroupPane(Group group) { + this(group, DEFAULT_HEIGHT, group.isDefaultExpend()); + } + + private GroupPane(Group group, boolean expendStatus) { + this(group, DEFAULT_HEIGHT, expendStatus); + } + + private GroupPane(Group group, int headHeight, boolean expendStatus) { + this.group = group; + this.headHeight = headHeight; + this.expendStatus = expendStatus; + initComponents(); + } + + public boolean isComponentEditable() { + return LocalWidgetRepoPane.getInstance().isEditable(); + } + + private void initComponents() { + this.setLayout(new BorderLayout()); + this.setOpaque(false); + + headerPanel = new UIHeaderPane(group.getGroupName(), headHeight); + JPanel head = new JPanel(new BorderLayout()); + head.add(headerPanel, BorderLayout.NORTH); + head.setPreferredSize(new Dimension(240, 24)); + this.add(head, BorderLayout.NORTH); + refreshShowPanel(); + } + + public void refreshShowPanel() { + this.setVisible(true); + refreshBindInfoList(); + + //按照筛选条件进行过滤 + elCaseBindInfoList = LocalWidgetFilter.getInstance().filter(elCaseBindInfoList); + boolean needExpendGroup = expendStatus || (isFiltering() && elCaseBindInfoList.length > 0); + if (elCaseBindInfoList.length == 0 && isFiltering()) { + this.setVisible(false); + } + + //刷新面板的时候可能还有查询条件,如果有的话走一遍查询的逻辑 + String keyWord = LocalWidgetRepoPane.getInstance().getKeyWord4Searching(); + if (StringUtils.isNotEmpty(keyWord)) { + searchByKeyword(keyWord); + return; + } + reCreateShowPane(elCaseBindInfoList); + expendGroup(needExpendGroup); + } + + public void reCreateShowPane(SharableWidgetProvider[] widgets) { + if (contentPanel != null) { + contentPanel.hidePreviewPane(); + GroupPane.this.remove(contentPanel); + } + contentPanel = new LocalWidgetSelectPane(group, widgets, isComponentEditable()); + GroupPane.this.add(contentPanel, BorderLayout.CENTER); + headerPanel.setMenuItemVisible(!isComponentEditable()); + validate(); + repaint(); + revalidate(); + } + + private void expendGroup(boolean expendStatus) { + headerPanel.showExpand(expendStatus); + contentPanel.setVisible(expendStatus); + } + + protected void setExpendStatus(boolean expendStatus) { + //在筛选或者搜索状态,调用这个方法直接返回 + if (isFiltering() || isSearching()) { + return; + } + this.expendStatus = expendStatus; + } + + public SharableWidgetProvider[] getAllBindInfoList() { + SharableWidgetProvider[] widgetProviders = group.getAllBindInfoList(); + if (widgetProviders == null) { + widgetProviders = new SharableWidgetProvider[0]; + } + sortType.sort(widgetProviders); + return widgetProviders; + } + + public void sortWidget(WidgetSortType sortType) { + this.sortType = sortType; + sortType.sort(elCaseBindInfoList); + reCreateShowPane(elCaseBindInfoList); + } + + public void searchByKeyword(String text) { + this.setVisible(true); + SharableWidgetProvider[] sharableWidgetArr = elCaseBindInfoList; + List widgets = new ArrayList<>(); + if (StringUtils.isNotEmpty(text)) { + for (SharableWidgetProvider provider : elCaseBindInfoList) { + if (provider.getName().toLowerCase().contains(text)) { + widgets.add(provider); + } + } + sharableWidgetArr = widgets.toArray(new SharableWidgetProvider[widgets.size()]); + } + + boolean needExpendGroup = expendStatus || (isSearching() && sharableWidgetArr.length > 0); + if (isSearching() && sharableWidgetArr.length == 0) { + setVisible(false); + } + reCreateShowPane(sharableWidgetArr); + expendGroup(needExpendGroup); + } + + public void refreshBindInfoList() { + elCaseBindInfoList = getAllBindInfoList(); + } + + private boolean isFiltering() { + return LocalWidgetRepoPane.getInstance().isFiltering(); + } + + private boolean isSearching() { + return LocalWidgetRepoPane.getInstance().isSearching(); + } + + private class UIHeaderPane extends JPanel { + private static final long serialVersionUID = 1L; + + private final UILabel arrow; + private final UILabel menuItem; + private final UILabel titleLabel; + private final int headHeight; + private boolean pressed; + private boolean hover; + + private final MouseAdapter mouseAdapter = new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + if (e.getButton() == MouseEvent.BUTTON3 && group.isEditable() && !GroupPane.this.isComponentEditable()) { + UIPopupMenu popupMenu = new UIPopupMenu(); + popupMenu.setOnlyText(true); + popupMenu.setBackground(UIConstants.DEFAULT_BG_RULER); + popupMenu.add(new PopupMenuItem(new RenameAction())); + popupMenu.add(new PopupMenuItem(new RemoveAction())); + + GUICoreUtils.showPopupMenu(popupMenu, UIHeaderPane.this, e.getX(), e.getY()); + } + } + + @Override + public void mousePressed(MouseEvent e) { + pressed = true; + } + + @Override + public void mouseReleased(MouseEvent e) { + if (pressed && hover) { + dealClickAction(e); + } + pressed = false; + } + + @Override + public void mouseEntered(MouseEvent e) { + hover = true; + } + + @Override + public void mouseExited(MouseEvent e) { + hover = false; + } + }; + + public UIHeaderPane(String title, int headHeight) { + this.setLayout(new BorderLayout()); + this.setBorder(BorderFactory.createEmptyBorder(0, 10, 1, 2)); + JPanel panel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + panel.setBackground(Color.decode("#EDEDEE")); + this.headHeight = headHeight; + arrow = new UILabel(downIcon); + arrow.setOpaque(false); + menuItem = createMenuItem(); + titleLabel = new UILabel(title); + titleLabel.setOpaque(false); + + JPanel leftPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); + leftPanel.add(arrow); + leftPanel.add(titleLabel); + leftPanel.setOpaque(false); + + panel.add(leftPanel, BorderLayout.CENTER); + + if (group.isEditable()) { + panel.add(menuItem, BorderLayout.EAST); + } + add(panel, BorderLayout.CENTER); + addListener(); + } + + public void showExpand(boolean expend) { + Icon showIcon = expend ? downIcon : rightIcon; + arrow.setIcon(showIcon); + } + + @Override + public Dimension getPreferredSize() { + return new Dimension(this.getWidth(), headHeight); + } + + @Override + public Dimension getSize() { + return new Dimension(this.getWidth(), headHeight); + } + + public UILabel createMenuItem() { + UILabel label = new UILabel(IOUtils.readIcon("/com/fr/base/images/share/menu_item.png")); + label.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + UIPopupMenu popupMenu = new UIPopupMenu(); + popupMenu.setOnlyText(true); + popupMenu.setBackground(UIConstants.DEFAULT_BG_RULER); + popupMenu.add(new PopupMenuItem(new RenameAction())); + popupMenu.add(new PopupMenuItem(new RemoveAction())); + + GUICoreUtils.showPopupMenu(popupMenu, menuItem, 0, menuItem.getSize().height); + } + }); + label.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5)); + label.setOpaque(false); + return label; + } + + protected void setMenuItemVisible(boolean visible) { + menuItem.setVisible(visible); + } + + private void addListener() { + this.addMouseListener(mouseAdapter); + } + + /** + * 由鼠标释放时调用该方法来触发左键点击事件 + */ + private void dealClickAction(MouseEvent e) { + if (e.getButton() == MouseEvent.BUTTON1) { + boolean isShow = contentPanel.isShowing(); + contentPanel.setVisible(!isShow); + GroupPane.this.setExpendStatus(!isShow); + showExpand(!isShow); + + getParent().validate(); + getParent().repaint(); + } + } + + private class RenameAction extends UpdateAction { + public RenameAction() { + this.putValue(Action.SMALL_ICON, null); + this.setName(Toolkit.i18nText("Fine-Design_Share_Group_Rename")); + } + + @Override + public void actionPerformed(ActionEvent e) { + new GroupFileDialog(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Design_Share_Group_Rename", group.getGroupName())) { + @Override + protected void confirmClose() { + this.dispose(); + String groupName = getFileName().replaceAll("[\\\\/:*?\"<>|]", StringUtils.EMPTY); + if (DefaultShareGroupManager.getInstance().renameGroup(group, groupName)) { + titleLabel.setText(groupName); + repaint(); + } else { + ShareUIUtils.showErrorMessageDialog(Toolkit.i18nText("Fine-Design_Share_Group_Rename_Failure")); + } + } + + @Override + protected boolean isDuplicate(String fileName) { + return DefaultShareGroupManager.getInstance().exist(fileName); + } + }; + + } + } + + private class RemoveAction extends UpdateAction { + public RemoveAction() { + this.putValue(Action.SMALL_ICON, null); + this.setName(Toolkit.i18nText("Fine-Design_Share_Group_Remove")); + } + + @Override + public void actionPerformed(ActionEvent e) { + int rv = FineJOptionPane.showConfirmDialog( + DesignerContext.getDesignerFrame(), + Toolkit.i18nText("Fine-Design_Share_Group_Remove_Info"), + Toolkit.i18nText("Fine-Design_Share_Group_Confirm"), + FineJOptionPane.YES_NO_OPTION + ); + if (rv == FineJOptionPane.YES_OPTION) { + if (DefaultShareGroupManager.getInstance().removeGroup(group)) { + LocalWidgetRepoPane.getInstance().removeGroup(group.getGroupName()); + } else { + ShareUIUtils.showErrorMessageDialog(Toolkit.i18nText("Fine-Design_Share_Group_Remove_Failure")); + } + } + } + } + } + + public enum GroupCreateStrategy { + DEFAULT { + @Override + public GroupPane creteGroupPane(Group group) { + return new GroupPane(group); + } + }, + CLOSURE { + @Override + public GroupPane creteGroupPane(Group group) { + return new GroupPane(group, false); + } + }; + + abstract public GroupPane creteGroupPane(Group group); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/LocalPaneStatus.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/LocalPaneStatus.java new file mode 100644 index 000000000..d56807245 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/LocalPaneStatus.java @@ -0,0 +1,87 @@ +package com.fr.design.mainframe.share.ui.local; + +import com.fr.base.BaseUtils; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.share.ui.base.LoadingPane; +import com.fr.design.mainframe.share.ui.base.NoMatchPane; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.SwingConstants; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; + +/** + * @Author: Yuan.Wang + * @Date: 2020/12/1 + */ +enum LocalPaneStatus { + + //无匹配 + NO_MATCH { + @Override + public JPanel getPanel() { + return new NoMatchPane(); + } + }, + + //正常 + NORMAL { + @Override + public JPanel getPanel() { + return new JPanel(); + } + }, + + //空 + EMPTY { + @Override + public JPanel getPanel() { + JPanel panel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + UILabel picLabel = new UILabel(); + picLabel.setIcon(BaseUtils.readIcon("com/fr/base/images/share/empty.png")); + picLabel.setHorizontalAlignment(SwingConstants.CENTER); + + panel.add(picLabel, BorderLayout.CENTER); + + JPanel labelPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + UILabel topLabel = new UILabel(Toolkit.i18nText("Fine-Design_Share_Empty_First"), SwingConstants.CENTER); + topLabel.setForeground(Color.GRAY); + UILabel bottomLabel = new UILabel(Toolkit.i18nText("Fine-Design_Share_Empty_Second"), SwingConstants.CENTER); + bottomLabel.setForeground(Color.GRAY); + labelPanel.add(topLabel, BorderLayout.CENTER); + labelPanel.add(bottomLabel, BorderLayout.SOUTH); + labelPanel.setPreferredSize(new Dimension(240, 40)); + panel.add(labelPanel, BorderLayout.SOUTH); + + panel.setPreferredSize(new Dimension(240, 180)); + + + JPanel emptyPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + emptyPanel.setBorder(BorderFactory.createEmptyBorder(100, 0, 0, 0)); + emptyPanel.add(panel, BorderLayout.NORTH); + return emptyPanel; + } + }, + + //加载 + LOADING { + @Override + public JPanel getPanel() { + return new LoadingPane(); + } + }, + + //安装 + INSTALLING { + @Override + public JPanel getPanel() { + return new LoadingPane(Toolkit.i18nText("Fine-Design_Share_installing")); + } + }; + + public abstract JPanel getPanel(); +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/LocalWidgetRepoPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/LocalWidgetRepoPane.java new file mode 100644 index 000000000..487a414e5 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/LocalWidgetRepoPane.java @@ -0,0 +1,266 @@ +package com.fr.design.mainframe.share.ui.local; + +import com.fr.design.dialog.BasicPane; +import com.fr.design.gui.icontainer.UIScrollPane; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.layout.VerticalFlowLayout; +import com.fr.design.mainframe.share.sort.WidgetSortType; +import com.fr.design.mainframe.share.ui.widgetfilter.LocalWidgetFilter; +import com.fr.design.mainframe.share.util.InstallComponentHelper; +import com.fr.design.mainframe.share.util.ShareComponentUtils; +import com.fr.form.share.group.DefaultShareGroupManager; +import com.fr.form.share.Group; +import com.fr.log.FineLoggerFactory; +import com.fr.stable.StringUtils; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.SwingWorker; +import java.awt.BorderLayout; +import java.awt.CardLayout; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * Created by kerry on 2020-10-16 + */ +public class LocalWidgetRepoPane extends BasicPane { + + private JPanel centerPane; + private UIScrollPane groupsScrollPane; + private JPanel groupsPane; + private ManagePane managePane; + + private final Map groupPaneMap = new HashMap<>(); + private final AtomicBoolean isRefreshing = new AtomicBoolean(false); + private boolean editable; + private CardLayout cardLayout; + private String keyWord4Searching = StringUtils.EMPTY; + + private LocalWidgetRepoPane() { + setLayout(FRGUIPaneFactory.createBorderLayout()); + initPane(); + } + + public static LocalWidgetRepoPane getInstance() { + return HOLDER.singleton; + } + + private static class HOLDER { + private static final LocalWidgetRepoPane singleton = new LocalWidgetRepoPane(); + } + + public boolean isEditable() { + return editable; + } + + public String getKeyWord4Searching() { + return keyWord4Searching; + } + + /** + * 初始化 + */ + public void initPane() { + //新用户预装组件 + InstallComponentHelper.installPreComponent(); + JPanel componentLibPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + componentLibPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 15, 0)); + + ToolbarPane toolbarPane = new ToolbarPane(); + managePane = new ManagePane(); + + JPanel northPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + northPane.add(toolbarPane, BorderLayout.NORTH); + northPane.add(managePane, BorderLayout.CENTER); + + cardLayout = new CardLayout(); + centerPane = new JPanel(cardLayout); + centerPane.add(LocalPaneStatus.NO_MATCH.getPanel(), LocalPaneStatus.NO_MATCH.name()); + centerPane.add(LocalPaneStatus.EMPTY.getPanel(), LocalPaneStatus.EMPTY.name()); + centerPane.add(LocalPaneStatus.LOADING.getPanel(), LocalPaneStatus.LOADING.name()); + centerPane.add(LocalPaneStatus.INSTALLING.getPanel(), LocalPaneStatus.INSTALLING.name()); + + componentLibPanel.add(northPane, BorderLayout.NORTH); + componentLibPanel.add(centerPane, BorderLayout.CENTER); + add(componentLibPanel, BorderLayout.CENTER); + cardLayout.show(centerPane, LocalPaneStatus.LOADING.name()); + toolbarPane.addFilterPopupStateChangeListener(state -> setWidgetPaneScrollEnable(!state)); + + doRefresh(); + } + + public void refreshAllGroupPane() { + refreshAllGroupPane(GroupPane.GroupCreateStrategy.DEFAULT); + } + + public void refreshAllGroupPane(GroupPane.GroupCreateStrategy createStrategy) { + editable = false; + groupPaneMap.clear(); + if (groupsScrollPane != null) { + centerPane.remove(groupsScrollPane); + } + groupsPane = FRGUIPaneFactory.createVerticalFlowLayout_Pane(false, VerticalFlowLayout.TOP, 0, 5); + + Group[] groups = DefaultShareGroupManager.getInstance().getAllGroup(); + for (Group group : groups) { + GroupPane groupPane = createStrategy.creteGroupPane(group); + groupPaneMap.put(group.getGroupName(), groupPane); + groupsPane.add(groupPane, BorderLayout.NORTH); + } + groupsScrollPane = new UIScrollPane(groupsPane); + groupsScrollPane.setBorder(null); + groupsScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); + + centerPane.add(groupsScrollPane, LocalPaneStatus.NORMAL.name()); + switchPane(); + } + + public void refreshPane() { + managePane.switchPanel(false); + switchPane(LocalPaneStatus.LOADING); + doRefresh(); + } + + public void switch2InstallingPane() { + switchPane(LocalPaneStatus.INSTALLING); + } + + public void refreshShowPanel(boolean isEdit) { + this.editable = isEdit; + refreshShowPanel(); + } + + public void refreshShowPanel() { + for (GroupPane groupPane : groupPaneMap.values()) { + groupPane.refreshShowPanel(); + } + switchPane(); + } + + public void refreshShowPanel(Group group) { + if (groupPaneMap.containsKey(group.getGroupName())) { + groupPaneMap.get(group.getGroupName()).refreshShowPanel(); + } + switchPane(); + } + + public void setWidgetPaneScrollEnable(boolean enable) { + groupsScrollPane.setWheelScrollingEnabled(enable); + } + + public void setManageButtonEnable(boolean enable) { + managePane.setButtonEnable(enable); + } + + public void removeGroup(String groupName) { + JPanel jPanel = groupPaneMap.remove(groupName); + groupsPane.remove(jPanel); + switchPane(); + } + + public void addGroup(Group group) { + GroupPane groupPane = GroupPane.GroupCreateStrategy.DEFAULT.creteGroupPane(group); + groupPaneMap.put(group.getGroupName(), groupPane); + groupsPane.add(groupPane); + switchPane(); + } + + public void searchByKeyword(String text) { + keyWord4Searching = text; + for (GroupPane groupPane : groupPaneMap.values()) { + groupPane.searchByKeyword(text); + } + switchPane(); + } + + public void sortWidget(WidgetSortType sortType) { + for (GroupPane groupPane : groupPaneMap.values()) { + groupPane.sortWidget(sortType); + } + } + + + private void doRefresh() { + if (isRefreshing.get()) { + return; + } + new SwingWorker() { + @Override + protected Boolean doInBackground() throws Exception { + if (isRefreshing.compareAndSet(false, true)) { + boolean isRefresh = DefaultShareGroupManager.getInstance().refresh(); + if (isRefresh) { + ShareComponentUtils.checkReadMe(); + } + return isRefresh; + } + return false; + } + + @Override + public void done() { + try { + if (get()) { + refreshAllGroupPane(); + } + } catch (InterruptedException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + Thread.currentThread().interrupt(); + } catch (ExecutionException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } finally { + isRefreshing.set(false); + } + } + }.execute(); + } + + /** + * 切换为要显示的面板 + */ + private void switchPane() { + switchPane(getStatus()); + } + + private void switchPane(LocalPaneStatus status) { + cardLayout.show(centerPane, status.name()); + centerPane.validate(); + centerPane.repaint(); + } + + private LocalPaneStatus getStatus() { + return isEmpty() ? LocalPaneStatus.EMPTY : isNoMatch() ? LocalPaneStatus.NO_MATCH : LocalPaneStatus.NORMAL; + } + + public boolean isFiltering() { + return LocalWidgetFilter.getInstance().hasFilter(); + } + + public boolean isSearching() { + return StringUtils.isNotEmpty(keyWord4Searching); + } + + private boolean isNoMatch() { + for (GroupPane groupPane : groupPaneMap.values()) { + if (groupPane.isVisible()) { + return false; + } + } + return true; + } + + private boolean isEmpty() { + Group[] groups = DefaultShareGroupManager.getInstance().getAllGroup(); + return groups.length == 1 && groups[0].getAllBindInfoList().length == 0; + } + + @Override + protected String title4PopupWindow() { + return Toolkit.i18nText("Fine-Design_Share_Local_Widget"); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/LocalWidgetSelectPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/LocalWidgetSelectPane.java new file mode 100644 index 000000000..8c6a9a6c3 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/LocalWidgetSelectPane.java @@ -0,0 +1,113 @@ +package com.fr.design.mainframe.share.ui.local; + +import com.fr.design.mainframe.share.AbstractWidgetSelectPane; +import com.fr.design.mainframe.share.ui.block.LocalWidgetBlock; +import com.fr.form.share.DefaultSharableWidget; +import com.fr.form.share.SharableWidgetProvider; +import com.fr.form.share.constants.ShareComponentConstants; +import com.fr.form.share.Group; +import com.fr.form.share.record.ShareWidgetInfoManager; +import com.fr.general.ComparatorUtils; +import com.fr.stable.ArrayUtils; + +import javax.swing.BorderFactory; +import java.awt.AWTEvent; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Point; +import java.awt.event.AWTEventListener; +import java.awt.event.MouseEvent; + +/** + * created by Harrison on 2020/03/23 + **/ +public class LocalWidgetSelectPane extends AbstractWidgetSelectPane { + private LocalWidgetBlock selectedBlock; + private final Group group; + + public LocalWidgetSelectPane(Group group, SharableWidgetProvider[] providers, boolean isEdit) { + this.group = group; + // 表示Popup弹窗是否能被点击到 + AWTEventListener awtEventListener = new AWTEventListener() { + @Override + public void eventDispatched(AWTEvent event) { + if (event instanceof MouseEvent) { + MouseEvent mv = (MouseEvent) event; + if (isCanCancelSelect(mv, selectedBlock)) { + LocalWidgetSelectPane.this.selectedBlock = null; + LocalWidgetSelectPane.this.repaint(); + } + } + + } + + private boolean isCanCancelSelect(MouseEvent mv, LocalWidgetBlock selectedBlock) { + if (mv.getClickCount() < 1) { + return false; + } + // 表示Popup弹窗是否能被点击到 + boolean clickFlag = false; + if (selectedBlock != null) { + if (!selectedBlock.isShowing()) { + return false; + } + Point p = selectedBlock.getLocationOnScreen(); + Point clickPoint = mv.getLocationOnScreen(); + clickFlag = clickPoint.getX() >= p.getX() + && clickPoint.getY() >= p.getY() + && clickPoint.getX() <= selectedBlock.getWidth() + p.getX() + && clickPoint.getY() <= p.getY() + selectedBlock.getHeight(); + + } + return selectedBlock != null && !clickFlag && !ComparatorUtils.equals(mv.getSource(), selectedBlock); + } + }; + + java.awt.Toolkit.getDefaultToolkit().addAWTEventListener(awtEventListener, AWTEvent.MOUSE_EVENT_MASK); + + // 设置面板的边框 ,距离上、左、下、右 的距离 + this.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0)); + if (ArrayUtils.isNotEmpty(providers)) { + showComponent(providers, isEdit); + } else { + showEmpty(); + } + ShareWidgetInfoManager.getInstance().checkInstallCompInfo(providers); + } + + public Group getGroup() { + return group; + } + + private void showComponent(SharableWidgetProvider[] providers, boolean isEdit) { + + int rowCount = (providers.length + 1) / 2; + int vgap = 10; + this.setLayout(new FlowLayout(FlowLayout.LEFT, 5, vgap)); + for (SharableWidgetProvider provider : providers) { + LocalWidgetBlock widgetButton = new LocalWidgetBlock((DefaultSharableWidget) provider, this); + widgetButton.setElementCaseEdit(isEdit); + this.add(widgetButton); + } + this.setPreferredSize(new Dimension(240, rowCount * (ShareComponentConstants.SHARE_BLOCK_HEIGHT + vgap))); + } + + private void showEmpty() { + this.setPreferredSize(new Dimension(240, 0)); + } + + public void setSelectBlock(LocalWidgetBlock block) { + this.selectedBlock = block; + this.repaint(); + } + + public LocalWidgetBlock getSelectedBlock() { + return selectedBlock; + } + + @Override + protected Container getParentContainer() { + return this.getParent().getParent(); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/ManagePane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/ManagePane.java new file mode 100644 index 000000000..67e2efe3f --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/ManagePane.java @@ -0,0 +1,245 @@ +package com.fr.design.mainframe.share.ui.local; + +import com.fr.design.constants.UIConstants; +import com.fr.design.dialog.FineJOptionPane; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.imenu.UIPopupMenu; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.share.action.CreateComponentAction; +import com.fr.design.mainframe.share.action.InstallComponentAction; +import com.fr.design.mainframe.share.action.ShareUIAspect; +import com.fr.design.mainframe.share.group.ui.GroupFileDialog; +import com.fr.design.mainframe.share.group.ui.GroupMoveDialog; +import com.fr.design.mainframe.share.ui.base.PopupMenuItem; +import com.fr.design.mainframe.share.util.ShareUIUtils; +import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.form.share.group.DefaultShareGroupManager; +import com.fr.form.share.Group; +import com.fr.general.IOUtils; +import com.fr.stable.StringUtils; + +import javax.swing.BorderFactory; +import javax.swing.Icon; +import javax.swing.JPanel; +import javax.swing.SwingConstants; +import java.awt.BorderLayout; +import java.awt.CardLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.event.ActionListener; + +/** + * @Author: Yuan.Wang + * @Date: 2020/10/29 + */ +class ManagePane extends JPanel implements ShareUIAspect { + private static final String NORMAL = "NORMAL"; + private static final String MANAGE = "MANAGE"; + private final UIButton addComponentButton; + + UIButton deleteSelectedButton; + UIButton moveGroupButton; + CardLayout cardLayout; + + public ManagePane() { + //添加组件 + addComponentButton = createAddComponentButton(); + //管理组件 + UIButton manageButton = createManageButton(); + //添加分组 + UIButton addGroupButton = createAddGroupButton(); + //删除选中 + deleteSelectedButton = createDeleteSelectedButton(); + //移动分组 + moveGroupButton = createMoveGroupButton(); + //取消 + UIButton cancelButton = createCancelButton(); + + deleteSelectedButton.setEnabled(false); + moveGroupButton.setEnabled(false); + + JPanel leftPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); + leftPanel.add(addComponentButton); + + JPanel rightPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); + rightPanel.add(manageButton); + rightPanel.add(addGroupButton); + + JPanel normalPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + normalPanel.add(leftPanel, BorderLayout.CENTER); + normalPanel.add(rightPanel, BorderLayout.EAST); + + JPanel managePanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 10, 5)); + managePanel.add(deleteSelectedButton); + managePanel.add(moveGroupButton); + managePanel.add(cancelButton); + + cardLayout = new CardLayout(); + this.setLayout(cardLayout); + this.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5)); + this.add(normalPanel, NORMAL); + this.add(managePanel, MANAGE); + } + + public void setButtonEnable(boolean enable) { + if (moveGroupButton.isEnabled() != enable) { + deleteSelectedButton.setEnabled(enable); + moveGroupButton.setEnabled(enable); + } + } + + /** + * 添加组件按钮 + */ + private UIButton createAddComponentButton() { + return createManageButton( + Toolkit.i18nText("Fine-Design_Share_Add"), + IOUtils.readIcon("/com/fr/base/images/share/filter_combo.png"), + e -> { + //创建组件和安装组件的弹窗 + UIPopupMenu popupMenu = new UIPopupMenu(); + popupMenu.setPreferredSize(new Dimension(74, 42)); + popupMenu.setOnlyText(true); + popupMenu.setBackground(UIConstants.DEFAULT_BG_RULER); + popupMenu.add(new PopupMenuItem(new CreateComponentAction(this))); + popupMenu.add(new PopupMenuItem(new InstallComponentAction())); + GUICoreUtils.showPopupMenu(popupMenu, addComponentButton, 0, addComponentButton.getSize().height); + } + ); + } + + /** + * 管理组件面板 + */ + private UIButton createManageButton() { + return createManageButton( + Toolkit.i18nText("Fine-Design_Share_Manage"), + e -> replacePanel(true) + ); + } + + /** + * 添加分组面板 + */ + private UIButton createAddGroupButton() { + return createManageButton( + Toolkit.i18nText("Fine-Design_Share_Group_Add"), + e -> new GroupFileDialog(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Design_Share_Group_Add")) { + @Override + protected void confirmClose() { + this.dispose(); + // 处理不合法的文件夹名称 + String userInput = getFileName().replaceAll("[\\\\/:*?\"<>|]", StringUtils.EMPTY); + //新建分组,刷新显示 + if (DefaultShareGroupManager.getInstance().createGroup(userInput)) { + LocalWidgetRepoPane.getInstance().refreshAllGroupPane(GroupPane.GroupCreateStrategy.CLOSURE); + } else { + ShareUIUtils.showErrorMessageDialog(Toolkit.i18nText("Fine-Design_Basic_Make_Failure")); + } + } + + @Override + protected boolean isDuplicate(String fileName) { + return DefaultShareGroupManager.getInstance().exist(fileName); + } + } + ); + } + + private UIButton createCancelButton() { + return createManageButton( + Toolkit.i18nText("Fine-Design_Share_Group_Cancel"), + e -> replacePanel(false) + ); + } + + /** + * 切换面板并刷新 + */ + public void replacePanel(boolean isEditing) { + switchPanel(isEditing); + LocalWidgetRepoPane.getInstance().refreshShowPanel(isEditing); + } + + /** + * 切换面板 + * + * @param isEditing 是否编辑 + */ + public void switchPanel(boolean isEditing) { + setButtonEnable(false); + WidgetSelectedManager.getInstance().clearSelect(); + cardLayout.show(this, isEditing ? MANAGE : NORMAL); + } + + private UIButton createDeleteSelectedButton() { + return createManageButton( + Toolkit.i18nText("Fine-Design_Share_Select_Remove"), + new Color(0xeb1d1f), + e -> { + int rv = FineJOptionPane.showConfirmDialog( + DesignerContext.getDesignerFrame(), + Toolkit.i18nText("Fine-Design_Share_Remove_Info"), + Toolkit.i18nText("Fine-Design_Share_Group_Confirm"), + FineJOptionPane.YES_NO_OPTION + ); + if (rv == FineJOptionPane.YES_OPTION) { + if (WidgetSelectedManager.getInstance().unInstallSelect()) { + //刷新界面的缓存 + FineJOptionPane.showMessageDialog(null, Toolkit.i18nText("Fine-Design_Form_Share_Module_Removed_Successful")); + replacePanel(false); + } else { + ShareUIUtils.showErrorMessageDialog(Toolkit.i18nText("Fine-Design_Form_Share_Module_Removed_Failed")); + } + } + }); + } + + private UIButton createMoveGroupButton() { + return createManageButton( + Toolkit.i18nText("Fine-Design_Share_Group_Move"), + e -> new GroupMoveDialog(DesignerContext.getDesignerFrame()) { + @Override + protected void confirmClose() { + this.dispose(); + Group group = (Group) getSelectGroupBox().getSelectedItem(); + assert group != null; + if (WidgetSelectedManager.getInstance().moveSelect(group.getGroupName())) { + replacePanel(false); + } else { + LocalWidgetRepoPane.getInstance().refreshShowPanel(); + ShareUIUtils.showErrorMessageDialog(Toolkit.i18nText("Fine-Design_Share_Group_Move_Fail_Message")); + } + } + + } + ); + } + + private UIButton createManageButton(String title, Icon icon, ActionListener actionListener) { + UIButton button = createManageButton(title, actionListener); + button.setIcon(icon); + button.setHorizontalTextPosition(SwingConstants.LEFT); + return button; + } + + private UIButton createManageButton(String title, ActionListener actionListener) { + return createManageButton(title, new Color(0x333334), actionListener); + } + + private UIButton createManageButton(String title, Color foregroundColor, ActionListener actionListener) { + UIButton button = new UIButton(title); + button.setBackground(Color.white); + button.setForeground(foregroundColor); + button.addActionListener(actionListener); + return button; + } + + @Override + public void afterOk() { + LocalWidgetRepoPane.getInstance().refreshShowPanel(false); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/ToolbarPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/ToolbarPane.java new file mode 100644 index 000000000..c720e7f9c --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/ToolbarPane.java @@ -0,0 +1,226 @@ +package com.fr.design.mainframe.share.ui.local; + +import com.fr.base.BaseUtils; +import com.fr.design.actions.UpdateAction; +import com.fr.design.constants.UIConstants; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.gui.imenu.UIPopupMenu; +import com.fr.design.gui.itextfield.UITextField; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.share.sort.WidgetSortType; +import com.fr.design.mainframe.share.ui.base.MouseClickListener; +import com.fr.design.mainframe.share.ui.base.SortPopupMenuItem; +import com.fr.design.mainframe.share.ui.widgetfilter.FilterPane; +import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.general.IOUtils; +import com.fr.stable.StringUtils; + +import javax.swing.Action; +import javax.swing.BorderFactory; +import javax.swing.Icon; +import javax.swing.JPanel; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import java.awt.BorderLayout; +import java.awt.CardLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.MouseEvent; + +/** + * @Author: Yuan.Wang + * @Date: 2020/10/29 + */ +class ToolbarPane extends JPanel { + private static final Color SEARCH_BORDER_COLOR = Color.decode("#F5F5F7"); + private static final Color SEARCH_BORDER_INPUT_COLOR = Color.decode("#419BF9"); + + private static final String NORMAL = "NORMAL"; + private static final String SEARCH = "SEARCH"; + + private UITextField searchTextField; + private final JPanel centerPane; + + //查询按钮 + private final UIButton searchButton; + //排序按钮 + private final UIButton sortButton; + //刷新按钮 + private final UIButton refreshButton; + + private final CardLayout cardLayout; + + private FilterPane filterPanel; + + public ToolbarPane() { + cardLayout = new CardLayout(); + centerPane = new JPanel(cardLayout); + + searchButton = createSearchButton(); + sortButton = createSortButton(); + refreshButton = createRefreshButton(); + filterPanel = createFilterPane(); + JPanel normalPanel = createNormalPanel(); + JPanel searchPanel = createSearchField(); + centerPane.add(normalPanel, NORMAL); + centerPane.add(searchPanel, SEARCH); + this.add(centerPane, BorderLayout.CENTER); + } + + public void addFilterPopupStateChangeListener(FilterPane.PopStateChangeListener listener) { + filterPanel.addPopupStateChangeListener(listener); + } + + private UIButton createSearchButton() { + return createToolButton( + IOUtils.readIcon("/com/fr/base/images/share/search_icon.png"), + Toolkit.i18nText("Fine-Design_Share_Search"), + e -> { + cardLayout.show(centerPane, SEARCH); + searchTextField.requestFocus(); + } + ); + } + + private UIButton createSortButton() { + return createToolButton( + IOUtils.readIcon("/com/fr/base/images/share/sort_icon.png"), + Toolkit.i18nText("Fine-Design_Share_Sort"), + e -> { + UIPopupMenu popupMenu = new UIPopupMenu(); + popupMenu.setOnlyText(true); + popupMenu.setBackground(UIConstants.DEFAULT_BG_RULER); + popupMenu.add(new SortPopupMenuItem(new SortAction(WidgetSortType.INSTALL_TIME))); + popupMenu.add(new SortPopupMenuItem(new SortAction(WidgetSortType.COMPONENT_NAME))); + + GUICoreUtils.showPopupMenu(popupMenu, sortButton, 0, sortButton.getSize().height); + } + ); + } + + private UIButton createRefreshButton() { + return createToolButton( + IOUtils.readIcon("/com/fr/base/images/share/refresh.png"), + Toolkit.i18nText("Fine-Design_Basic_Refresh"), + e -> { + filterPanel.reset(); + LocalWidgetRepoPane.getInstance().refreshPane(); + } + ); + } + + private FilterPane createFilterPane() { + filterPanel = FilterPane.createLocalFilterPane(); + filterPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 10)); + filterPanel.registerChangeListener(e -> LocalWidgetRepoPane.getInstance().refreshShowPanel()); + return filterPanel; + } + + private JPanel createNormalPanel() { + JPanel panel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + JPanel buttonPane = new JPanel(new FlowLayout(FlowLayout.RIGHT, 0, 0)); + buttonPane.add(searchButton); + buttonPane.add(sortButton); + buttonPane.add(refreshButton); + panel.add(filterPanel, BorderLayout.CENTER); + panel.add(buttonPane, BorderLayout.EAST); + return panel; + } + + private JPanel createSearchField() { + final JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + jPanel.setPreferredSize(new Dimension(228, 10)); + jPanel.setBorder(BorderFactory.createLineBorder(SEARCH_BORDER_COLOR)); + jPanel.setBackground(Color.WHITE); + UILabel label = new UILabel(IOUtils.readIcon("/com/fr/base/images/share/search_icon.png")); + label.setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 0)); + jPanel.add(label, BorderLayout.WEST); + this.searchTextField = new UITextField(); + this.searchTextField.setBorderPainted(false); + this.searchTextField.setPlaceholder(Toolkit.i18nText("Fine-Design_Basic_Plugin_Search")); + this.searchTextField.addFocusListener(new FocusListener() { + @Override + public void focusGained(FocusEvent e) { + jPanel.setBorder(BorderFactory.createLineBorder(SEARCH_BORDER_INPUT_COLOR)); + jPanel.repaint(); + } + + @Override + public void focusLost(FocusEvent e) { + jPanel.setBorder(BorderFactory.createLineBorder(SEARCH_BORDER_COLOR)); + jPanel.repaint(); + } + }); + this.searchTextField.getDocument().addDocumentListener(new DocumentListener() { + @Override + public void insertUpdate(DocumentEvent e) { + filterByName(); + } + + @Override + public void removeUpdate(DocumentEvent e) { + filterByName(); + } + + @Override + public void changedUpdate(DocumentEvent e) { + filterByName(); + } + }); + jPanel.add(this.searchTextField, BorderLayout.CENTER); + UILabel xLabel = new UILabel(BaseUtils.readIcon("/com/fr/design/images/buttonicon/close_icon.png")); + xLabel.addMouseListener(new MouseClickListener() { + @Override + public void mouseClicked(MouseEvent e) { + searchTextField.setText(StringUtils.EMPTY); + cardLayout.show(centerPane, NORMAL); + } + }); + xLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); + jPanel.add(xLabel, BorderLayout.EAST); + + return jPanel; + } + + private void filterByName() { + String text = searchTextField.getText(); + boolean searchStatus = !StringUtils.isEmpty(text); + sortButton.setEnabled(!searchStatus); + LocalWidgetRepoPane.getInstance().searchByKeyword(text); + } + + private static class SortAction extends UpdateAction { + private final WidgetSortType sortType; + + public SortAction(WidgetSortType sortType) { + this.putValue(Action.SMALL_ICON, null); + this.setName(sortType.getDisplayName()); + this.sortType = sortType; + } + + @Override + public void actionPerformed(ActionEvent e) { + LocalWidgetRepoPane.getInstance().sortWidget(sortType); + } + } + + /** + * 创建工具条按钮 + */ + private UIButton createToolButton(Icon icon, String toolTip, ActionListener actionListener) { + UIButton toolButton = new UIButton(); + toolButton.setIcon(icon); + toolButton.setToolTipText(toolTip); + toolButton.set4ToolbarButton(); + toolButton.addActionListener(actionListener); + return toolButton; + } + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/WidgetSelectedManager.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/WidgetSelectedManager.java new file mode 100644 index 000000000..d211887f5 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/WidgetSelectedManager.java @@ -0,0 +1,121 @@ +package com.fr.design.mainframe.share.ui.local; + +import com.fr.form.share.group.DefaultShareGroupManager; +import com.fr.form.share.Group; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * @Author: Yuan.Wang + * @Date: 2021/1/15 + */ +public class WidgetSelectedManager { + private final Map> selectedWidgetMap = new HashMap<>(); + + private WidgetSelectedManager() { + + } + + private static class Holder { + private static final WidgetSelectedManager INSTANCE = new WidgetSelectedManager(); + } + + public static WidgetSelectedManager getInstance() { + return Holder.INSTANCE; + } + + /** + * 添加选中组件 + */ + public synchronized void addSelect(String groupName, String uuid) { + if (selectedWidgetMap.containsKey(groupName)) { + selectedWidgetMap.get(groupName).add(uuid); + } else { + selectedWidgetMap.put(groupName, Stream.of(uuid).collect(Collectors.toList())); + } + } + + /** + * 删除选中组件 + */ + public synchronized void removeSelect(String groupName, String uuid) { + if (selectedWidgetMap.containsKey(groupName)) { + selectedWidgetMap.get(groupName).remove(uuid); + } + } + + /** + * 卸载单个选中组件 + */ + public synchronized boolean unInstallSelect(String groupName, String uuid) { + Group group = DefaultShareGroupManager.getInstance().getGroup(groupName); + return group != null && group.unInstallSelect(Stream.of(uuid).collect(Collectors.toList())); + } + + /** + * 卸载所有选中组件 + */ + public synchronized boolean unInstallSelect() { + boolean result = true; + for (String groupName : selectedWidgetMap.keySet()) { + Group group = DefaultShareGroupManager.getInstance().getGroup(groupName); + result &= group != null && group.unInstallSelect(selectedWidgetMap.get(groupName)); + } + selectedWidgetMap.clear(); + return result; + } + + /** + * 是否选中某组件 + */ + public synchronized boolean isSelected(String groupName, String uuid) { + return selectedWidgetMap.containsKey(groupName) && selectedWidgetMap.get(groupName).contains(uuid); + } + + /** + * 清空选中组件 + */ + public synchronized void clearSelect() { + selectedWidgetMap.clear(); + } + + /** + * 被选中是否为空 + */ + public synchronized boolean isSelectEmpty() { + return selectedWidgetMap.isEmpty() || selectedWidgetMap.values().stream().noneMatch(list -> (list.size() > 0)); + } + + /** + * 移动所有选中到某分组 + */ + public synchronized boolean moveSelect(String toGroupName) { + boolean result = true; + Group toGroup = DefaultShareGroupManager.getInstance().getGroup(toGroupName); + if (toGroup == null) { + return false; + } + for (String groupName : selectedWidgetMap.keySet()) { + Group fromGroup = DefaultShareGroupManager.getInstance().getGroup(groupName); + result &= fromGroup != null && fromGroup.moveModule(toGroup, selectedWidgetMap.get(groupName)); + } + selectedWidgetMap.clear(); + return result; + } + + /** + * 移动单独组件到某分组 + */ + public synchronized boolean moveSelect(String formGroupName, String toGroupName, String uuid) { + Group fromGroup = DefaultShareGroupManager.getInstance().getGroup(formGroupName); + Group toGroup = DefaultShareGroupManager.getInstance().getGroup(toGroupName); + if (fromGroup == null || toGroup == null) { + return false; + } + return fromGroup.moveModule(toGroup, Stream.of(uuid).collect(Collectors.toList())); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/AbstractOnlineWidgetShowPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/AbstractOnlineWidgetShowPane.java new file mode 100644 index 000000000..fc2390d61 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/AbstractOnlineWidgetShowPane.java @@ -0,0 +1,269 @@ +package com.fr.design.mainframe.share.ui.online; + +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.share.sort.OnlineWidgetSortType; +import com.fr.design.mainframe.share.ui.base.FlexSearchFieldPane; +import com.fr.design.mainframe.share.ui.base.LoadingPane; +import com.fr.design.mainframe.share.ui.widgetfilter.FilterPane; +import com.fr.form.share.base.DataLoad; +import com.fr.form.share.bean.OnlineShareWidget; +import com.fr.form.share.utils.ShareUtils; +import com.fr.general.IOUtils; +import com.fr.stable.StringUtils; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.SwingWorker; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import java.awt.BorderLayout; +import java.awt.CardLayout; +import java.awt.Color; +import java.awt.FlowLayout; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Created by kerry on 2020-10-19 + */ +public abstract class AbstractOnlineWidgetShowPane extends JPanel { + private static final String SEARCH_RESULT_PANE = "SEARCH_RESULT_PANE"; + private static final String MAIN_FILTER_TAB_PANE = "MAIN_FILTER_TAB_PANE"; + + private JPanel componentSelectPane; + private JPanel searchResultShowPane; + private JPanel mainCenterPane; + private FilterPane filterPane; + private JPanel centerPane; + private SortTabPane sortTabPane; + + private final JPanel loadingPane = new LoadingPane(); + + private OnlineShareWidget[] sharableWidgetProviders; + + //缓存一份用于搜索 + private final OnlineShareWidget[] sharableWidgetCache; + //主面板和搜索面板的cardLayout + private CardLayout mainCardLayout; + + + public AbstractOnlineWidgetShowPane(OnlineShareWidget[] sharableWidgetProviders) { + this.sharableWidgetCache = sharableWidgetProviders; + this.sharableWidgetProviders = sharableWidgetProviders; + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + JPanel contentPane = initContentPane(); + this.add(contentPane, BorderLayout.CENTER); + } + + protected JPanel initContentPane() { + JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + OnlineWidgetSortType.COMPOSITE.sort(sharableWidgetProviders); + componentSelectPane = createOnlineWidgetSelectPane(sharableWidgetProviders); + centerPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + centerPane.add(componentSelectPane, BorderLayout.CENTER); + filterPane = createFilterPane(); + filterPane.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 8)); + initFilterPaneListener(filterPane); + sortTabPane = new SortTabPane(); + initSortTabPane(sortTabPane); + FlexSearchFieldPane flexSearchPane = new FlexSearchFieldPane(filterPane); + initSearchTextFieldPaneListener(flexSearchPane); + + JPanel northPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + northPane.add(flexSearchPane, BorderLayout.CENTER); + northPane.add(sortTabPane, BorderLayout.SOUTH); + initNorthPane(jPanel, northPane); + + searchResultShowPane = createOnlineWidgetSelectPane(new OnlineShareWidget[]{}); + mainCardLayout = new CardLayout(); + mainCenterPane = new JPanel(mainCardLayout); + mainCenterPane.add(centerPane, MAIN_FILTER_TAB_PANE); + mainCenterPane.add(searchResultShowPane, SEARCH_RESULT_PANE); + jPanel.add(mainCenterPane, BorderLayout.CENTER); + + filterPane.addPopupStateChangeListener(state -> setWidgetPaneScrollEnable(!state)); + return jPanel; + } + + protected void initNorthPane(JPanel jPanel, JPanel northPane) { + jPanel.add(northPane, BorderLayout.NORTH); + } + + + protected OnlineWidgetSelectPane createOnlineWidgetSelectPane(OnlineShareWidget[] sharableWidgetProviders) { + return new OnlineWidgetSelectPane(sharableWidgetProviders, filterPane, 50); + } + + protected OnlineWidgetSelectPane createOnlineWidgetSelectPane(DataLoad dataLoad) { + return new OnlineWidgetSelectPane(dataLoad, filterPane, 50); + } + + protected FilterPane createFilterPane() { + return FilterPane.createOnlineFilterPane(); + } + + protected OnlineShareWidget[] getSharableWidgetProviders() { + return sharableWidgetProviders; + } + + public void searchByKeyword(String text) { + if (StringUtils.isEmpty(text)) { + this.mainCardLayout.show(mainCenterPane, MAIN_FILTER_TAB_PANE); + return; + } + List widgets = new ArrayList<>(); + if (StringUtils.isNotEmpty(text)) { + for (OnlineShareWidget provider : sharableWidgetCache) { + if (provider.getName().toLowerCase().contains(text)) { + widgets.add(provider); + } + } + } + + if (searchResultShowPane != null) { + mainCenterPane.remove(searchResultShowPane); + } + this.searchResultShowPane = createOnlineWidgetSelectPane(widgets.toArray(new OnlineShareWidget[widgets.size()])); + this.mainCenterPane.add(searchResultShowPane, SEARCH_RESULT_PANE); + this.mainCardLayout.show(mainCenterPane, SEARCH_RESULT_PANE); + this.validate(); + this.repaint(); + + } + + public void initFilterPaneListener(FilterPane filterPane) { + filterPane.registerChangeListener(new ChangeListener() { + @Override + public void stateChanged(final ChangeEvent e) { + String filterStr = e.getSource().toString(); + centerPane.remove(componentSelectPane); + componentSelectPane = createOnlineWidgetSelectPane(() -> { + sharableWidgetProviders = new OnlineShareWidget[0]; + sharableWidgetProviders = ShareUtils.getFilterWidgets(filterStr); + return sharableWidgetProviders; + }); + centerPane.add(componentSelectPane, BorderLayout.CENTER); + AbstractOnlineWidgetShowPane.this.validate(); + AbstractOnlineWidgetShowPane.this.repaint(); + } + }); + } + + public void initSearchTextFieldPaneListener(FlexSearchFieldPane searchFieldPane) { + searchFieldPane.registerChangeListener(event -> { + Object object = event.getSource(); + if (object instanceof String) { + String text = (String) object; + sortTabPane.setVisible(StringUtils.isEmpty(text)); + searchByKeyword(text); + } + }); + } + + public void initSortTabPane(SortTabPane sortTabPane) { + + } + + private void setWidgetPaneScrollEnable(boolean enable) { + if (componentSelectPane instanceof OnlineWidgetSelectPane) { + ((OnlineWidgetSelectPane) componentSelectPane).setWidgetPaneScrollEnable(enable); + } + } + + public class SortTabPane extends JPanel { + private final Color BLUE = Color.decode("#419BF9"); + private int index; + private final UILabel[] labels; + private final Map recordMap; + private List mouseListeners = new ArrayList<>(); + + public SortTabPane() { + setLayout(new FlowLayout(FlowLayout.LEFT)); + setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 10)); + OnlineWidgetSortType[] sortTypes = OnlineWidgetSortType.values(); + recordMap = new HashMap<>(); + labels = new UILabel[sortTypes.length]; + int i = 0; + for (OnlineWidgetSortType sortType : sortTypes) { + labels[i] = createTab(sortType); + recordMap.put(sortType.getDisplayName(), i); + add(labels[i]); + i++; + if (i != sortTypes.length) { + add(createSeparator()); + } + } + setIndex(0); + } + + public void setIndex(int index) { + labels[this.index].setForeground(Color.black); + labels[index].setForeground(BLUE); + this.index = index; + repaint(); + } + + public int getIndex() { + return index; + } + + private UILabel createTab(OnlineWidgetSortType sortType) { + UILabel label = new UILabel(sortType.getDisplayName()); + label.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + if (sharableWidgetProviders.length == 0) { + return; + } + String title = label.getText(); + if (index != recordMap.get(title)) { + setIndex(recordMap.get(title)); + } + if (componentSelectPane != null) { + centerPane.remove(componentSelectPane); + centerPane.add(loadingPane); + } + AbstractOnlineWidgetShowPane.this.validate(); + AbstractOnlineWidgetShowPane.this.repaint(); + new SwingWorker() { + @Override + protected Boolean doInBackground() { + sortType.sort(sharableWidgetProviders); + componentSelectPane = createOnlineWidgetSelectPane(sharableWidgetProviders); + return true; + } + + @Override + protected void done() { + centerPane.removeAll(); + centerPane.add(componentSelectPane, BorderLayout.CENTER); + AbstractOnlineWidgetShowPane.this.validate(); + AbstractOnlineWidgetShowPane.this.repaint(); + } + }.execute(); + + for (MouseListener listener : mouseListeners) { + listener.mouseClicked(e); + } + } + }); + return label; + } + + private UILabel createSeparator() { + UILabel label = new UILabel(IOUtils.readIcon("/com/fr/base/images/share/separator.png")); + label.setBorder(BorderFactory.createEmptyBorder(0, 2, 0, 2)); + return label; + } + + public void registerSortTabMouseListener(MouseListener listener) { + mouseListeners.add(listener); + } + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineDownloadPackagePane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineDownloadPackagePane.java new file mode 100644 index 000000000..59a09c466 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineDownloadPackagePane.java @@ -0,0 +1,253 @@ +package com.fr.design.mainframe.share.ui.online; + +import com.fr.design.dialog.FineJOptionPane; +import com.fr.design.gui.icontainer.UIScrollPane; +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.share.ui.base.DownloadProgressPane; +import com.fr.design.mainframe.share.ui.base.ImitationProgress; +import com.fr.design.mainframe.share.ui.base.MouseClickListener; +import com.fr.design.mainframe.share.ui.block.OnlineWidgetBlock; +import com.fr.design.mainframe.share.ui.block.SimpleWidgetBlock; +import com.fr.design.mainframe.share.ui.local.LocalWidgetRepoPane; +import com.fr.design.mainframe.share.ui.online.widgetpackage.OnlineWidgetPackagesShowPane; +import com.fr.design.mainframe.share.util.DownloadUtils; +import com.fr.design.mainframe.share.util.InstallUtils; +import com.fr.design.mainframe.share.util.ShareComponentUtils; +import com.fr.form.share.bean.OnlineShareWidget; +import com.fr.form.share.Group; +import com.fr.log.FineLoggerFactory; +import com.fr.stable.StableUtils; +import org.jetbrains.annotations.Nullable; + +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.SwingWorker; +import java.awt.AlphaComposite; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Composite; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.event.MouseEvent; +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ExecutionException; + +/** + * @Author: Yuan.Wang + * @Date: 2020/12/22 + */ +public class OnlineDownloadPackagePane extends OnlineWidgetSelectPane { + private final String packageId; + private volatile double process; + + + private ImitationThread imitationThread; + private SwingWorker downloadWorker; + private DownloadProgressPane downloadProgressPane; + private final OnlineWidgetPackagesShowPane parentPane; + + + public OnlineDownloadPackagePane(OnlineWidgetPackagesShowPane parentPane, OnlineShareWidget[] providers, int widgetsPerNum) { + super(providers, widgetsPerNum); + this.parentPane = parentPane; + this.packageId = parentPane.getCurrentPackageId(); + } + + protected OnlineWidgetBlock createWidgetBlock(OnlineShareWidget provider) { + return new SimpleWidgetBlock(provider, this); + } + + protected void setScrollPaneStyle(UIScrollPane scrollPane) { + scrollPane.setBorder(null); + scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); + scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); + scrollPane.setWheelScrollingEnabled(false); + } + + @Override + protected boolean pagePaneEnable() { + return false; + } + + protected JPanel createWidgetPane() { + return new JPanel() { + @Override + public void paint(Graphics g) { + super.paint(g); + Graphics2D g2d = (Graphics2D) g; + Composite oldComposite = g2d.getComposite(); + AlphaComposite composite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.65f); + g2d.setComposite(composite); + g2d.setColor(Color.DARK_GRAY); + g2d.fillRect(0, 0, getWidth(), getHeight()); + g2d.setComposite(oldComposite); + } + }; + } + + protected JPanel createContentPane(JPanel widgetPane) { + JPanel panel = new JPanel() { + @Override + public void paint(Graphics g) { + for (int i = 0; i < getComponentCount(); i++) { + getComponent(i).setSize(getSize()); + } + super.paint(g); + } + }; + panel.setLayout(null); + downloadProgressPane = new DownloadProgressPane(new MouseClickListener() { + @Override + public void mouseClicked(MouseEvent e) { + int returnVal = FineJOptionPane.showConfirmDialog(DesignerContext.getDesignerFrame(), + Toolkit.i18nText("Fine-Design_Share_Download_Cancel_Confirm"), Toolkit.i18nText("Fine-Design_Share_Group_Confirm"), + FineJOptionPane.OK_CANCEL_OPTION); + if (returnVal == FineJOptionPane.OK_OPTION) { + //取消下载线程 + imitationThread.interrupt(); + downloadWorker.cancel(false); + + //切换面板 + parentPane.resetWidgetDetailPane(packageId, getSharableWidgetProviders()); + } + } + }); + panel.add(downloadProgressPane); + panel.add(widgetPane, BorderLayout.CENTER); + return panel; + } + + public void downloadWidget(OnlineShareWidget onlineShareWidget) { + + final com.fr.design.extra.Process downloadProcess = aDouble -> { + OnlineDownloadPackagePane.this.process = 0.8 * aDouble; + downloadProgressPane.updateProgress(process); + }; + final com.fr.design.extra.Process installProcess = aDouble -> { + OnlineDownloadPackagePane.this.process = 0.8 + 0.2 * aDouble; + downloadProgressPane.updateProgress(process); + }; + + downloadProcess.process(0.0D); + + //假进度线程 + final ImitationProgress imitationProgress = new ImitationProgress(downloadProcess, getSharableWidgetNum()); + imitationThread = new ImitationThread(imitationProgress); + imitationThread.setName("Component-ImitationProcessThread"); + + //下载线程 + downloadWorker = new DownLoadSwingWorker(installProcess, onlineShareWidget); + + parallel(imitationThread, downloadWorker); + } + + private void parallel(Thread imitationProcessThread, SwingWorker worker) { + imitationProcessThread.start(); + worker.execute(); + } + + /** + * 假进度线程 + */ + private static class ImitationThread extends Thread { + + private final ImitationProgress imitationProgress; + + public ImitationThread(ImitationProgress progress) { + imitationProgress = progress; + } + + @Override + public void run() { + imitationProgress.start(); + } + + public void complete() { + imitationProgress.completed(); + this.interrupt(); + } + + public void stopThread() { + imitationProgress.stop(); + this.interrupt(); + } + } + + private class DownLoadSwingWorker extends SwingWorker { + final com.fr.design.extra.Process installProcess; + final OnlineShareWidget onlineShareWidget; + + public DownLoadSwingWorker(com.fr.design.extra.Process installProcess, OnlineShareWidget onlineShareWidget) { + this.installProcess = installProcess; + this.onlineShareWidget = onlineShareWidget; + } + + @Override + @Nullable + protected Group doInBackground() { + final String filePath; + List failureList = new ArrayList<>(); + try { + filePath = DownloadUtils.downloadPackage(onlineShareWidget.getId(), onlineShareWidget.getName(), DownLoadSwingWorker.this::isCancelled); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + imitationThread.stopThread(); + return null; + } + if (this.isCancelled()) { + imitationThread.stopThread(); + StableUtils.deleteFile(new File(filePath)); + return null; + } + + //等待假进度线程结束 + imitationThread.complete(); + try { + imitationThread.join(); + } catch (InterruptedException ignore) { + } + + //再判断一次 + if (this.isCancelled()) { + StableUtils.deleteFile(new File(filePath)); + return null; + } + ShareComponentUtils.checkReadMe(); + //安装 + File file = new File(filePath); + installProcess.process(0.0D); + downloadProgressPane.changeState(); + InstallUtils.InstallResult result = null; + try { + if (file.exists()) { + result = InstallUtils.installReusFile(file, System.currentTimeMillis(), failureList, installProcess); + } + } finally { + //删掉下载组件的目录 + StableUtils.deleteFile(file); + } + return result == null ? null : result.group; + } + + @Override + protected void done() { + OnlineDownloadPackagePane.this.process = 0.0D; + //替换面板,显示下载label + parentPane.resetWidgetDetailPane(packageId, getSharableWidgetProviders()); + parentPane.repaint(); + if (!isCancelled()) { + try { + Group group = get(); + if (group != null) { + LocalWidgetRepoPane.getInstance().addGroup(group); + } + } catch (InterruptedException | ExecutionException e) { + FineLoggerFactory.getLogger().error(e, e.getMessage()); + } + } + } + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineResourceManager.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineResourceManager.java new file mode 100644 index 000000000..6a99209d3 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineResourceManager.java @@ -0,0 +1,53 @@ +package com.fr.design.mainframe.share.ui.online; + +import javax.swing.SwingWorker; +import java.util.ArrayList; +import java.util.List; + +/** + * Created by kerry on 2020-12-10 + */ +public class OnlineResourceManager { + private static class HOLDER { + private static final OnlineResourceManager singleton = new OnlineResourceManager(); + } + + private OnlineResourceManager(){ + + } + + public static OnlineResourceManager getInstance() { + return HOLDER.singleton; + } + + private SwingWorker swingWorker; + + private final List loaderList = new ArrayList<>(); + + public void cancelLoad() { + if (swingWorker != null) { + swingWorker.cancel(true); + } + this.loaderList.clear(); + } + + public void addLoader(ResourceLoader loader) { + this.loaderList.add(loader); + } + + public void loadImage() { + swingWorker = new SwingWorker() { + @Override + protected Boolean doInBackground() { + for (ResourceLoader loader : loaderList) { + loader.load(); + } + return true; + } + }; + swingWorker.execute(); + + } + + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetRepoPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetRepoPane.java new file mode 100644 index 000000000..af329cde8 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetRepoPane.java @@ -0,0 +1,189 @@ +package com.fr.design.mainframe.share.ui.online; + +import com.fr.base.BaseUtils; +import com.fr.design.dialog.BasicPane; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.share.ui.base.LoadingPane; +import com.fr.design.mainframe.share.ui.base.MouseClickListener; +import com.fr.form.share.bean.OnlineShareWidget; +import com.fr.form.share.utils.ShareUtils; +import com.fr.log.FineLoggerFactory; +import com.fr.stable.StringUtils; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.SwingConstants; +import javax.swing.SwingWorker; +import java.awt.BorderLayout; +import java.awt.CardLayout; +import java.awt.Color; +import java.awt.Cursor; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.event.MouseEvent; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ExecutionException; + + +/** + * Created by kerry on 2020-10-16 + */ +public class OnlineWidgetRepoPane extends BasicPane { + private static final String MARKET_URL = "https://market.fanruan.com/reuse"; + private OnlineWidgetTabPane componentTabPane; + private JPanel centerPane; + private boolean isShowPackagePanel = false; + private CardLayout cardLayout; + + enum Status {LOADING, DISCONNECTED, NORMAL} + + public static OnlineWidgetRepoPane getInstance() { + return OnlineWidgetRepoPane.HOLDER.singleton; + } + + private static class HOLDER { + private static final OnlineWidgetRepoPane singleton = new OnlineWidgetRepoPane(); + } + + @Override + protected String title4PopupWindow() { + return Toolkit.i18nText("Fine-Design_Share_Online"); + } + + public OnlineWidgetRepoPane() { + initPane(); + } + + public boolean isShowPackagePanel() { + return isShowPackagePanel; + } + + public void setShowPackagePanel(boolean showPackagePanel) { + isShowPackagePanel = showPackagePanel; + } + + private void initPane() { + cardLayout = new CardLayout(); + this.setLayout(cardLayout); + this.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0)); + this.centerPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + + this.add(new LoadingPane(), Status.LOADING.name()); + this.add(this.centerPane, Status.NORMAL.name()); + this.add(createInternetErrorPane(), Status.DISCONNECTED.name()); + + switchPane(Status.LOADING); + synchronizedLoadingContent(); + } + + private void addCenterPane() { + this.centerPane.removeAll(); + this.centerPane.add(this.componentTabPane, BorderLayout.CENTER); + this.switchPane(Status.NORMAL); + } + + public void switch2InternetErrorPane() { + switchPane(Status.DISCONNECTED); + } + + private void switchPane(Status status) { + cardLayout.show(this, status.name()); + } + + private void synchronizedLoadingContent() { + new SwingWorker() { + @Override + protected Boolean doInBackground() throws Exception { + return initContentPane(); + } + + @Override + protected void done() { + try { + if (get()) { + addCenterPane(); + } + } catch (InterruptedException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + Thread.currentThread().interrupt(); + } catch (ExecutionException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + } + }.execute(); + } + + private boolean initContentPane() { + List sharableWidgets = new ArrayList<>(); + List sharableWidgetPackage = new ArrayList<>(); + + try { + ShareUtils.getAllSharableWidgetsFromShop(sharableWidgets, sharableWidgetPackage); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + switchPane(Status.DISCONNECTED); + return false; + } + this.componentTabPane = new OnlineWidgetTabPane(sharableWidgets.toArray(new OnlineShareWidget[sharableWidgets.size()]), + sharableWidgetPackage.toArray(new OnlineShareWidget[sharableWidgetPackage.size()])); + + return true; + } + + private void reload() { + this.removeAll(); + initPane(); + this.validate(); + this.repaint(); + } + + private JPanel createInternetErrorPane() { + JPanel panel = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, FlowLayout.LEADING, 0, 5); + UILabel imagePanel = new UILabel(BaseUtils.readIcon("/com/fr/base/images/share/internet_error.png")); + imagePanel.setPreferredSize(new Dimension(240, 96)); + imagePanel.setHorizontalAlignment(SwingConstants.CENTER); + panel.add(imagePanel); + UILabel uiLabel = tipLabel(Toolkit.i18nText("Fine-Design_Share_Internet_Connect_Failed")); + uiLabel.setForeground(Color.decode("#8F8F92")); + UILabel reloadLabel = tipLabel(Toolkit.i18nText("Fine-Design_Share_Online_Reload")); + reloadLabel.setForeground(Color.decode("#419BF9")); + reloadLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + reloadLabel.addMouseListener(new MouseClickListener() { + @Override + public void mouseClicked(MouseEvent e) { + super.mouseClicked(e); + reload(); + } + }); + + + UILabel tipLabel1 = tipLabel(Toolkit.i18nText("Fine-Design_Share_Internet_Connect_Failed_Tip1")); + tipLabel1.setForeground(Color.decode("#8F8F92")); + UILabel tipLabel2 = tipLabel(Toolkit.i18nText("Fine-Design_Share_Internet_Connect_Failed_Tip2")); + tipLabel2.setForeground(Color.decode("#8F8F92")); + UILabel tipLabel3 = tipLabel(MARKET_URL); + tipLabel3.setForeground(Color.decode("#8F8F92")); + + + UILabel emptyLabel = tipLabel(StringUtils.EMPTY); + panel.add(uiLabel); + panel.add(reloadLabel); + panel.add(emptyLabel); + panel.add(tipLabel1); + panel.add(tipLabel2); + panel.add(tipLabel3); + panel.setBorder(BorderFactory.createEmptyBorder(240, 0, 0, 0)); + return panel; + } + + private UILabel tipLabel(String text) { + UILabel tipLabel = new UILabel(text); + tipLabel.setHorizontalAlignment(SwingConstants.CENTER); + tipLabel.setPreferredSize(new Dimension(240, 20)); + return tipLabel; + } + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetSelectPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetSelectPane.java new file mode 100644 index 000000000..61e3ced83 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetSelectPane.java @@ -0,0 +1,225 @@ +package com.fr.design.mainframe.share.ui.online; + +import com.fr.design.gui.icontainer.UIScrollPane; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.share.AbstractWidgetSelectPane; +import com.fr.design.mainframe.share.ui.base.LoadingPane; +import com.fr.design.mainframe.share.ui.base.NoMatchPane; +import com.fr.design.mainframe.share.ui.base.PagingFiledPane; +import com.fr.design.mainframe.share.ui.block.OnlineWidgetBlock; +import com.fr.design.mainframe.share.ui.block.PreviewWidgetBlock; +import com.fr.design.mainframe.share.ui.widgetfilter.FilterPane; +import com.fr.form.share.base.DataLoad; +import com.fr.form.share.bean.OnlineShareWidget; +import com.fr.form.share.constants.ShareComponentConstants; +import com.fr.form.share.utils.ShareUtils; +import com.fr.log.FineLoggerFactory; +import com.fr.stable.ArrayUtils; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.SwingWorker; +import java.awt.BorderLayout; +import java.awt.CardLayout; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.util.concurrent.ExecutionException; + +/** + * Created by kerry on 2020-10-19 + */ +public class OnlineWidgetSelectPane extends AbstractWidgetSelectPane { + protected static final int H_GAP = 5; + protected static final int V_GAP = 10; + + enum PaneStatue {NORMAL, NO_MATCH, LOADING, DISCONNECTED} + + private OnlineShareWidget[] sharableWidgetProviders; + private PagingFiledPane pagingFiledPane; + private JPanel contentPane; + private UIScrollPane scrollPane; + private FilterPane filterPane; + private final int widgetsPerNum; + private CardLayout cardLayout; + + public OnlineWidgetSelectPane(OnlineShareWidget[] providers, FilterPane filterPane, int widgetsPerNum) { + this(providers, widgetsPerNum); + this.filterPane = filterPane; + } + + public OnlineWidgetSelectPane(final DataLoad dataLoad, FilterPane filterPane, final int widgetsPerNum) { + this(dataLoad, widgetsPerNum); + this.filterPane = filterPane; + } + + public OnlineWidgetSelectPane(OnlineShareWidget[] providers, int widgetsPerNum) { + this.widgetsPerNum = widgetsPerNum; + sharableWidgetProviders = providers; + init(); + initPagingPane(); + switchPane(createComponents()); + } + + public OnlineWidgetSelectPane(final DataLoad dataLoad, final int widgetsPerNum) { + this.widgetsPerNum = widgetsPerNum; + init(); + //异步获取组件信息 + new SwingWorker() { + @Override + protected PaneStatue doInBackground() { + sharableWidgetProviders = dataLoad.load(); + initPagingPane(); + return createComponents(); + } + + @Override + protected void done() { + try { + switchPane(get()); + } catch (InterruptedException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + Thread.currentThread().interrupt(); + } catch (ExecutionException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + } + }.execute(); + } + + private void init() { + cardLayout = new CardLayout(); + this.setLayout(cardLayout); + // 设置面板的边框 ,距离上、左、下、右 的距离 + this.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0)); + contentPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + this.add(new LoadingPane(), PaneStatue.LOADING.name()); + this.add(new NoMatchPane(), PaneStatue.NO_MATCH.name()); + this.add(contentPane, PaneStatue.NORMAL.name()); + switchPane(PaneStatue.LOADING); + } + + public int getSharableWidgetNum() { + return sharableWidgetProviders == null ? 0 : sharableWidgetProviders.length; + } + + public OnlineShareWidget[] getSharableWidgetProviders() { + return sharableWidgetProviders; + } + + /** + * 切换需要显示的面板 + */ + private void switchPane(PaneStatue statue) { + if (statue == PaneStatue.DISCONNECTED) { + OnlineWidgetRepoPane.getInstance().switch2InternetErrorPane(); + return; + } + cardLayout.show(this, statue.name()); + if (statue == PaneStatue.NORMAL) { + //异步加载组件缩略图 + OnlineResourceManager.getInstance().loadImage(); + } + } + + private void synchronizedLoadingContent() { + new SwingWorker() { + @Override + protected PaneStatue doInBackground() { + return createComponents(); + } + + @Override + protected void done() { + try { + switchPane(get()); + } catch (InterruptedException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + Thread.currentThread().interrupt(); + } catch (ExecutionException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + } + }.execute(); + } + + private void initPagingPane() { + this.pagingFiledPane = new PagingFiledPane(sharableWidgetProviders.length, widgetsPerNum); + this.pagingFiledPane.registerChangeListener(event -> { + OnlineWidgetSelectPane.this.switchPane(PaneStatue.LOADING); + synchronizedLoadingContent(); + }); + pagingFiledPane.setEnable(pagePaneEnable()); + } + + private PaneStatue createComponents() { + if (ArrayUtils.isEmpty(sharableWidgetProviders)) { + return PaneStatue.NO_MATCH; + } + if (!ShareUtils.testConnection()) { + return PaneStatue.DISCONNECTED; + } + OnlineResourceManager.getInstance().cancelLoad(); + + contentPane.removeAll(); + scrollPane = createScrollPane(); + + contentPane.add(scrollPane, BorderLayout.CENTER); + contentPane.add(this.pagingFiledPane, BorderLayout.SOUTH); + return PaneStatue.NORMAL; + } + + private UIScrollPane createScrollPane() { + OnlineShareWidget[] showWidgets = this.pagingFiledPane.getShowItems(this.sharableWidgetProviders); + JPanel widgetPane = createWidgetPane(); + widgetPane.setLayout(new FlowLayout(FlowLayout.LEFT, H_GAP, V_GAP)); + for (OnlineShareWidget provider : showWidgets) { + PreviewWidgetBlock widgetButton = createWidgetBlock(provider); + widgetPane.add(widgetButton); + } + widgetPane.setPreferredSize(new Dimension(240, getPaneHeight(showWidgets.length))); + + UIScrollPane scrollPane = new UIScrollPane(createContentPane(widgetPane)); + setScrollPaneStyle(scrollPane); + return scrollPane; + } + + protected JPanel createWidgetPane() { + return new JPanel(); + } + + protected JPanel createContentPane(JPanel widgetPane) { + JPanel panel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + panel.add(widgetPane, BorderLayout.CENTER); + return panel; + } + + protected boolean pagePaneEnable() { + return true; + } + + protected void setScrollPaneStyle(UIScrollPane scrollPane) { + scrollPane.setBorder(null); + scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); + scrollPane.setWheelScrollingEnabled(filterPane == null || !filterPane.isShowPopup()); + } + + protected PreviewWidgetBlock createWidgetBlock(OnlineShareWidget provider) { + return new OnlineWidgetBlock(provider, this); + } + + protected int getPaneHeight(int count) { + return (count + 1) / 2 * (ShareComponentConstants.SHARE_BLOCK_HEIGHT + V_GAP); + } + + public void setWidgetPaneScrollEnable(boolean enable) { + if (scrollPane != null) { + scrollPane.setWheelScrollingEnabled(enable); + } + } + + protected Container getParentContainer() { + return this.getParent(); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetShowPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetShowPane.java new file mode 100644 index 000000000..2325fb130 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetShowPane.java @@ -0,0 +1,144 @@ +package com.fr.design.mainframe.share.ui.online; + +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.mainframe.share.collect.ComponentCollector; +import com.fr.design.mainframe.share.ui.base.FlexSearchFieldPane; +import com.fr.design.mainframe.share.ui.widgetfilter.FilterPane; +import com.fr.form.share.bean.OnlineShareWidget; +import com.fr.stable.StringUtils; + +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import javax.swing.text.BadLocationException; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + + +/** + * Created by kerry on 2020-10-19 + */ +public class OnlineWidgetShowPane extends AbstractOnlineWidgetShowPane { + private String lastSearch = StringUtils.EMPTY; + private String lastFilter = StringUtils.EMPTY; + private int lastSortTabSelectedIndex = 0; + + public OnlineWidgetShowPane(OnlineShareWidget[] sharableWidgetProviders) { + super(sharableWidgetProviders); + } + + @Override + public void initSearchTextFieldPaneListener(FlexSearchFieldPane searchFieldPane) { + super.initSearchTextFieldPaneListener(searchFieldPane); + + searchFieldPane.registerSearchTextFieldFocusListener(new FocusAdapter() { + private KeyListener keyListener = new KeyAdapter() { + @Override + public void keyPressed(KeyEvent e) { + if (e.getKeyCode() == KeyEvent.VK_DELETE) { + collectSearchText(false); + } + } + }; + public void focusGained(FocusEvent e) { + searchFieldPane.addKeyListener(keyListener); + } + @Override + public void focusLost(FocusEvent e) { + searchFieldPane.removeKeyListener(keyListener); + collectSearchText(true); + + } + }); + + searchFieldPane.registerDeleteIconMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + collectSearchText(false); + } + }); + + searchFieldPane.registerFieldDocumentListener(new DocumentListener() { + @Override + public void insertUpdate(DocumentEvent e) { + try { + lastSearch = e.getDocument().getText(0, e.getDocument().getLength()); + } catch (BadLocationException ex) { + ex.printStackTrace(); + } + } + @Override + public void removeUpdate(DocumentEvent e) { + textChanged(e); + } + + @Override + public void changedUpdate(DocumentEvent e) { + textChanged(e); + } + + public void textChanged(DocumentEvent e) {}; + }); + } + + @Override + public void initFilterPaneListener(FilterPane filterPane) { + super.initFilterPaneListener(filterPane); + filterPane.registerChangeListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + lastFilter = e.getSource().toString(); + } + }); + filterPane.addPopupStateChangeListener(new FilterPane.PopStateChangeListener() { + @Override + public void stateChange(boolean state) { + if (!state) { + collectFilterContent(); + } + } + }); + } + + @Override + public void initSortTabPane(SortTabPane sortTabPane) { + super.initSortTabPane(sortTabPane); + lastSortTabSelectedIndex = sortTabPane.getIndex(); + sortTabPane.registerSortTabMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + if (sortTabPane.getIndex() != lastSortTabSelectedIndex) { + collectSortType(((UILabel) e.getSource()).getText()); + lastSortTabSelectedIndex = sortTabPane.getIndex(); + } + } + }); + } + + private void collectSearchText(boolean isSaveInfo) { + if (StringUtils.isNotEmpty(lastSearch)) { + ComponentCollector.getInstance().collectSearchContent(this.lastSearch); + if (isSaveInfo) { + ComponentCollector.getInstance().saveInfo(); + } + lastSearch = StringUtils.EMPTY; + } + } + + private void collectFilterContent() { + if (StringUtils.isNotEmpty(lastFilter)) { + ComponentCollector.getInstance().collectFilterContent(lastFilter); + lastSearch = StringUtils.EMPTY; + } + } + + private void collectSortType(String sortType) { + ComponentCollector.getInstance().collectSortType(sortType); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetTabPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetTabPane.java new file mode 100644 index 000000000..96837fd3c --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetTabPane.java @@ -0,0 +1,58 @@ +package com.fr.design.mainframe.share.ui.online; + +import com.fr.design.gui.ibutton.UITabGroup; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.share.collect.ComponentCollector; +import com.fr.design.mainframe.share.ui.online.widgetpackage.OnlineWidgetPackagesShowPane; +import com.fr.form.share.bean.OnlineShareWidget; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import java.awt.BorderLayout; +import java.awt.CardLayout; + +/** + * Created by kerry on 2020-10-19 + */ +public class OnlineWidgetTabPane extends JPanel { + private static final String COMPONENT = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Share"); + private static final String COMPONENT_PACKAGE = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Share_Package"); + private CardLayout cardLayout; + private JPanel centerPane; + private boolean packagePaneCreated = false; + + public OnlineWidgetTabPane(OnlineShareWidget[] sharableWidgets, OnlineShareWidget[] sharableWidgetPackage) { + initPane(sharableWidgets, sharableWidgetPackage); + } + + private void initPane(OnlineShareWidget[] sharableWidgets, OnlineShareWidget[] sharableWidgetPackages) { + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + this.cardLayout = new CardLayout(); + this.centerPane = new JPanel(cardLayout); + this.centerPane.add(new OnlineWidgetShowPane(sharableWidgets), COMPONENT); + //延迟组件包面板的初始化,防止组件面板里组件的缩略图和组件包面板里组件的缩略图一起加载 + UITabGroup headGroup = new UITabGroup(new String[]{COMPONENT, COMPONENT_PACKAGE}) { + public void tabChanged(int newSelectedIndex) { + OnlineWidgetRepoPane.getInstance().setShowPackagePanel(newSelectedIndex != 0); + if (newSelectedIndex == 0) { + cardLayout.show(centerPane, COMPONENT); + } else { + ComponentCollector.getInstance().collectCmpPktClick(); + //延迟组件包面板的初始化,防止组件面板里组件和缩略图和组件包面板里组件的缩略图一起加载 + if (!packagePaneCreated) { + centerPane.add(new OnlineWidgetPackagesShowPane(sharableWidgetPackages), COMPONENT_PACKAGE); + packagePaneCreated = true; + } + cardLayout.show(centerPane, COMPONENT_PACKAGE); + } + } + }; + headGroup.setSelectedIndex(0); + this.centerPane.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0)); + JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + jPanel.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 10)); + jPanel.add(headGroup, BorderLayout.CENTER); + this.add(jPanel, BorderLayout.NORTH); + this.add(centerPane, BorderLayout.CENTER); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/ResourceLoader.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/ResourceLoader.java new file mode 100644 index 000000000..a57a64588 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/ResourceLoader.java @@ -0,0 +1,13 @@ +package com.fr.design.mainframe.share.ui.online; + +/** + * Created by kerry on 2020-12-10 + * todo 后面看看能不能和DataLoad合并起来 + */ +public interface ResourceLoader { + /** + * 加载资源文件 + */ + void load(); + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/widgetpackage/OnlineWidgetPackageSelectPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/widgetpackage/OnlineWidgetPackageSelectPane.java new file mode 100644 index 000000000..2271f0c89 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/widgetpackage/OnlineWidgetPackageSelectPane.java @@ -0,0 +1,40 @@ +package com.fr.design.mainframe.share.ui.online.widgetpackage; + +import com.fr.design.mainframe.share.ui.block.OnlineWidgetPackageBlock; +import com.fr.design.mainframe.share.ui.block.PreviewWidgetBlock; +import com.fr.design.mainframe.share.ui.online.OnlineWidgetSelectPane; +import com.fr.form.share.base.DataLoad; +import com.fr.form.share.bean.OnlineShareWidget; +import com.fr.form.share.constants.ShareComponentConstants; + +/** + * Created by kerry on 2020-10-21 + */ +public class OnlineWidgetPackageSelectPane extends OnlineWidgetSelectPane { + private final OnlineWidgetPackagesShowPane parentPane; + + public OnlineWidgetPackageSelectPane(OnlineShareWidget[] providers, int widgetsPerNum, OnlineWidgetPackagesShowPane parentPane) { + super(providers, widgetsPerNum); + this.parentPane = parentPane; + + } + + public OnlineWidgetPackageSelectPane(DataLoad dataLoad, int widgetsPerNum, OnlineWidgetPackagesShowPane parentPane) { + super(dataLoad, widgetsPerNum); + this.parentPane = parentPane; + + } + + public void showWidgetDetailPane(String id) { + this.parentPane.showWidgetDetailPane(id); + } + + protected PreviewWidgetBlock createWidgetBlock(OnlineShareWidget provider) { + return new OnlineWidgetPackageBlock(provider, this); + } + + protected int getPaneHeight(int count) { + return count * (ShareComponentConstants.SHARE_PACKAGE_BLOCK_HEIGHT + V_GAP); + } + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/widgetpackage/OnlineWidgetPackagesShowPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/widgetpackage/OnlineWidgetPackagesShowPane.java new file mode 100644 index 000000000..d9697495b --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/widgetpackage/OnlineWidgetPackagesShowPane.java @@ -0,0 +1,183 @@ +package com.fr.design.mainframe.share.ui.online.widgetpackage; + + +import com.fr.design.dialog.FineJOptionPane; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.share.ui.base.MouseClickListener; +import com.fr.design.mainframe.share.ui.online.AbstractOnlineWidgetShowPane; +import com.fr.design.mainframe.share.ui.online.OnlineDownloadPackagePane; +import com.fr.design.mainframe.share.ui.online.OnlineWidgetSelectPane; +import com.fr.design.mainframe.share.ui.widgetfilter.FilterPane; +import com.fr.form.share.base.DataLoad; +import com.fr.form.share.bean.OnlineShareWidget; +import com.fr.form.share.utils.ShareUtils; +import com.fr.stable.StringUtils; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import java.awt.BorderLayout; +import java.awt.CardLayout; +import java.awt.Color; +import java.awt.Cursor; +import java.awt.event.MouseEvent; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Created by kerry on 2020-10-19 + */ +public class OnlineWidgetPackagesShowPane extends AbstractOnlineWidgetShowPane { + private static final Color TEXT_COLOR = Color.decode("#419BF9"); + private static final String WIDGETS_INFO = "WIDGETS_INFO"; + private static final String WIDGET_DETAIL = "WIDGET_DETAIL"; + + private CardLayout cardLayout; + private JPanel centerPane; + private JPanel detailPane; + private String currentPackageId; + private OnlineWidgetSelectPane onlineWidgetSelectPane; + private UILabel downloadLabel; + private final Map cachePanelMap = new HashMap<>(); + + public OnlineWidgetPackagesShowPane(OnlineShareWidget[] sharableWidgetProviders) { + super(sharableWidgetProviders); + } + + protected JPanel initContentPane() { + JPanel firstPane = super.initContentPane(); + cardLayout = new CardLayout(); + centerPane = new JPanel(cardLayout); + centerPane.add(firstPane, WIDGETS_INFO); + + JPanel secondPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + UILabel backLabel = createLabel(Toolkit.i18nText("Fine-Design_Report_AlphaFine_Back"), new MouseClickListener() { + @Override + public void mouseClicked(MouseEvent e) { + cardLayout.show(centerPane, WIDGETS_INFO); + } + }); + downloadLabel = createLabel(Toolkit.i18nText("Fine-Design_Share_Download_All_Component"), new MouseClickListener() { + @Override + public void mouseClicked(MouseEvent e) { + String message = Toolkit.i18nText("Fine-Design_Share_Download_All_Component_Message") + + "\n" + + Toolkit.i18nText("Fine-Design_Share_Total") + + onlineWidgetSelectPane.getSharableWidgetNum() + + Toolkit.i18nText("Fine-Design_Share_Piece"); + int returnValue = FineJOptionPane.showConfirmDialog(DesignerContext.getDesignerFrame(), message, Toolkit.i18nText("Fine-Design_Basic_Confirm"), FineJOptionPane.YES_NO_OPTION); + if (returnValue == FineJOptionPane.OK_OPTION && onlineWidgetSelectPane.getSharableWidgetNum() != 0) { + downLoadPackage(); + } + } + }); + + JPanel downloadPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + downloadPane.setBorder(BorderFactory.createEmptyBorder(0, 130, 0, 0)); + downloadPane.add(downloadLabel, BorderLayout.CENTER); + + JPanel labelPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + labelPane.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 10)); + labelPane.add(backLabel, BorderLayout.WEST); + labelPane.add(downloadPane, BorderLayout.CENTER); + + secondPane.add(labelPane, BorderLayout.NORTH); + detailPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + detailPane.add(new OnlineWidgetSelectPane(new OnlineShareWidget[]{}, 50), BorderLayout.CENTER); + secondPane.add(detailPane, BorderLayout.CENTER); + centerPane.add(secondPane, WIDGET_DETAIL); + cardLayout.show(centerPane, WIDGETS_INFO); + return centerPane; + } + + private void downLoadPackage() { + downloadLabel.setVisible(false); + detailPane.removeAll(); + OnlineDownloadPackagePane widgetSelectPane = new OnlineDownloadPackagePane(this, onlineWidgetSelectPane.getSharableWidgetProviders(), 50); + detailPane.add(widgetSelectPane, BorderLayout.CENTER); + cardLayout.show(centerPane, WIDGET_DETAIL); + + cachePanelMap.put(currentPackageId, widgetSelectPane); + + for (OnlineShareWidget onlineShareWidget : getSharableWidgetProviders()) { + if (StringUtils.equals(onlineShareWidget.getId(), currentPackageId)) { + widgetSelectPane.downloadWidget(onlineShareWidget); + break; + } + } + } + + private UILabel createLabel(String i18nText, MouseClickListener clickListener) { + UILabel label = new UILabel(i18nText); + label.setForeground(TEXT_COLOR); + label.addMouseListener(clickListener); + label.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + return label; + } + + protected void initNorthPane(JPanel jPanel, JPanel northPane) { + //暂时隐藏,以后会展示出来 + } + + + protected OnlineWidgetSelectPane createOnlineWidgetSelectPane(OnlineShareWidget[] sharableWidgetProviders) { + return new OnlineWidgetPackageSelectPane(filterPackageWidget(sharableWidgetProviders), 10, this); + } + + protected OnlineWidgetSelectPane createOnlineWidgetSelectPane(DataLoad dataLoad) { + return new OnlineWidgetPackageSelectPane(dataLoad, 10, this); + } + + private OnlineShareWidget[] filterPackageWidget(OnlineShareWidget[] sharableWidgetProviders) { + List onlineShareWidgets = new ArrayList<>(); + for (OnlineShareWidget widget : sharableWidgetProviders) { + if (widget.isWidgetPackage()) { + onlineShareWidgets.add(widget); + } + } + return onlineShareWidgets.toArray(new OnlineShareWidget[onlineShareWidgets.size()]); + } + + public void showWidgetDetailPane(final String id) { + currentPackageId = id; + boolean containsCache = cachePanelMap.containsKey(id); + onlineWidgetSelectPane = containsCache ? cachePanelMap.get(id) : new OnlineWidgetSelectPane(() -> ShareUtils.getPackageWidgets(id), 50); + downloadLabel.setVisible(!containsCache); + showWidgetDetailPane(onlineWidgetSelectPane); + } + + + public void resetWidgetDetailPane(String id, final OnlineShareWidget[] onlineShareWidgets) { + if (StringUtils.equals(id, currentPackageId)) { + showWidgetDetailPane(new OnlineWidgetSelectPane(onlineShareWidgets, 50)); + setDownloadLabelVisible(true); + } + removeCachePane(id); + } + + private void showWidgetDetailPane(OnlineWidgetSelectPane onlineWidgetSelectPane) { + detailPane.removeAll(); + detailPane.add(onlineWidgetSelectPane, BorderLayout.CENTER); + cardLayout.show(centerPane, WIDGET_DETAIL); + } + + public void setDownloadLabelVisible(boolean visible) { + downloadLabel.setVisible(visible); + } + + public String getCurrentPackageId() { + return currentPackageId; + } + + public void removeCachePane(String packageId) { + cachePanelMap.remove(packageId); + } + + protected FilterPane createFilterPane() { + return FilterPane.createOnlinePackageFilterPane(); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/widgetfilter/FilterPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/widgetfilter/FilterPane.java new file mode 100644 index 000000000..4e8f9ffc5 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/widgetfilter/FilterPane.java @@ -0,0 +1,237 @@ +package com.fr.design.mainframe.share.ui.widgetfilter; + +import com.fr.base.BaseUtils; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.share.ui.base.MouseClickListener; +import com.fr.form.share.bean.WidgetFilterTypeInfo; +import com.fr.form.share.utils.ShareUtils; +import com.fr.general.ComparatorUtils; +import com.fr.invoke.Reflect; + +import javax.swing.BorderFactory; +import javax.swing.Icon; +import javax.swing.JPanel; +import javax.swing.Popup; +import javax.swing.PopupFactory; +import javax.swing.SwingConstants; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import java.awt.AWTEvent; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Cursor; +import java.awt.Dimension; +import java.awt.Point; +import java.awt.event.AWTEventListener; +import java.awt.event.MouseEvent; +import java.util.ArrayList; +import java.util.EventListener; +import java.util.List; + +/** + * Created by kerry on 2020-10-21 + */ +public class FilterPane extends JPanel { + public static final String SOURCE_FILTER_KEY = "2@source"; + public static final String CHART_FILTER_KEY = "3@chart"; + public static final String REPORT_FILTER_KEY = "4@report"; + + private static final Icon FILTER_COMBO = BaseUtils.readIcon("/com/fr/base/images/share/filter_combo.png"); + private static final Icon FILTER_COMBO_UP = BaseUtils.readIcon("/com/fr/base/images/share/filter_combo_up.png"); + private final UILabel filterLabel; + private UILabel arrowButton; + private Popup popup; + private boolean showPopup = false; + private FilterPopupPane filterPopupPane; + private List changeListenerList = new ArrayList<>(); + private final AWTEventListener awtEventListener; + List listenerList = new ArrayList<>(); + + private FilterPane() { + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + final JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + jPanel.setBorder(BorderFactory.createLineBorder(Color.decode("#D9DADD"))); + this.add(jPanel, BorderLayout.CENTER); + jPanel.setBackground(Color.WHITE); + this.filterLabel = new UILabel(Toolkit.i18nText("Fine-Design_Share_Online_No_Filter"), SwingConstants.LEFT); + filterLabel.setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 0)); + filterLabel.setPreferredSize(new Dimension(80, 20)); + filterLabel.setForeground(Color.decode("#8F8F92")); + filterLabel.addMouseListener(new MouseClickListener() { + @Override + public void mouseClicked(MouseEvent e) { + super.mouseClicked(e); + if (filterPopupPane != null) { + if (filterPopupPane.hasFilter()) { + filterPopupPane.reset(); + } else { + controlFilterPopUp(); + } + } + + } + }); + jPanel.addMouseListener( + new MouseClickListener() { + @Override + public void mouseClicked(MouseEvent e) { + super.mouseClicked(e); + controlFilterPopUp(); + } + } + ); + JPanel subPane = FRGUIPaneFactory.createLeftFlowZeroGapBorderPane(); + subPane.add(filterLabel); + subPane.setBackground(Color.WHITE); + jPanel.add(subPane, BorderLayout.CENTER); + arrowButton = new UILabel(FILTER_COMBO); + awtEventListener = event -> { + if (event instanceof MouseEvent) { + MouseEvent mv = (MouseEvent) event; + if (isCanHide(mv, jPanel)) { + hideFilterPopUp(); + } + } + + }; + jPanel.add(arrowButton, BorderLayout.EAST); + } + + public static FilterPane createLocalFilterPane() { + FilterPane pane = new FilterPane(); + pane.filterPopupPane = new LocalFilterPopupPane(pane, LocalWidgetFilterCategory.getLocalCategory()); + return pane; + } + + public static FilterPane createOnlineFilterPane() { + FilterPane pane = new FilterPane(); + pane.filterPopupPane = new OnlineFilterPopupPane(pane, pane.loadFilterCategories()); + return pane; + } + + public static FilterPane createOnlinePackageFilterPane() { + FilterPane pane = new FilterPane() { + @Override + protected List loadFilterCategories() { + List filterTypeInfos = super.loadFilterCategories(); + filterTypeInfos.removeIf(info -> ComparatorUtils.equals(FilterPane.CHART_FILTER_KEY, info.getKey()) + || ComparatorUtils.equals(FilterPane.REPORT_FILTER_KEY, info.getKey())); + return filterTypeInfos; + } + }; + pane.filterPopupPane = new LocalFilterPopupPane(pane, pane.loadFilterCategories()); + return pane; + } + + public void changeFilterButtonStatus(boolean hasFilter) { + if (hasFilter) { + switchToClearFilter(); + } else { + switchToNoFilter(); + } + } + + public boolean isShowPopup() { + return showPopup; + } + + private void controlFilterPopUp() { + if (!showPopup) { + showFilterPopUp(); + } else { + hideFilterPopUp(); + } + } + + private synchronized void showFilterPopUp() { + PopupFactory pf = PopupFactory.getSharedInstance(); + Point p = FilterPane.this.getLocationOnScreen(); + popup = pf.getPopup(FilterPane.this, filterPopupPane, p.x, p.y + FilterPane.this.getHeight()); + popup.show(); + filterPopupPane.setPreferredSize(new Dimension(228, filterPopupPane.getHeight())); + showPopup = true; + arrowButton.setIcon(FILTER_COMBO_UP); + firePopupStateChange(true); + java.awt.Toolkit.getDefaultToolkit().addAWTEventListener(awtEventListener, AWTEvent.MOUSE_EVENT_MASK); + } + + private void hideFilterPopUp() { + popup.hide(); + showPopup = false; + arrowButton.setIcon(FILTER_COMBO); + firePopupStateChange(false); + java.awt.Toolkit.getDefaultToolkit().removeAWTEventListener(awtEventListener); + } + + protected List loadFilterCategories() { + return ShareUtils.getWidgetFilterTypeInfos(); + } + + private boolean isCanHide(MouseEvent mv, JPanel jPanel) { + if (mv.getClickCount() < 1) { + return false; + } + // 表示Popup弹窗是否能被点击到 + boolean clickFlag = false; + if (popup != null && showPopup) { + Component component = Reflect.on(popup).call("getComponent").get(); + Point p = component.getLocationOnScreen(); + Point clickPoint = mv.getLocationOnScreen(); + clickFlag = clickPoint.getX() >= p.getX() + && clickPoint.getY() >= p.getY() + && clickPoint.getX() <= component.getWidth() + p.getX() + && clickPoint.getY() <= p.getY() + component.getHeight(); + + } + return popup != null && showPopup + && !clickFlag && !ComparatorUtils.equals(mv.getSource(), jPanel) + && !ComparatorUtils.equals(mv.getSource(), filterLabel); + } + + public void registerChangeListener(ChangeListener changeListener) { + changeListenerList.add(changeListener); + } + + public void fireChangeListener(ChangeEvent e) { + for (ChangeListener changeListener : changeListenerList) { + changeListener.stateChanged(e); + } + } + + public void reset() { + if (filterPopupPane != null && filterPopupPane.hasFilter()) { + filterPopupPane.reset(); + } + switchToNoFilter(); + } + + private void switchToNoFilter() { + filterLabel.setText(Toolkit.i18nText("Fine-Design_Share_Online_No_Filter")); + filterLabel.setForeground(Color.decode("#8F8F92")); + filterLabel.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + } + + private void switchToClearFilter() { + filterLabel.setText(Toolkit.i18nText("Fine-Design_Share_Online_Clear_Filter")); + filterLabel.setForeground(Color.decode("#419BF9")); + filterLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + } + + public void firePopupStateChange(boolean PopupState) { + for (PopStateChangeListener listener : listenerList) { + listener.stateChange(PopupState); + } + } + + public void addPopupStateChangeListener(PopStateChangeListener listener) { + listenerList.add(listener); + } + + public interface PopStateChangeListener extends EventListener { + void stateChange(boolean state); + } + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/widgetfilter/FilterPopupPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/widgetfilter/FilterPopupPane.java new file mode 100644 index 000000000..e2bcd5344 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/widgetfilter/FilterPopupPane.java @@ -0,0 +1,201 @@ +package com.fr.design.mainframe.share.ui.widgetfilter; + +import com.fr.design.gui.icheckbox.UICheckBox; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.layout.VerticalFlowLayout; +import com.fr.form.share.bean.WidgetFilterInfo; +import com.fr.form.share.bean.WidgetFilterTypeInfo; +import com.fr.general.ComparatorUtils; +import com.fr.stable.StringUtils; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.event.ChangeEvent; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Font; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.util.ArrayList; +import java.util.List; + +/** + * @Author: Yuan.Wang + * @Date: 2020/11/11 + */ +public abstract class FilterPopupPane extends JPanel { + private static final Color BORDER_COLOR = Color.decode("#D9DADD"); + private static final String FILTER_ALL_ID = "0"; + + FilterPane filterPane; + private List filterList = new ArrayList<>(); + private final List checkBoxList = new ArrayList<>(); + private boolean reset = false; + + + public FilterPopupPane(FilterPane filterPane, List widgetFilterCategories) { + this.filterPane = filterPane; + initPane(widgetFilterCategories); + } + + private void initPane(List widgetFilterCategories) { + this.setBackground(Color.WHITE); + this.setBorder(BorderFactory.createLineBorder(BORDER_COLOR)); + this.setForeground(Color.decode("#FFFFFF")); + this.setLayout(new BorderLayout()); + this.add(createVerticalFlowPane(widgetFilterCategories), BorderLayout.CENTER); + } + + public boolean hasFilter() { + return filterList.size() > 0; + } + + protected List getFilterList() { + return filterList; + } + + private JPanel createVerticalFlowPane(List widgetFilterCategories) { + + List topWidgetTypeFilter = new ArrayList<>(); + List widgetTypeFilter = new ArrayList<>(); + List otherWidgetTypeFilter = new ArrayList<>(); + + for (WidgetFilterTypeInfo info : widgetFilterCategories) { + if (ComparatorUtils.equals(FilterPane.CHART_FILTER_KEY, info.getKey()) + || ComparatorUtils.equals(FilterPane.REPORT_FILTER_KEY, info.getKey())) { + widgetTypeFilter.add(info); + } else if (ComparatorUtils.equals(FilterPane.SOURCE_FILTER_KEY, info.getKey())) { + topWidgetTypeFilter.add(info); + } else { + otherWidgetTypeFilter.add(info); + } + } + + JPanel verticalFlowPane = new JPanel(); + verticalFlowPane.setBackground(Color.WHITE); + VerticalFlowLayout layout = new VerticalFlowLayout(FlowLayout.LEADING, 0, 10); + layout.setAlignLeft(true); + verticalFlowPane.setLayout(layout); + + verticalFlowPane.setBackground(Color.WHITE); + verticalFlowPane.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5)); + + for (WidgetFilterTypeInfo info : topWidgetTypeFilter) { + verticalFlowPane.add(createOtherCategoryPane(info)); + } + if (widgetTypeFilter.size() > 0) { + verticalFlowPane.add(createWidgetTypeFilterPane(widgetTypeFilter)); + } + for (WidgetFilterTypeInfo info : otherWidgetTypeFilter) { + verticalFlowPane.add(createOtherCategoryPane(info)); + } + return verticalFlowPane; + } + + private JPanel createWidgetTypeFilterPane(List widgetTypeFilter) { + JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + jPanel.setBackground(Color.WHITE); + UILabel titleLabel = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Type")); + titleLabel.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5)); + titleLabel.setPreferredSize(new Dimension(226, 20)); + titleLabel.setOpaque(true); + titleLabel.setBackground(Color.decode("#EDEDEE")); + jPanel.add(titleLabel, BorderLayout.NORTH); + + JPanel contentPane = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, FlowLayout.LEADING, 0, 10); + contentPane.setBackground(Color.WHITE); + for (WidgetFilterTypeInfo info : widgetTypeFilter) { + contentPane.add(createTypeFilterPane(info)); + } + jPanel.add(contentPane, BorderLayout.CENTER); + return jPanel; + } + + private JPanel createTypeFilterPane(WidgetFilterTypeInfo widgetFilterTypeInfo) { + JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + jPanel.setBackground(Color.WHITE); + UILabel titleLabel = new UILabel(widgetFilterTypeInfo.getTitle() + ":"); + titleLabel.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5)); + titleLabel.setFont(new Font(titleLabel.getFont().getName(), Font.BOLD, titleLabel.getFont().getSize())); + jPanel.add(titleLabel, BorderLayout.NORTH); + jPanel.add(createCategoryDetailPane(widgetFilterTypeInfo), BorderLayout.CENTER); + return jPanel; + } + + private JPanel createOtherCategoryPane(WidgetFilterTypeInfo filterTypeInfo) { + JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + jPanel.setBackground(Color.WHITE); + UILabel titleLabel = new UILabel(filterTypeInfo.getTitle()); + titleLabel.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5)); + titleLabel.setPreferredSize(new Dimension(226, 20)); + titleLabel.setOpaque(true); + titleLabel.setBackground(Color.decode("#EDEDEE")); + jPanel.add(titleLabel, BorderLayout.NORTH); + jPanel.add(createCategoryDetailPane(filterTypeInfo), BorderLayout.CENTER); + return jPanel; + } + + private JPanel createCategoryDetailPane(WidgetFilterTypeInfo filterTypeInfo) { + JPanel contentPane = FRGUIPaneFactory.createNColumnGridInnerContainer_S_Pane(2); + contentPane.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0)); + contentPane.setBackground(Color.WHITE); + int displayCount = 0; + for (final WidgetFilterInfo filterInfo : filterTypeInfo.getFilterItems()) { + if (!ComparatorUtils.equals(FILTER_ALL_ID, filterInfo.getId())) { + displayCount++; + } + } + int contentPaneHeight = ((displayCount + 1) / 2) * 27; + contentPane.setPreferredSize(new Dimension(228, contentPaneHeight)); + for (final WidgetFilterInfo filterInfo : filterTypeInfo.getFilterItems()) { + if (ComparatorUtils.equals(FILTER_ALL_ID, filterInfo.getId())) { + continue; + } + final UICheckBox checkBox = new UICheckBox(filterInfo.getName()); + checkBox.setBackground(Color.WHITE); + + checkBox.addItemListener(new ItemListener() { + @Override + public void itemStateChanged(ItemEvent e) { + if (reset) { + return; + } + if (checkBox.isSelected()) { + filterList.add(filterInfo); + } else if (filterList.contains(filterInfo)) { + filterList.remove(filterInfo); + } + checkFilterButtonStatus(); + filterPane.fireChangeListener(new ChangeEvent(assembleFilter())); + } + }); + + + checkBoxList.add(checkBox); + contentPane.add(checkBox); + } + return contentPane; + } + + protected abstract String assembleFilter(); + + private void checkFilterButtonStatus() { + filterPane.changeFilterButtonStatus(hasFilter()); + } + + public void reset() { + reset = true; + for (UICheckBox checkBox : checkBoxList) { + checkBox.setSelected(false); + } + filterList.clear(); + checkFilterButtonStatus(); + filterPane.fireChangeListener(new ChangeEvent(StringUtils.EMPTY)); + reset = false; + } + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/widgetfilter/LocalFilterPopupPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/widgetfilter/LocalFilterPopupPane.java new file mode 100644 index 000000000..5a589d32c --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/widgetfilter/LocalFilterPopupPane.java @@ -0,0 +1,23 @@ +package com.fr.design.mainframe.share.ui.widgetfilter; + +import com.fr.form.share.bean.WidgetFilterTypeInfo; +import com.fr.stable.StringUtils; + +import java.util.ArrayList; +import java.util.List; + +/** + * @Author: Yuan.Wang + * @Date: 2020/11/11 + */ +public class LocalFilterPopupPane extends FilterPopupPane { + public LocalFilterPopupPane(FilterPane pane, List loadFilterCategories) { + super(pane, loadFilterCategories); + } + + @Override + protected String assembleFilter() { + LocalWidgetFilter.getInstance().setFilterList(getFilterList() == null ? new ArrayList<>() : getFilterList()); + return StringUtils.EMPTY; + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/widgetfilter/LocalWidgetFilter.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/widgetfilter/LocalWidgetFilter.java new file mode 100644 index 000000000..259e6fcc9 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/widgetfilter/LocalWidgetFilter.java @@ -0,0 +1,139 @@ +package com.fr.design.mainframe.share.ui.widgetfilter; + +import com.fr.design.i18n.Toolkit; +import com.fr.form.share.DefaultSharableWidget; +import com.fr.form.share.SharableWidgetProvider; +import com.fr.form.share.bean.WidgetFilterInfo; +import com.fr.design.mainframe.share.constants.DisplayDevice; +import com.fr.stable.ArrayUtils; +import com.fr.stable.StringUtils; + +import java.util.ArrayList; +import java.util.List; + +/** + * @Author: Yuan.Wang + * @Date: 2020/11/11 + */ +public class LocalWidgetFilter { + private List filterList; + + private LocalWidgetFilter() { + filterList = new ArrayList<>(); + } + + private static class Holder { + private static final LocalWidgetFilter HOLDER = new LocalWidgetFilter(); + } + + public static LocalWidgetFilter getInstance() { + return Holder.HOLDER; + } + + public void setFilterList(List filterList) { + this.filterList = filterList; + } + + public boolean shouldShow(SharableWidgetProvider provider) { + if (filterList == null || filterList.size() == 0) { + return true; + } + if (provider instanceof DefaultSharableWidget) { + DefaultSharableWidget bindInfo = (DefaultSharableWidget) provider; + //类型,即图表类型或报表类型 + boolean sameType = true; + //展示终端,即PC端、移动端 + boolean sameDisplayDevice = true; + //价格,即免费或者付费 + boolean sameSource = true; + + //如果有筛选条件,先初始化为false + for (WidgetFilterInfo filterInfo : filterList) { + if (StringUtils.equals(filterInfo.getType(), "chart") | StringUtils.equals(filterInfo.getType(), "report")) { + sameType = false; + } + if (StringUtils.equals(filterInfo.getType(), "displayDevice")) { + sameDisplayDevice = false; + } + if (StringUtils.equals(filterInfo.getType(), "source")) { + sameSource = false; + } + } + //符合条件,设置为true + for (WidgetFilterInfo filterInfo : filterList) { + //类型 + sameType |= filterType(filterInfo, bindInfo); + //展示终端 + sameDisplayDevice |= filterDisplayDevice(filterInfo, bindInfo); + //来源 + sameSource |= filterSource(filterInfo, bindInfo); + } + return sameDisplayDevice & sameSource & sameType; + } + return false; + } + + public SharableWidgetProvider[] filter(SharableWidgetProvider[] elCaseBindInfoList) { + SharableWidgetProvider[] result = elCaseBindInfoList; + for (SharableWidgetProvider provider : result) { + if (!LocalWidgetFilter.getInstance().shouldShow(provider)) { + result = ArrayUtils.removeElement(result, provider); + } + } + return result; + } + + public boolean hasFilter() { + return filterList != null && filterList.size() != 0; + } + + private boolean filterType(WidgetFilterInfo filterInfo, DefaultSharableWidget bindInfo) { + //图表报表类型 + if (StringUtils.equals(filterInfo.getType(), "chart") | StringUtils.equals(filterInfo.getType(), "report")) { + //图表、报表类型改名之后的兼容 + if (sameType(filterInfo, bindInfo)) { + return true; + } + return StringUtils.equals(bindInfo.getChildClassify(), filterInfo.getName()); + } + return false; + } + + private boolean filterDisplayDevice(WidgetFilterInfo filterInfo, DefaultSharableWidget bindInfo) { + if (StringUtils.equals(filterInfo.getType(), "displayDevice")) { + boolean sameMobile = StringUtils.equals(filterInfo.getName(), "移动端") & DisplayDevice.supportMobile(bindInfo.getDisplayDevice()); + boolean samePC = StringUtils.equals(filterInfo.getName(), "PC端") & DisplayDevice.supportPC(bindInfo.getDisplayDevice()); + //filterInfo的设备信息 = bindInfo的设备信息,为true + return sameMobile | samePC; + } + return false; + } + + private boolean filterSource(WidgetFilterInfo filterInfo, DefaultSharableWidget bindInfo) { + if (StringUtils.equals(filterInfo.getType(), "source")) { + boolean sameMarket = StringUtils.equals(filterInfo.getName(), "商城") && StringUtils.equals(bindInfo.getSource(), DefaultSharableWidget.MARKET); + boolean sameLocal = StringUtils.equals(filterInfo.getName(), "本地") && StringUtils.equals(bindInfo.getSource(), DefaultSharableWidget.LOCAL); + return sameMarket | sameLocal; + } + return false; + } + + private boolean sameType(WidgetFilterInfo filterInfo, DefaultSharableWidget bindInfo) { + //旧:其他 新:其它图表 + boolean other = StringUtils.equals(filterInfo.getName(), Toolkit.i18nText("Fine-Design_Share_Type_Chart_Other")) + && (StringUtils.equals(bindInfo.getChildClassify(), Toolkit.i18nText("Fine-Design_Share_Type_Chart_Other")) + || StringUtils.equals(bindInfo.getChildClassify(), Toolkit.i18nText("Fine-Design_Share_Type_Others"))); + + //旧:移动维度切换 新:多维度切换 + boolean dimensionChange = StringUtils.equals(filterInfo.getName(), Toolkit.i18nText("Fine-Design_Share_Type_Dimension_Change")) + && (StringUtils.equals(bindInfo.getChildClassify(), Toolkit.i18nText("Fine-Design_Share_Type_Mobile_Dimension_Change")) + || StringUtils.equals(bindInfo.getChildClassify(), Toolkit.i18nText("Fine-Design_Share_Type_Dimension_Change"))); + + //旧:移动填报 新:填报 + boolean fill = StringUtils.equals(filterInfo.getName(), Toolkit.i18nText("Fine-Design_Share_Type_Fill")) + && (StringUtils.equals(bindInfo.getChildClassify(), Toolkit.i18nText("Fine-Design_Share_Type_Fill")) + || StringUtils.equals(bindInfo.getChildClassify(), Toolkit.i18nText("Fine-Design_Share_Type_Mobile_Fill"))); + + return other | dimensionChange | fill; + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/widgetfilter/LocalWidgetFilterCategory.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/widgetfilter/LocalWidgetFilterCategory.java new file mode 100644 index 000000000..9e5d4f34e --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/widgetfilter/LocalWidgetFilterCategory.java @@ -0,0 +1,82 @@ +package com.fr.design.mainframe.share.ui.widgetfilter; + +import com.fr.form.share.bean.WidgetFilterInfo; +import com.fr.form.share.bean.WidgetFilterTypeInfo; + +import java.util.ArrayList; +import java.util.List; + +/** + * @Author: Yuan.Wang + * @Date: 2020/11/12 + */ +public class LocalWidgetFilterCategory { + + public static List getLocalCategory() { + List category = new ArrayList<>(); + + WidgetFilterTypeInfo source = new WidgetFilterTypeInfo(); + source.setTitle("来源"); + source.setKey("2@source"); + source.addFilterItem(new WidgetFilterInfo("本地", "1", "source")); + source.addFilterItem(new WidgetFilterInfo("商城", "2", "source")); + source.addFilterItem(new WidgetFilterInfo("全部", "0", "source")); + + WidgetFilterTypeInfo displayDevice = new WidgetFilterTypeInfo(); + displayDevice.setTitle("展示终端"); + displayDevice.setKey("1@displayDevice"); + displayDevice.addFilterItem(new WidgetFilterInfo("PC端", "1", "displayDevice")); + displayDevice.addFilterItem(new WidgetFilterInfo("移动端", "2", "displayDevice")); + displayDevice.addFilterItem(new WidgetFilterInfo("全部", "0", "displayDevice")); + + WidgetFilterTypeInfo fee = new WidgetFilterTypeInfo(); + fee.setTitle("价格"); + fee.setKey("2@fee"); + fee.addFilterItem(new WidgetFilterInfo("付费", "2", "fee")); + fee.addFilterItem(new WidgetFilterInfo("免费", "1", "fee")); + fee.addFilterItem(new WidgetFilterInfo("全部", "0", "fee")); + + WidgetFilterTypeInfo chart = new WidgetFilterTypeInfo(); + chart.setTitle("基础元素"); + chart.setKey("3@chart"); + chart.addFilterItem(new WidgetFilterInfo("柱形图/条形图", "1", "chart")); + chart.addFilterItem(new WidgetFilterInfo("折线图", "3", "chart")); + chart.addFilterItem(new WidgetFilterInfo("组合图", "4", "chart")); + chart.addFilterItem(new WidgetFilterInfo("饼图", "2", "chart")); + chart.addFilterItem(new WidgetFilterInfo("仪表盘", "5", "chart")); + chart.addFilterItem(new WidgetFilterInfo("地图", "6", "chart")); + chart.addFilterItem(new WidgetFilterInfo("其他图表", "7", "chart")); + chart.addFilterItem(new WidgetFilterInfo("明细表", "8", "chart")); + chart.addFilterItem(new WidgetFilterInfo("基础控件", "9", "chart")); + chart.addFilterItem(new WidgetFilterInfo("全部", "0", "chart")); + + WidgetFilterTypeInfo report = new WidgetFilterTypeInfo(); + report.setTitle("综合应用"); + report.setKey("4@report"); + report.addFilterItem(new WidgetFilterInfo("指标卡", "1", "report")); + report.addFilterItem(new WidgetFilterInfo("标题头", "2", "report")); + report.addFilterItem(new WidgetFilterInfo("特殊功能卡", "4", "report")); + report.addFilterItem(new WidgetFilterInfo("多维度切换", "5", "report")); + report.addFilterItem(new WidgetFilterInfo("移动目录导航", "6", "report")); + report.addFilterItem(new WidgetFilterInfo("填报", "8", "report")); + report.addFilterItem(new WidgetFilterInfo("全部", "0", "report")); + + WidgetFilterTypeInfo style = new WidgetFilterTypeInfo(); + style.setTitle("风格"); + style.setKey("5@style"); + style.addFilterItem(new WidgetFilterInfo("简约清新", "1", "style")); + style.addFilterItem(new WidgetFilterInfo("商务稳重", "2", "style")); + style.addFilterItem(new WidgetFilterInfo("活泼绚丽", "3", "style")); + style.addFilterItem(new WidgetFilterInfo("酷炫科技", "4", "style")); + style.addFilterItem(new WidgetFilterInfo("其他风格", "5", "style")); + style.addFilterItem(new WidgetFilterInfo("全部", "0", "style")); + + category.add(displayDevice); + category.add(source); + category.add(chart); + category.add(report); + return category; + + } + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/widgetfilter/OnlineFilterPopupPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/widgetfilter/OnlineFilterPopupPane.java new file mode 100644 index 000000000..2543b4a77 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/widgetfilter/OnlineFilterPopupPane.java @@ -0,0 +1,23 @@ +package com.fr.design.mainframe.share.ui.widgetfilter; + +import com.fr.form.share.bean.WidgetFilterTypeInfo; +import com.fr.form.share.utils.ShareUtils; + +import java.util.List; + +/** + * @Author: Yuan.Wang + * @Date: 2020/11/11 + */ +public class OnlineFilterPopupPane extends FilterPopupPane { + + public OnlineFilterPopupPane(FilterPane filterPane, List widgetFilterCategories) { + super(filterPane, widgetFilterCategories); + } + + protected String assembleFilter() { + return ShareUtils.assembleFilter(getFilterList()); + } + + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/util/DownloadUtils.java b/designer-form/src/main/java/com/fr/design/mainframe/share/util/DownloadUtils.java new file mode 100644 index 000000000..93a8f73b0 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/util/DownloadUtils.java @@ -0,0 +1,143 @@ +package com.fr.design.mainframe.share.util; + +import com.fr.config.MarketConfig; +import com.fr.design.extra.PluginConstants; +import com.fr.form.share.base.CancelCheck; +import com.fr.form.share.constants.ShareComponentConstants; +import com.fr.general.CloudCenter; +import com.fr.log.FineLoggerFactory; +import com.fr.stable.ProductConstants; +import com.fr.stable.StableUtils; +import com.fr.third.org.apache.http.HttpEntity; +import com.fr.third.org.apache.http.HttpException; +import com.fr.third.org.apache.http.HttpStatus; +import com.fr.third.org.apache.http.client.config.CookieSpecs; +import com.fr.third.org.apache.http.client.config.RequestConfig; +import com.fr.third.org.apache.http.client.methods.CloseableHttpResponse; +import com.fr.third.org.apache.http.client.methods.HttpUriRequest; +import com.fr.third.org.apache.http.client.methods.RequestBuilder; +import com.fr.third.org.apache.http.impl.client.BasicCookieStore; +import com.fr.third.org.apache.http.impl.client.CloseableHttpClient; +import com.fr.third.org.apache.http.impl.client.HttpClients; +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.InputStream; + +/** + * created by Harrison on 2020/05/27 + **/ +public class DownloadUtils { + private static final String MARKET_LOGIN_URL = CloudCenter.getInstance().acquireUrlByKind("market.login"); + private static final String REUSES_URL = CloudCenter.getInstance().acquireUrlByKind("af.reuseInfo") + "file/"; + private static final String PACKAGE_REUSES_URL = CloudCenter.getInstance().acquireUrlByKind("af.reuseInfo") + "package/download/"; + + + public static boolean login(CloseableHttpClient client) throws Exception { + + HttpUriRequest login = RequestBuilder.post() + .setUri(MARKET_LOGIN_URL) + .setHeader("User-Agent", "Mozilla/5.0") + .addParameter("username", MarketConfig.getInstance().getBbsUsername()) + .addParameter("password", MarketConfig.getInstance().getBbsPassword()) + .build(); + CloseableHttpResponse loginResponse = client.execute(login); + return loginResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK; + } + + private static CloseableHttpClient createClient() { + + BasicCookieStore cookieStore = new BasicCookieStore(); + return HttpClients.custom() + .setDefaultRequestConfig(RequestConfig.custom() + .setCookieSpec(CookieSpecs.STANDARD).build()) + .setDefaultCookieStore(cookieStore) + .build(); + } + + @NotNull + public static String download(String id, String fileName, com.fr.design.extra.Process process) throws Exception { + CloseableHttpResponse fileRes = getHttpResponse(REUSES_URL, id); + if (fileRes.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { + + String realPath = StableUtils.pathJoin(ProductConstants.getEnvHome(), ShareComponentConstants.PLUGIN_CACHE, ShareComponentConstants.DOWNLOAD_SHARE); + String filePath; + + HttpEntity entity = fileRes.getEntity(); + long totalSize = entity.getContentLength(); + + InputStream content = entity.getContent(); + filePath = StableUtils.pathJoin(realPath, fileName + ".reu"); + StableUtils.makesureFileExist(new File(filePath)); + FileOutputStream writer = new FileOutputStream(filePath); + byte[] data = new byte[PluginConstants.BYTES_NUM]; + int bytesRead; + int totalBytesRead = 0; + + while ((bytesRead = content.read(data)) > 0) { + writer.write(data, 0, bytesRead); + data = new byte[PluginConstants.BYTES_NUM]; + totalBytesRead += bytesRead; + process.process(totalBytesRead / (double) totalSize); + } + content.close(); + writer.flush(); + writer.close(); + FineLoggerFactory.getLogger().info("download widget{} success", id); + return filePath; + } else { + FineLoggerFactory.getLogger().info("download widget{} failed", id); + throw new HttpException(); + } + } + + public static String downloadPackage(String id, String fileName, CancelCheck cancelCheck) throws Exception { + + CloseableHttpResponse fileRes = getHttpResponse(PACKAGE_REUSES_URL, id); + + String realPath = StableUtils.pathJoin(ProductConstants.getEnvHome(), ShareComponentConstants.PLUGIN_CACHE, ShareComponentConstants.DOWNLOAD_PACKAGE_SHARE); + String filePath; + if (fileRes.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { + HttpEntity entity = fileRes.getEntity(); + filePath = StableUtils.pathJoin(realPath, fileName + ".reus"); + StableUtils.makesureFileExist(new File(filePath)); + + InputStream content = entity.getContent(); + FileOutputStream writer = new FileOutputStream(filePath); + + byte[] data = new byte[PluginConstants.BYTES_NUM * 20]; + int bytesRead; + + while (!cancelCheck.isCanceled() && (bytesRead = content.read(data)) > 0) { + writer.write(data, 0, bytesRead); + data = new byte[PluginConstants.BYTES_NUM * 20]; + } + + content.close(); + writer.flush(); + writer.close(); + if (cancelCheck.isCanceled()) { + FineLoggerFactory.getLogger().info("download widget{} canceled", id); + } else { + FineLoggerFactory.getLogger().info("download widget{} failed", id); + } + return filePath; + } else { + FineLoggerFactory.getLogger().info("download widget{} failed", id); + throw new HttpException(); + } + } + + private static CloseableHttpResponse getHttpResponse(String url, String id) throws Exception { + //先登录一下。不然可能失败 + CloseableHttpClient client = createClient(); + FineLoggerFactory.getLogger().info("login fr-market"); + login(client); + FineLoggerFactory.getLogger().info("start download widget {}", id); + HttpUriRequest file = RequestBuilder.get() + .setUri(url + id) + .build(); + return client.execute(file); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/util/InstallComponentHelper.java b/designer-form/src/main/java/com/fr/design/mainframe/share/util/InstallComponentHelper.java new file mode 100644 index 000000000..d2846d93c --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/util/InstallComponentHelper.java @@ -0,0 +1,64 @@ +package com.fr.design.mainframe.share.util; + +import com.fr.design.mainframe.reuse.SnapChatKeys; +import com.fr.design.notification.SnapChat; +import com.fr.design.notification.SnapChatFactory; +import com.fr.form.share.constants.ComponentPath; +import com.fr.form.share.group.filter.DirFilter; +import com.fr.form.share.group.filter.ReuFilter; +import com.fr.io.utils.ResourceIOUtils; +import com.fr.log.FineLoggerFactory; +import com.fr.stable.ArrayUtils; +import com.fr.stable.StableUtils; +import com.fr.workspace.WorkContext; + +import java.io.InputStream; + +/** + * @Author: Yuan.Wang + * @Date: 2020/12/4 + */ +public class InstallComponentHelper { + + private static final String PRE_INSTALL_PATH = "/com/fr/form/share/components"; + private static final String[] PRE_INSTALL_COMPONENTS = new String[]{ + "单行指标卡.f3df58b3-4302-4cab-ab77-caaf225de60a.reu", + "分层雷达图-深色.49f8397c-e6a6-482a-acc7-46d8cec353a4.reu", + "红绿灯表格-浅色.d0466992-328a-4ccf-ad67-6cbc844d669c.reu", + "进度表格-深色.de4141ce-5c25-4506-9424-f5aa15fbf6d0.reu", + "三列指标卡.61a83d18-a162-4dc3-aa57-3b954edaf82e.reu", + "透明按钮切换图表.e373e13a-3da0-4c29-91bc-9ae804241023.reu" + }; + + public static void installPreComponent() { + if (needPreInstallComponent()) { + for (String componentPath : PRE_INSTALL_COMPONENTS) { + try { + InputStream inputStream = InstallComponentHelper.class.getResourceAsStream(StableUtils.pathJoin(PRE_INSTALL_PATH, componentPath)); + byte[] data = ResourceIOUtils.inputStream2Bytes(inputStream); + WorkContext.getWorkResource().write(StableUtils.pathJoin(ComponentPath.SHARE_PATH.path(), componentPath), data); + } catch (Exception e) { + FineLoggerFactory.getLogger().error("install Component filed" + e.getMessage(), e); + } + } + } + + } + + private static boolean needPreInstallComponent() { + //老用户或者组件库里已有组件,不预装组件 + SnapChat snapChat = SnapChatFactory.createSnapChat(false, SnapChatKeys.COMPONENT); + return !snapChat.hasRead() && !hasComponentInstalled(); + } + + /** + * 判断是否已有组件被安装 + */ + private static boolean hasComponentInstalled() { + String sharePath = ComponentPath.SHARE_PATH.path(); + String[] components = WorkContext.getWorkResource().list(sharePath, new ReuFilter()); + String[] dirs = WorkContext.getWorkResource().list(sharePath, new DirFilter()); + return components != null && ArrayUtils.isNotEmpty(components) + || (dirs != null && ArrayUtils.isNotEmpty(dirs)); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/util/InstallUtils.java b/designer-form/src/main/java/com/fr/design/mainframe/share/util/InstallUtils.java new file mode 100644 index 000000000..c25f53f51 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/util/InstallUtils.java @@ -0,0 +1,150 @@ +package com.fr.design.mainframe.share.util; + +import com.fr.form.share.group.DefaultShareGroup; +import com.fr.form.share.group.DefaultShareGroupManager; +import com.fr.form.share.Group; +import com.fr.form.share.group.TempFileOperator; +import com.fr.form.share.utils.ReuxUtils; +import com.fr.form.share.utils.ShareUtils; +import com.fr.io.repository.base.fs.FileSystemRepository; +import com.fr.log.FineLoggerFactory; +import com.fr.stable.ProductConstants; +import com.fr.stable.StableUtils; +import com.fr.stable.project.ProjectConstants; +import org.jetbrains.annotations.Nullable; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +/** + * @Author: Yuan.Wang + * @Date: 2020/12/21 + */ +public class InstallUtils { + + private static final String DOT = "."; + + /** + * 安装组件包 + */ + public static boolean installReusFile(File chosenFile, long installTime, List list) { + return installReusFile(chosenFile, installTime, list, o -> { + //do nothing + }).installStatus; + } + + /** + * 安装组件包 + */ + public static InstallResult installReusFile(File chosenFile, long installTime, List list, com.fr.design.extra.Process process) { + Group group = createComponentGroup(chosenFile.getName()); + if (group == null) { + return new InstallResult(false, null); + } + int totalFileNum; + int installedFileNum = 0; + try (TempFileOperator tempFilOperator = new TempFileOperator(getUnZipCacheDir())) { + File[] files = unZipReuxsFile(chosenFile, tempFilOperator.getTempFilePath()); + totalFileNum = files.length; + boolean installStatus = true; + for (File file : files) { + boolean success = installReuFile(group, file, installTime); + if (!success) { + list.add(getFilePrefix(chosenFile) + ": " + getFilePrefix(file)); + } + installedFileNum++; + process.process(installedFileNum / (double) totalFileNum); + installStatus &= success; + } + return new InstallResult(installStatus, group); + } catch (Exception e) { + process.process(1.0); + FineLoggerFactory.getLogger().error(e.getMessage(), e); + return new InstallResult(false, group); + } + + } + + /** + * 安装组件 + */ + public static boolean installReuFile(File chosenFile, long installTime, List list) { + Group defaultGroup = DefaultShareGroupManager.getInstance().getGroup(DefaultShareGroup.GROUP_NAME); + if (defaultGroup == null) { + return false; + } + boolean success = installReuFile(defaultGroup, chosenFile, installTime); + if (!success) { + list.add(getFilePrefix(chosenFile)); + } + return success; + } + + @Nullable + private static Group createComponentGroup(String fileName) { + String groupName = fileName.substring(0, fileName.indexOf(DOT + ReuxUtils.REUS_SUFFIX)); + + //有重名分组则加后缀 + if (DefaultShareGroupManager.getInstance().getGroup(groupName) != null) { + int suffix = 1; + while (DefaultShareGroupManager.getInstance().getGroup(groupName + suffix) != null) { + suffix++; + } + groupName = groupName + suffix; + } + + if (!DefaultShareGroupManager.getInstance().createGroup(groupName)) { + return null; + } + return DefaultShareGroupManager.getInstance().getGroup(groupName); + } + + private static boolean installReuFile(Group group, File chosenFile, long installTime) { + try { + if (!group.installModule(chosenFile)) { + return false; + } + ShareUtils.recordInstallTime(chosenFile.getName(), installTime); + return true; + } catch (IOException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + return false; + } + } + + private static File[] unZipReuxsFile(File chosenFile, String tempFilePath) throws IOException { + List files = new ArrayList<>(); + ReuxUtils.unzipRueFile(chosenFile, tempFilePath); + String[] components = FileSystemRepository.getSingleton().list(tempFilePath, s -> s.endsWith(ProjectConstants.REU)); + for (String component : components) { + files.add(new File(StableUtils.pathJoin(tempFilePath, component))); + } + return files.toArray(new File[files.size()]); + } + + private static String getUnZipCacheDir() { + return StableUtils.pathJoin(ProductConstants.getEnvHome(), "plugin_cache", "reu_share_temp"); + } + + private static String getFilePrefix(File file) { + String fileName = file.getName(); + return fileName.contains(DOT) ? fileName.substring(0, fileName.indexOf(DOT)) : fileName; + } + + /** + * 安装的返回结果 + */ + public static class InstallResult { + public final boolean installStatus; + public final Group group; + + public InstallResult(boolean installStatus, Group group) { + this.installStatus = installStatus; + this.group = group; + } + } + + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/util/ShareComponentUtils.java b/designer-form/src/main/java/com/fr/design/mainframe/share/util/ShareComponentUtils.java new file mode 100644 index 000000000..abd2c5450 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/util/ShareComponentUtils.java @@ -0,0 +1,93 @@ +package com.fr.design.mainframe.share.util; + +import com.fr.base.io.IOFile; +import com.fr.base.iofile.attr.ExtendSharableAttrMark; +import com.fr.design.designer.creator.XCreator; +import com.fr.design.designer.creator.XCreatorUtils; +import com.fr.design.designer.creator.XLayoutContainer; +import com.fr.design.file.HistoryTemplateListCache; +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.FormSelection; +import com.fr.design.mainframe.JForm; +import com.fr.design.mainframe.JTemplate; +import com.fr.form.share.SharableWidgetProvider; +import com.fr.form.share.bean.ShareLayoutWidget; +import com.fr.form.share.constants.ComponentPath; +import com.fr.form.ui.Widget; +import com.fr.form.ui.container.cardlayout.WCardMainBorderLayout; +import com.fr.stable.StableUtils; +import com.fr.stable.StringUtils; +import com.fr.workspace.WorkContext; +import org.jetbrains.annotations.NotNull; + +import java.awt.Dimension; +import java.awt.Rectangle; + +/** + * Coder: zack + * Date: 2016/9/20 + * Time: 12:00 + */ +public class ShareComponentUtils { + + @NotNull + public static XCreator createXCreator(Widget creatorSource, String shareId, SharableWidgetProvider provider) { + + XCreator xCreator; + if (creatorSource instanceof WCardMainBorderLayout) { + xCreator = XCreatorUtils.createXCreator(creatorSource, new Dimension(500, 300)); + } else if (creatorSource instanceof ShareLayoutWidget) { + xCreator = XCreatorUtils.createXCreator(((ShareLayoutWidget) creatorSource).getWidget(), new Dimension(provider.getWidth(), provider.getHeight())); + } else { + xCreator = XCreatorUtils.createXCreator(creatorSource, new Dimension(provider.getWidth(), provider.getHeight())); + } + xCreator.setBackupBound(new Rectangle(provider.getWidth(), provider.getHeight())); + xCreator.setShareId(shareId); + return xCreator; + } + + /** + * 检查readme.txt文件 + */ + public static void checkReadMe() { + String shareDir = ComponentPath.SHARE_PATH.path(); + String readmePath = StableUtils.pathJoin(shareDir, "readme.txt"); + if (WorkContext.getWorkResource().exist(readmePath)) { + return; + } + String msg = Toolkit.i18nText("Fine-Design_Share_Share_Read_Me_Tip"); + WorkContext.getWorkResource().write(readmePath, msg.getBytes()); + } + + public static String getWidgetId(Widget widget) { + if (StringUtils.isEmpty(widget.getWidgetID())) { + // 做下兼容处理,之前的插件创建的组件没有对应的widgetId + return widget.getWidgetName(); + } + return widget.getWidgetID(); + } + + public static String getCurrentTemplateID() { + JTemplate jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + IOFile target = (IOFile) jt.getTarget(); + return target.getTemplateID(); + } + + public static boolean isShareWidget(XCreator xCreator) { + if (xCreator == null) { + return false; + } + if (xCreator.isShared()) { + return true; + } + if (xCreator instanceof XLayoutContainer) { + XLayoutContainer xLayoutContainer = (XLayoutContainer) xCreator; + ExtendSharableAttrMark sharableAttrMark = xLayoutContainer.toData().getWidgetAttrMark(ExtendSharableAttrMark.XML_TAG); + return sharableAttrMark != null && StringUtils.isNotEmpty(sharableAttrMark.getShareId()); + } + return false; + } + + + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/util/ShareUIUtils.java b/designer-form/src/main/java/com/fr/design/mainframe/share/util/ShareUIUtils.java new file mode 100644 index 000000000..204553f1d --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/util/ShareUIUtils.java @@ -0,0 +1,189 @@ +package com.fr.design.mainframe.share.util; + +import com.fr.design.dialog.FineJOptionPane; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.DesignerContext; +import com.fr.invoke.Reflect; +import com.fr.log.FineLoggerFactory; +import com.fr.stable.ArrayUtils; +import com.fr.third.net.sf.cglib.proxy.Callback; +import com.fr.third.net.sf.cglib.proxy.CallbackFilter; +import com.fr.third.net.sf.cglib.proxy.Enhancer; +import com.fr.third.net.sf.cglib.proxy.MethodInterceptor; +import com.fr.third.net.sf.cglib.proxy.MethodProxy; +import com.fr.third.net.sf.cglib.proxy.NoOp; +import org.jetbrains.annotations.NotNull; + +import javax.swing.AbstractButton; +import javax.swing.JComponent; +import javax.swing.SwingConstants; +import javax.swing.plaf.ComponentUI; +import java.awt.Graphics; +import java.awt.event.ActionEvent; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; + +/** + * created by Harrison on 2020/04/20 + **/ +public class ShareUIUtils { + + private static final String PAINT_METHOD = "paint"; + + private static final String widthStyle = "%s"; + + /** + * 停止当前线程 xx s + * + * @param limit 限制 + * @throws InterruptedException 中断异常 + */ + public static void wait(int limit) throws InterruptedException { + + long start = System.currentTimeMillis(); + while (System.currentTimeMillis() - start < limit) { + Thread.sleep(50); + } + } + + public static String formatWidthString(String msg, int width) { + + return String.format(widthStyle, width, msg); + } + + public static UILabel createTipsLabel(String msg) { + + String tips = "" + msg + ""; + return new UILabel(tips); + } + + public static UILabel createTopRightUILabel(String msg) { + + UILabel label = new UILabel(msg, SwingConstants.RIGHT); + label.setVerticalAlignment(SwingConstants.TOP); + return label; + } + + public static UILabel createCenterRightUILabel(String msg) { + + UILabel label = new UILabel(msg, SwingConstants.RIGHT); + label.setVerticalAlignment(SwingConstants.CENTER); + return label; + } + + public static UILabel createHyperlinkLabel(String msg) { + + String hyperlink = ("") + msg + ""; + return new UILabel(hyperlink); + } + + public static String convertStateChange(int stateChange) { + + return String.valueOf(stateChange); + } + + public static void simulateAction(AbstractButton button) { + + ActionEvent event = new ActionEvent(button, + ActionEvent.ACTION_PERFORMED, + button.getActionCommand()); + button.dispatchEvent(event); + } + + public static T wrapUI(final ComponentUI newUI, final T component, Object... constructArgs) { + + try { + return warpUI0(newUI, component, constructArgs); + } catch (Exception e) { + //虽然没渲染上,但是不影响使用。 使用 warn 吧 + FineLoggerFactory.getLogger().warn(e.getMessage(), e); + return component; + } + } + + @SuppressWarnings("unchecked") + private static T warpUI0(final ComponentUI newUI, final T component, Object... constructArgs) throws NoSuchMethodException { + + Enhancer enhancer = new Enhancer(); + enhancer.setSuperclass(component.getClass()); + enhancer.setCallbacks(new Callback[]{ + NoOp.INSTANCE, + new MethodInterceptor() { + @Override + public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { + + Object value = methodProxy.invokeSuper(o, objects); + newUI.paint((Graphics) objects[0], component); + return value; + } + } + }); + enhancer.setCallbackFilter(new CallbackFilter() { + @Override + public int accept(Method method) { + return method.getName().equals(PAINT_METHOD) ? 1 : 0; + } + }); + + + Constructor constructor = constructor(component.getClass(), constructArgs); + if (constructArgs.length == 0 || constructor == null) { + return (T) enhancer.create(); + } + return (T) enhancer.create(constructor.getParameterTypes(), constructArgs); + } + + + public static Constructor constructor(Class type, Object... args) { + + Class[] types = argumentTypes(args); + try { + return type.getDeclaredConstructor(types); + } catch (NoSuchMethodException e) { + for (Constructor constructor : type.getDeclaredConstructors()) { + if (match(constructor.getParameterTypes(), types)) { + return constructor; + } + } + } + return null; + } + + public static void showErrorMessageDialog(String message) { + FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), + message, + Toolkit.i18nText("Fine-Design_Share_Dialog_Message"), + FineJOptionPane.ERROR_MESSAGE); + } + + private static boolean match(Class[] declaredTypes, Class[] actualTypes) { + if (declaredTypes.length == actualTypes.length) { + for (int i = 0; i < actualTypes.length; i++) { + if (Reflect.wrapper(declaredTypes[i]).isAssignableFrom(Reflect.wrapper(actualTypes[i]))) { + continue; + } + return false; + } + return true; + } else { + return false; + } + } + + @NotNull + private static Class[] argumentTypes(Object[] constructArgs) { + + if (ArrayUtils.isEmpty(constructArgs)) { + return new Class[0]; + } + int length = constructArgs.length; + Class[] classes = new Class[length]; + for (int i = 0; i < length; i++) { + classes[i] = constructArgs[i].getClass(); + } + return classes; + } + + +} diff --git a/designer-form/src/main/java/com/fr/design/widget/ui/designer/mobile/component/MobileComponentFrozenPane.java b/designer-form/src/main/java/com/fr/design/widget/ui/designer/mobile/component/MobileComponentFrozenPane.java index 0dd2fcc15..a06cb1cd0 100644 --- a/designer-form/src/main/java/com/fr/design/widget/ui/designer/mobile/component/MobileComponentFrozenPane.java +++ b/designer-form/src/main/java/com/fr/design/widget/ui/designer/mobile/component/MobileComponentFrozenPane.java @@ -14,6 +14,8 @@ import com.fr.design.widget.FRWidgetFactory; import com.fr.form.main.Form; import com.fr.form.ui.FormWidgetHelper; import com.fr.form.ui.Widget; +import com.fr.form.ui.container.WBodyLayoutType; +import com.fr.form.ui.container.WFitLayout; import com.fr.form.ui.container.WLayout; import com.fr.form.ui.container.WSortLayout; import com.fr.form.ui.widget.CRBoundsWidget; @@ -123,9 +125,7 @@ public class MobileComponentFrozenPane extends BasicPane { } private List frozenWidgets() { - Form form = WidgetPropertyPane.getInstance().getEditingFormDesigner().getTarget(); - WLayout container = form.getContainer(); - WSortLayout wSortLayout = (WSortLayout) container.getWidget(container.getWidgetCount() - 1); + WSortLayout wSortLayout = getBodyWSortLayout(); List list = wSortLayout.getNonContainerWidgetList(); List widgets = new ArrayList<>(); for (String value : list) { @@ -137,6 +137,18 @@ public class MobileComponentFrozenPane extends BasicPane { return widgets; } + private WSortLayout getBodyWSortLayout() { + Form form = WidgetPropertyPane.getInstance().getEditingFormDesigner().getTarget(); + WLayout container = form.getContainer(); + WFitLayout wFitLayout = (WFitLayout) container.getWidget(container.getWidgetCount() - 1); + WSortLayout wSortLayout = wFitLayout; + if (wFitLayout.getBodyLayoutType() == WBodyLayoutType.ABSOLUTE) { + CRBoundsWidget boundsWidget = (CRBoundsWidget) wFitLayout.getWidget(0); + wSortLayout = (WSortLayout) boundsWidget.getWidget(); + } + return wSortLayout; + } + @Override protected String title4PopupWindow() { return "ComponentFrozenPane"; diff --git a/designer-form/src/test/java/com/fr/design/mainframe/ReuseTriggerPointManagerTest.java b/designer-form/src/test/java/com/fr/design/mainframe/ReuseTriggerPointManagerTest.java new file mode 100644 index 000000000..8a80e7f7d --- /dev/null +++ b/designer-form/src/test/java/com/fr/design/mainframe/ReuseTriggerPointManagerTest.java @@ -0,0 +1,45 @@ +package com.fr.design.mainframe; + +import com.fr.design.mainframe.reuse.ComponentReuseNotificationInfo; +import org.junit.Assert; +import org.junit.Test; + +/** + * Created by kerry on 5/10/21 + */ +public class ReuseTriggerPointManagerTest { + private static final long ONE_WEEK_TIME = 7 * 24 * 3600 * 1000L; + + + @Test + public void testNeedTrigger() { + ComponentReuseNotificationInfo notificationInfo = ComponentReuseNotificationInfo.getInstance(); + notificationInfo.setNotifiedNumber(0); + Assert.assertTrue(ReuseTriggerPointManager.getInstance().needTrigger()); + + notificationInfo.setNotifiedNumber(1); + Assert.assertTrue(ReuseTriggerPointManager.getInstance().needTrigger()); + + notificationInfo.setNotifiedNumber(2); + Assert.assertFalse(ReuseTriggerPointManager.getInstance().needTrigger()); + + notificationInfo.setNotifiedNumber(0); + notificationInfo.setLastNotifyTime(System.currentTimeMillis()); + Assert.assertFalse(ReuseTriggerPointManager.getInstance().needTrigger()); + + notificationInfo.setNotifiedNumber(1); + notificationInfo.setLastNotifyTime(System.currentTimeMillis()); + Assert.assertFalse(ReuseTriggerPointManager.getInstance().needTrigger()); + + + notificationInfo.setNotifiedNumber(1); + notificationInfo.setLastNotifyTime(System.currentTimeMillis() - ONE_WEEK_TIME - 1); + Assert.assertTrue(ReuseTriggerPointManager.getInstance().needTrigger()); + + + notificationInfo.setNotifiedNumber(2); + notificationInfo.setLastNotifyTime(System.currentTimeMillis()); + Assert.assertFalse(ReuseTriggerPointManager.getInstance().needTrigger()); + } + +} diff --git a/designer-form/src/test/java/com/fr/design/mainframe/ShareWidgetButtonTest.java b/designer-form/src/test/java/com/fr/design/mainframe/ShareWidgetButtonTest.java deleted file mode 100644 index 50f8afc18..000000000 --- a/designer-form/src/test/java/com/fr/design/mainframe/ShareWidgetButtonTest.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.fr.design.mainframe; - -import com.fr.chart.chartattr.ChartCollection; -import com.fr.design.designer.creator.XCreator; -import com.fr.form.share.SharableWidgetProvider; -import com.fr.form.ui.ChartEditor; -import com.fr.general.ImageWithSuffix; -import com.fr.invoke.Reflect; -import org.easymock.EasyMock; -import org.junit.Assert; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.powermock.core.classloader.annotations.PowerMockIgnore; -import org.powermock.modules.junit4.PowerMockRunner; - -@RunWith(PowerMockRunner.class) -@PowerMockIgnore({"com.fr.jvm.assist.*", "javax.swing.*"}) -public class ShareWidgetButtonTest { - - @Test - public void testCreateXCreator() throws Exception { - - SharableWidgetProvider provider = EasyMock.mock(SharableWidgetProvider.class); - EasyMock.expect(provider.getWidth()).andReturn(300).anyTimes(); - EasyMock.expect(provider.getHeight()).andReturn(400).anyTimes(); - EasyMock.expect(provider.getName()).andReturn("test-drag").anyTimes(); - EasyMock.expect(provider.getCover()).andReturn(new ImageWithSuffix("utf-8")).anyTimes(); - EasyMock.replay(provider); - - ShareWidgetButton.ShareWidgetUI ui = new ShareWidgetButton.ShareWidgetUI(); - - ChartEditor editor = new ChartEditor(); - Reflect.on(editor).set("chartCollection", new ChartCollection()); - XCreator xCreator = ui.createXCreator(editor, "333", provider); - Assert.assertEquals(300, xCreator.getWidth()); - Assert.assertEquals(400, xCreator.getHeight()); - } -} \ No newline at end of file diff --git a/designer-realize/src/main/java/com/fr/design/actions/utils/ReportActionUtils.java b/designer-realize/src/main/java/com/fr/design/actions/utils/ReportActionUtils.java index 7f4a51394..2c0b73fe9 100644 --- a/designer-realize/src/main/java/com/fr/design/actions/utils/ReportActionUtils.java +++ b/designer-realize/src/main/java/com/fr/design/actions/utils/ReportActionUtils.java @@ -2,7 +2,9 @@ package com.fr.design.actions.utils; import com.fr.base.Style; import com.fr.design.actions.cell.style.StyleActionInterface; +import com.fr.design.mainframe.DesignOperationEvent; import com.fr.design.mainframe.ElementCasePane; +import com.fr.event.EventDispatcher; import com.fr.grid.selection.CellSelection; import com.fr.grid.selection.FloatSelection; import com.fr.grid.selection.Selection; @@ -50,9 +52,7 @@ public class ReportActionUtils { @Override public void dealWith(CellElement editCellElement) { Style style2Mod = editCellElement.getStyle(); - editCellElement.setStyle( - styleActionInterface.executeStyle(style2Mod, selectedStyle)); - + updateCellStyle(editCellElement, styleActionInterface.executeStyle(style2Mod, selectedStyle)); } }); } @@ -119,4 +119,9 @@ public class ReportActionUtils { //peter:直接返回当前编辑元素的Style return editCellElement.getStyle(); } -} \ No newline at end of file + + public static void updateCellStyle(CellElement cellElement, Style style){ + cellElement.setStyle(style); + EventDispatcher.fire(DesignOperationEvent.CELL_STYLE_MODIFY); + } +} diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/ElementCasePane.java b/designer-realize/src/main/java/com/fr/design/mainframe/ElementCasePane.java index 30f7b1546..324c21ed4 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/ElementCasePane.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/ElementCasePane.java @@ -271,6 +271,9 @@ public abstract class ElementCasePane extends Tar @Override public void mouseClicked(MouseEvent e) { //如果没有格式刷,点击时就是想使用格式刷 + if (!formatBrush.isEnabled()) { + return; + } if (e.getClickCount() == 1) { if (!formatBrush.isSelected()) { DesignerContext.setFormatState(DesignerContext.FORMAT_STATE_ONCE); @@ -529,7 +532,7 @@ public abstract class ElementCasePane extends Tar || DesignModeContext.isAuthorityEditing()) { try { //旧选中内容编辑器释放模板对象 - QuickEditor editor = this.getCurrentEditor(); + QuickEditor editor = this.selection.getQuickEditorWithoutPopulate(this); if (editor != null) { editor.release(); } diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/JWorkBook.java b/designer-realize/src/main/java/com/fr/design/mainframe/JWorkBook.java index ff14d54f4..0f1ced379 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/JWorkBook.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/JWorkBook.java @@ -145,6 +145,10 @@ public class JWorkBook extends JTemplate { super(workBook, fileName); populateReportParameterAttr(); } + public JWorkBook(WorkBook workBook, FILE file, Parameter[] parameters) { + super(workBook, file, parameters); + populateReportParameterAttr(); + } public JWorkBook(WorkBook workBook, FILE file) { super(workBook, file); @@ -871,6 +875,11 @@ public class JWorkBook extends JTemplate { return new WorkBookModelAdapter(this); } + @Override + protected WorkBookModelAdapter createDesignModel(Parameter[] parameters) { + return new WorkBookModelAdapter(this, parameters); + } + /** * 表单的工具栏 * diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/TemplateLockedHandler.java b/designer-realize/src/main/java/com/fr/design/mainframe/TemplateLockedHandler.java new file mode 100644 index 000000000..7eb6eec5c --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/TemplateLockedHandler.java @@ -0,0 +1,27 @@ +package com.fr.design.mainframe; + +import com.fr.design.dialog.FineJOptionPane; +import com.fr.design.i18n.Toolkit; +import com.fr.design.ui.util.UIUtil; + +/** + * @author hades + * @version 10.0 + * Created by hades on 2021/5/14 + */ +public class TemplateLockedHandler { + + public static void generateTipAndRefresh() { + UIUtil.invokeLaterIfNeeded(new Runnable() { + @Override + public void run() { + FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), + Toolkit.i18nText("Fine_Designer_Remote_Design_Locked_Message"), + Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"), + FineJOptionPane.WARNING_MESSAGE); + DesignerFrameFileDealerPane.getInstance().refresh(); + } + }); + } + +} diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/WorkBookModelAdapter.java b/designer-realize/src/main/java/com/fr/design/mainframe/WorkBookModelAdapter.java index 87391a5a0..53f193be7 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/WorkBookModelAdapter.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/WorkBookModelAdapter.java @@ -36,6 +36,9 @@ public class WorkBookModelAdapter extends DesignModelAdapter { @Override public JTemplate openTemplate(FILE tplFile) { - - return new JWorkBook(asIOFile(tplFile), tplFile); + JWorkBook emptyTemplate = new JWorkBook(new WorkBook(new WorkSheet()), tplFile); + OpenWorker> worker = new OpenWorker<>( + new Callable>() { + @Override + public OpenResult call() { + WorkBook workBook = asIOFile(tplFile); + return new OpenResult<>(workBook, workBook.getParameters()); + } + }, emptyTemplate); + worker.addCallBack(new Callable>() { + @Override + public JTemplate call() throws Exception { + OpenResult result = worker.getResult(); + return new JWorkBook(result.getBaseBook(), tplFile, result.getRef()); + } + }); + worker.start(tplFile.getPath()); + FineLoggerFactory.getLogger().info(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Template_Opening_And_Waiting", tplFile.getName()) + "..."); + OpenResult result = worker.getResult(); + if (result != null) { + return new JWorkBook(result.getBaseBook(), tplFile); + } + return emptyTemplate; } @Override diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/app/CptApp.java b/designer-realize/src/main/java/com/fr/design/mainframe/app/CptApp.java index adadab36d..431b401fc 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/app/CptApp.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/app/CptApp.java @@ -3,6 +3,7 @@ package com.fr.design.mainframe.app; import com.fr.base.BaseUtils; import com.fr.base.Style; import com.fr.base.TempNameStyle; +import com.fr.base.chart.exception.ChartNotFoundException; import com.fr.base.extension.FileExtension; import com.fr.base.io.XMLEncryptUtils; import com.fr.config.ServerPreferenceConfig; @@ -12,6 +13,8 @@ import com.fr.design.gui.ibutton.UIButton; import com.fr.design.gui.ilable.UILabel; import com.fr.design.i18n.Toolkit; import com.fr.design.mainframe.DecodeDialog; +import com.fr.design.mainframe.TemplateLockedHandler; +import com.fr.design.ui.util.UIUtil; import com.fr.design.utils.gui.GUICoreUtils; import com.fr.exception.DecryptTemplateException; import com.fr.exception.RemoteDesignPermissionDeniedException; @@ -56,18 +59,17 @@ class CptApp extends AbstractWorkBookApp { } WorkBook tpl = new WorkBook(); - // richer:打开报表通知 - FineLoggerFactory.getLogger().info(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Template_Opening_And_Waiting", file.getName()) + "..."); TempNameStyle namestyle = TempNameStyle.getInstance(); namestyle.clear(); try { tpl.readStream(file.asInputStream()); - } catch (DecryptTemplateException e) { + } catch (DecryptTemplateException | ChartNotFoundException e) { throw e; } catch (RemoteDesignPermissionDeniedException exp) { FineLoggerFactory.getLogger().error(Toolkit.i18nText("Fine-Design_Basic_Template_Permission_Denied") + file, exp); } catch (TplLockedException exp) { FineLoggerFactory.getLogger().error(file + Toolkit.i18nText("Fine-Design_Basic_Template_Status_Locked"), exp); + TemplateLockedHandler.generateTipAndRefresh(); } catch (Exception exp) { FineLoggerFactory.getLogger().error(Toolkit.i18nText("Fine-Design_Report_NS_Exception_ReadError") + file, exp); } @@ -85,7 +87,12 @@ class CptApp extends AbstractWorkBookApp { al.add((String) it.next()); } if (!al.isEmpty()) { - showConfirmDialog(al); + UIUtil.invokeLaterIfNeeded(new Runnable() { + @Override + public void run() { + showConfirmDialog(al); + } + }); } } diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/app/CptxApp.java b/designer-realize/src/main/java/com/fr/design/mainframe/app/CptxApp.java index a59ead41d..95104e2f8 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/app/CptxApp.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/app/CptxApp.java @@ -1,5 +1,6 @@ package com.fr.design.mainframe.app; +import com.fr.base.chart.exception.ChartNotFoundException; import com.fr.base.extension.FileExtension; import com.fr.base.frpx.exception.FRPackageRunTimeException; import com.fr.base.frpx.exception.InvalidWorkBookException; @@ -37,7 +38,7 @@ class CptxApp extends AbstractWorkBookApp { long time = System.currentTimeMillis(); tpl = new WorkBookX(inputStream); FineLoggerFactory.getLogger().error("cost: " + (System.currentTimeMillis() - time) + " ms"); - } catch (DecryptTemplateException e) { + } catch (DecryptTemplateException | ChartNotFoundException e) { throw e; } catch (RemoteDesignPermissionDeniedException exp) { FineLoggerFactory.getLogger().error(Toolkit.i18nText("Fine-Design_Basic_Template_Permission_Denied") + file, exp); diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/app/FormApp.java b/designer-realize/src/main/java/com/fr/design/mainframe/app/FormApp.java index 046451337..5d828713f 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/app/FormApp.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/app/FormApp.java @@ -1,22 +1,31 @@ package com.fr.design.mainframe.app; +import com.fr.base.Parameter; +import com.fr.base.chart.exception.ChartNotFoundException; import com.fr.base.io.XMLEncryptUtils; import com.fr.design.DesignerEnvManager; import com.fr.design.i18n.Toolkit; import com.fr.design.mainframe.AbstractAppProvider; import com.fr.design.mainframe.BaseJForm; import com.fr.design.mainframe.DecodeDialog; +import com.fr.design.mainframe.JForm; import com.fr.design.mainframe.JTemplate; +import com.fr.design.mainframe.TemplateLockedHandler; +import com.fr.design.worker.open.OpenResult; +import com.fr.design.worker.open.OpenWorker; import com.fr.exception.DecryptTemplateException; import com.fr.exception.RemoteDesignPermissionDeniedException; import com.fr.exception.TplLockedException; import com.fr.file.FILE; import com.fr.form.main.Form; +import com.fr.form.ui.container.WBorderLayout; +import com.fr.general.ComparatorUtils; import com.fr.log.FineLoggerFactory; import com.fr.stable.Constants; import com.fr.stable.bridge.StableFactory; import java.util.HashMap; +import java.util.concurrent.Callable; /** * Created by juhaoyu on 2018/6/27. @@ -36,9 +45,46 @@ class FormApp extends AbstractAppProvider { HashMap classType = new HashMap(); classType.put(Constants.ARG_0, Form.class); classType.put(Constants.ARG_1, FILE.class); + FineLoggerFactory.getLogger().info(Toolkit.i18nText("Fine-Design_Report_Template_Opening_And_Waiting", tplFile.getName()) + "..."); + return compatibleForm(tplFile, classType); + } - return (JTemplate) StableFactory.getMarkedInstanceObjectFromClass(BaseJForm.XML_TAG, - new Object[]{asIOFile(tplFile), tplFile}, classType, BaseJForm.class); + /** + * 兼容外部注册的frm类型 + * + * @return + */ + private JTemplate compatibleForm(FILE tplFile, HashMap classType) { + if (ComparatorUtils.equals(StableFactory.getRegisteredClass(BaseJForm.XML_TAG), JForm.class)) { + classType.put(Constants.ARG_2, Parameter[].class); + JForm emptyForm = new JForm(new Form(new WBorderLayout("form")), tplFile); + OpenWorker> worker = new OpenWorker<>( + new Callable>() { + @Override + public OpenResult call() throws Exception { + Form form = asIOFile(tplFile); + return new OpenResult<>(form, form.getParameters()); + } + }, emptyForm); + worker.addCallBack(new Callable>() { + @Override + public JTemplate call() throws Exception { + OpenResult result = worker.getResult(); + return (JTemplate) StableFactory.getMarkedInstanceObjectFromClass(BaseJForm.XML_TAG, + new Object[]{result.getBaseBook(), tplFile, result.getRef()}, classType, BaseJForm.class); + } + }); + worker.start(tplFile.getPath()); + OpenResult result = worker.getResult(); + if (result != null) { + return (JTemplate) StableFactory.getMarkedInstanceObjectFromClass(BaseJForm.XML_TAG, + new Object[]{result.getBaseBook(), tplFile, new Parameter[0]}, classType, BaseJForm.class); + } + return emptyForm; + } else { + return (JTemplate) StableFactory.getMarkedInstanceObjectFromClass(BaseJForm.XML_TAG, + new Object[]{asIOFile(tplFile), tplFile}, classType, BaseJForm.class); + } } @Override @@ -54,16 +100,15 @@ class FormApp extends AbstractAppProvider { // peter:打开新报表. Form tpl = new Form(); - // richer:打开报表通知 - FineLoggerFactory.getLogger().info(com.fr.design.i18n.Toolkit.i18nText("file.getName()", file.getName()) + "..."); try { tpl.readStream(file.asInputStream()); - } catch (DecryptTemplateException e) { + } catch (DecryptTemplateException | ChartNotFoundException e) { throw e; } catch (RemoteDesignPermissionDeniedException exp) { FineLoggerFactory.getLogger().error(Toolkit.i18nText("Fine-Design_Basic_Template_Permission_Denied") + file, exp); } catch (TplLockedException exp) { FineLoggerFactory.getLogger().error(file + Toolkit.i18nText("Fine-Design_Basic_Template_Status_Locked"), exp); + TemplateLockedHandler.generateTipAndRefresh(); } catch (Exception exp) { FineLoggerFactory.getLogger().error("Failed to generate frm from " + file, exp); return null; diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/app/XlsApp.java b/designer-realize/src/main/java/com/fr/design/mainframe/app/XlsApp.java index 3741f8b35..5b135ccdf 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/app/XlsApp.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/app/XlsApp.java @@ -2,6 +2,7 @@ package com.fr.design.mainframe.app; import com.fr.base.extension.FileExtension; import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.TemplateLockedHandler; import com.fr.exception.RemoteDesignPermissionDeniedException; import com.fr.exception.TplLockedException; import com.fr.file.FILE; @@ -30,6 +31,7 @@ class XlsApp extends AbstractWorkBookApp { FineLoggerFactory.getLogger().error(Toolkit.i18nText("Fine-Design_Basic_Template_Permission_Denied") + tplFile, exp); } catch (TplLockedException exp) { FineLoggerFactory.getLogger().error(tplFile + Toolkit.i18nText("Fine-Design_Basic_Template_Status_Locked"), exp); + TemplateLockedHandler.generateTipAndRefresh(); } catch (Exception exp) { FineLoggerFactory.getLogger().error("Failed to generate xls from " + tplFile, exp); } diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/app/XlsxApp.java b/designer-realize/src/main/java/com/fr/design/mainframe/app/XlsxApp.java index 9d66cffb8..f5a5498cf 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/app/XlsxApp.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/app/XlsxApp.java @@ -2,6 +2,7 @@ package com.fr.design.mainframe.app; import com.fr.base.extension.FileExtension; import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.TemplateLockedHandler; import com.fr.exception.RemoteDesignPermissionDeniedException; import com.fr.exception.TplLockedException; import com.fr.file.FILE; @@ -31,6 +32,7 @@ class XlsxApp extends AbstractWorkBookApp { FineLoggerFactory.getLogger().error(Toolkit.i18nText("Fine-Design_Basic_Template_Permission_Denied") + tplFile, exp); } catch (TplLockedException exp) { FineLoggerFactory.getLogger().error(tplFile + Toolkit.i18nText("Fine-Design_Basic_Template_Status_Locked"), exp); + TemplateLockedHandler.generateTipAndRefresh(); } catch (Exception exp) { FineLoggerFactory.getLogger().error("Failed to generate xlsx from " + tplFile, exp); } diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/CellStylePane.java b/designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/CellStylePane.java index 4bfd9fa46..049b0111a 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/CellStylePane.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/CellStylePane.java @@ -1,6 +1,7 @@ package com.fr.design.mainframe.cell.settingpane; import com.fr.base.Style; +import com.fr.design.actions.utils.ReportActionUtils; import com.fr.design.constants.UIConstants; import com.fr.design.mainframe.cell.settingpane.style.StylePane; import com.fr.design.style.BorderUtils; @@ -63,7 +64,7 @@ public class CellStylePane extends AbstractCellAttrPane { @Override public void updateBean(TemplateCellElement cellElement) { - cellElement.setStyle(stylePane.updateBean()); + ReportActionUtils.updateCellStyle(cellElement, stylePane.updateBean()); } @Override diff --git a/designer-realize/src/main/java/com/fr/design/share/effect/BaseEffectItem.java b/designer-realize/src/main/java/com/fr/design/share/effect/BaseEffectItem.java new file mode 100644 index 000000000..20d562621 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/effect/BaseEffectItem.java @@ -0,0 +1,115 @@ +package com.fr.design.share.effect; + +import com.fr.design.beans.BasicBeanPane; +import com.fr.design.gui.controlpane.NameableCreator; +import com.fr.design.share.effect.source.SourceNode; +import com.fr.stable.StringUtils; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; + +public class BaseEffectItem implements EffectItem{ + private String name = StringUtils.EMPTY; + private String description = StringUtils.EMPTY; + private NameableCreator creator; + private T object; + private SourceNode sourceNode; + + @Override + public SourceNode getSourceNode() { + return sourceNode; + } + + @Override + public String getConfigPath() { + return getSourceNode().toString(); + } + + public void setSourceNode(SourceNode sourceNode) { + this.sourceNode = sourceNode; + } + + @Override + public String getName() { + return name; + } + + @Override + public void setName(String name) { + this.name = name; + } + + @Override + public String getDescription() { + return description; + } + + @Override + public void setDescription(String description) { + this.description = description; + } + + + @Override + public void save() { + + } + + @Override + public Object getPopulateBean(){ + return getObject(); + } + + @Override + public void updateBean(Object bean) { + + } + + @Override + public T getObject() { + return object; + } + + @Override + public void setObject(T ob) { + this.object = ob; + } + + @Override + public NameableCreator creator() { + return this.creator; + } + + public void setNameableCreator(NameableCreator creator) { + this.creator = creator; + } + + @Override + public BasicBeanPane createPaneByCreators(NameableCreator creator) { + try { + return creator.getUpdatePane().newInstance(); + } catch (InstantiationException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + } + + @Override + public BasicBeanPane createPaneByCreators(NameableCreator creator, String string) { + Constructor constructor; + try { + constructor = creator.getUpdatePane().getDeclaredConstructor(new Class[]{String.class}); + constructor.setAccessible(true); + return (BasicBeanPane) constructor.newInstance(string); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } catch (InstantiationException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } catch (InvocationTargetException e) { + throw new RuntimeException(e); + } + } +} diff --git a/designer-realize/src/main/java/com/fr/design/share/effect/ConditionEffectItem.java b/designer-realize/src/main/java/com/fr/design/share/effect/ConditionEffectItem.java new file mode 100644 index 000000000..ea5096085 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/effect/ConditionEffectItem.java @@ -0,0 +1,86 @@ +package com.fr.design.share.effect; + +import com.fr.chart.chartattr.Plot; +import com.fr.chart.chartglyph.ConditionAttr; +import com.fr.design.ChartTypeInterfaceManager; +import com.fr.design.beans.BasicBeanPane; +import com.fr.design.condition.ConditionAttributesPane; +import com.fr.design.gui.controlpane.NameObjectCreator; +import com.fr.design.gui.controlpane.NameableCreator; +import com.fr.design.share.effect.source.SourceNode; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; + +public class ConditionEffectItem extends BaseEffectItem { + private ConditionAttr condition; + private Plot plot; + public ConditionEffectItem(ConditionAttr condition, SourceNode sourceNode, Plot plot) { + this.condition = condition; + this.plot = plot; + this.setSourceNode(sourceNode); + init(); + } + + private void init() { + ConditionAttr object; + try { + object = (ConditionAttr) condition.clone(); + } catch (CloneNotSupportedException e) { + object = new ConditionAttr(); + object.setName(condition.getName()); + object.setCondition(condition.getCondition()); + for (int i = 0; i < condition.getDataSeriesConditionCount(); i++) { + object.addDataSeriesCondition(condition.getDataSeriesCondition(i)); + } + } + setObject(object); + this.setName(condition.getName()); + this.setNameableCreator(new NameObjectCreator(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Condition_Attributes"), ConditionAttr.class, getPlotConditionPane(this.plot))); + } + + private Class getPlotConditionPane(Plot plot) { + return ChartTypeInterfaceManager.getInstance().getPlotConditionPane(plot).getClass(); + } + + @Override + public void setName(String name) { + super.setName(name); + getObject().setName(name); + } + + @Override + public BasicBeanPane createPaneByCreators(NameableCreator creator) { + Constructor constructor = null; + try { + constructor = creator.getUpdatePane().getConstructor(Plot.class); + return constructor.newInstance(this.plot); + + } catch (InstantiationException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } + return null; + } + + @Override + public void updateBean(Object bean) { + ConditionAttr conditionAttr = (ConditionAttr) bean; + conditionAttr.setName(this.getName()); + setObject(conditionAttr); + } + + public void save() { + condition.setName(getObject().getName()); + condition.setCondition(getObject().getCondition()); + condition.removeAll(); + for (int i = 0; i < getObject().getDataSeriesConditionCount(); i++) { + condition.addDataSeriesCondition(getObject().getDataSeriesCondition(i)); + } + } +} diff --git a/designer-realize/src/main/java/com/fr/design/share/effect/EffectItem.java b/designer-realize/src/main/java/com/fr/design/share/effect/EffectItem.java new file mode 100644 index 000000000..33bfe7fe5 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/effect/EffectItem.java @@ -0,0 +1,32 @@ +package com.fr.design.share.effect; + +import com.fr.design.beans.BasicBeanPane; +import com.fr.design.gui.controlpane.NameableCreator; +import com.fr.design.share.effect.source.SourceNode; +import com.fr.stable.Nameable; + +public interface EffectItem extends Nameable { + SourceNode getSourceNode(); + + String getConfigPath(); + + String getDescription(); + + void setDescription(String description); + + T getObject(); + + void setObject(T ob); + + Object getPopulateBean(); + + void save(); + + void updateBean(Object bean); + + NameableCreator creator(); + + BasicBeanPane createPaneByCreators(NameableCreator creator); + + BasicBeanPane createPaneByCreators(NameableCreator creator, String string); +} diff --git a/designer-realize/src/main/java/com/fr/design/share/effect/EffectItemGroup.java b/designer-realize/src/main/java/com/fr/design/share/effect/EffectItemGroup.java new file mode 100644 index 000000000..923c200d1 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/effect/EffectItemGroup.java @@ -0,0 +1,279 @@ +package com.fr.design.share.effect; + +import com.fr.chart.chartattr.Chart; +import com.fr.chart.chartattr.ChartCollection; +import com.fr.chart.chartattr.Plot; +import com.fr.chart.chartglyph.ConditionCollection; +import com.fr.chartx.attr.ChartProvider; +import com.fr.design.share.effect.source.SourceNode; +import com.fr.design.share.effect.source.SourceNodeUtils; +import com.fr.form.FormElementCaseProvider; +import com.fr.form.event.Listener; +import com.fr.form.ui.ChartEditor; +import com.fr.form.ui.ElementCaseEditor; +import com.fr.form.ui.Widget; +import com.fr.form.ui.container.WTitleLayout; +import com.fr.js.NameJavaScript; +import com.fr.js.NameJavaScriptGroup; +import com.fr.plugin.chart.attr.axis.VanChartAlertValue; +import com.fr.plugin.chart.attr.axis.VanChartAxis; +import com.fr.plugin.chart.attr.plot.VanChartPlot; +import com.fr.plugin.chart.attr.plot.VanChartRectanglePlot; +import com.fr.plugin.chart.custom.VanChartCustomPlot; +import com.fr.report.cell.DefaultTemplateCellElement; +import com.fr.report.cell.cellattr.highlight.DefaultHighlight; +import com.fr.report.cell.cellattr.highlight.HighlightGroup; +import com.fr.report.web.util.ReportEngineEventMapping; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; + +public class EffectItemGroup { + private List conditionEffectItems = new ArrayList(); + private List highlightEffectItems = new ArrayList(); + private List hyperlinkEffectItems = new ArrayList(); + private List listenerEffectItems = new ArrayList(); + private List stackAndAxisConditionEffectItems = new ArrayList(); + private List vanChartAlertValueEffectItems = new ArrayList(); + private List effectItems = new ArrayList(); + private LinkedHashMap> effectItemsMap; + private Widget widget; + + public EffectItemGroup() { + + } + + public EffectItemGroup(Widget widget) { + this.widget = widget; + initListener(widget); + if (widget instanceof WTitleLayout) { + WTitleLayout wTitleLayout = (WTitleLayout) widget; + this.widget = wTitleLayout.getBodyBoundsWidget().getWidget(); + if (this.widget instanceof ElementCaseEditor) { + initElementCase(); + } else if (this.widget instanceof ChartEditor) { + initChartEditor(); + } + } + } + + public Widget getWidget() { + return widget; + } + + private void initListener(Widget widget) { + int listenerSize = widget.getListenerSize(); + for (int index = 0; index < listenerSize; index ++) { + Listener listener = widget.getListener(index); + SourceNode sourceNode = SourceNodeUtils.createSourceNode(widget, null); + String eventName = switchLang(listener.getEventName()) + (index + 1); + this.add(new ListenerEffectItem(listener, sourceNode, eventName)); + } + } + + private String switchLang(String eventName) { + // 在 properties 文件中找到相应的 key 值 + String localeKey = ReportEngineEventMapping.getLocaleName(eventName); + return com.fr.design.i18n.Toolkit.i18nText(localeKey); + } + + private void initElementCase() { + ElementCaseEditor editor = (ElementCaseEditor) this.widget; + FormElementCaseProvider elementCase = editor.getElementCase(); + Iterator cellIterator = elementCase.cellIterator(); + + while(cellIterator.hasNext()) { + DefaultTemplateCellElement cellElement = (DefaultTemplateCellElement) cellIterator.next(); + SourceNode cellSourceNode = SourceNodeUtils.createSourceNode(cellElement, null); + + // 条件属性 + if (cellElement.getHighlightGroup() != null) { + HighlightGroup highlightGroup = cellElement.getHighlightGroup(); + for (int index = 0; index < highlightGroup.size(); index ++) { + DefaultHighlight highlight=(DefaultHighlight) highlightGroup.getHighlight(index); + this.add(new HighlightEffectItem(highlight, cellSourceNode)); + } + } + + // 超链 + if (cellElement.getNameHyperlinkGroup() != null) { + NameJavaScriptGroup nameHyperlinkGroup = cellElement.getNameHyperlinkGroup(); + for (int index = 0; index < nameHyperlinkGroup.size(); index ++) { + NameJavaScript nameJavaScript = nameHyperlinkGroup.getNameHyperlink(index); + this.add(new HyperlinkEffectItem(nameJavaScript, cellSourceNode)); + } + } + + // 图表内部 + Object value = cellElement.getValue(); + if (value instanceof ChartCollection) { + ChartCollection chartCollection = (ChartCollection) value; + for (int index = 0; index < chartCollection.getChartCount(); index++) { + Chart chart= (Chart) chartCollection.getChart(index, ChartProvider.class); + SourceNode chartSourceNode = SourceNodeUtils.createSourceNode(chart.getPlot(), chartCollection.getChartName(index), cellSourceNode); + Plot plot = chart.getPlot(); + initChartPlot(plot, chartSourceNode, false); + } + + } + } + + } + + private void initChartEditor() { + ChartEditor editor = (ChartEditor) this.widget; + ChartCollection chartCollection = (ChartCollection) editor.getChartCollection(); + for (int index = 0; index < chartCollection.getChartCount(); index++) { + Chart chart= (Chart) chartCollection.getChart(index, ChartProvider.class); + SourceNode plotSourceNode = SourceNodeUtils.createSourceNode(chart.getPlot(), chartCollection.getChartName(index), null); + Plot plot = chart.getPlot(); + initChartPlot(plot, plotSourceNode, false); + } + + } + + private void initChartPlot(Plot plot, SourceNode sourceNode, boolean isSubChart) { + if (plot.getConditionCollection() != null) { + // 图表条件属性 + ConditionCollection conditionCollection = plot.getConditionCollection(); + for (int j = 0; j < conditionCollection.getConditionAttrSize(); j ++) { + this.add(new ConditionEffectItem(conditionCollection.getConditionAttr(j), sourceNode, plot)); + } + } + + if (plot.getHotHyperLink() != null) { + // 图表超链 + NameJavaScriptGroup nameHyperlinkGroup = plot.getHotHyperLink(); + for (int j = 0; j < nameHyperlinkGroup.size(); j ++) { + NameJavaScript nameJavaScript = nameHyperlinkGroup.getNameHyperlink(j); + this.add(new HyperlinkEffectItem(nameJavaScript, sourceNode)); + } + } + + if (plot instanceof VanChartRectanglePlot) { + VanChartRectanglePlot rectanglePlot = (VanChartRectanglePlot) plot; + // 堆积和坐标轴 + ConditionCollection stackAndAxisCondition= rectanglePlot.getStackAndAxisCondition(); + + for(int index = 0; index < stackAndAxisCondition.getConditionAttrSize(); index ++) { + this.add(new StackAndAxisConditionEffectItem(stackAndAxisCondition.getConditionAttr(index), sourceNode, (VanChartRectanglePlot) plot)); + } + if (!isSubChart) { + // 警戒线 + List xAxisList = rectanglePlot.getXAxisList(); + List yAxisList = rectanglePlot.getYAxisList(); + for(VanChartAxis axis : xAxisList) { + for(VanChartAlertValue alertValue: axis.getAlertValues()) { + this.add(new VanChartAlertValueEffectItem(alertValue, sourceNode, (VanChartRectanglePlot) plot)); + } + } + for(VanChartAxis axis : yAxisList) { + for(VanChartAlertValue alertValue: axis.getAlertValues()) { + this.add(new VanChartAlertValueEffectItem(alertValue, sourceNode, (VanChartRectanglePlot) plot)); + } + } + } + } + + if (plot instanceof VanChartCustomPlot) { + VanChartCustomPlot customPlot = (VanChartCustomPlot) plot; + List plotList= customPlot.getCustomPlotList(); + for(VanChartPlot innerPlot : plotList) { + initChartPlot(innerPlot, SourceNodeUtils.createSourceNode(innerPlot, sourceNode), true); + } + } + } + + public List getConditionEffectItems() { + return conditionEffectItems; + } + + public List getHighlightEffectItems() { + return highlightEffectItems; + } + + public List getHyperlinkEffectItems() { + return hyperlinkEffectItems; + } + + public List getListenerEffectItems() { + return listenerEffectItems; + } + + public List getStackAndAxisConditionEffectItems() { + return stackAndAxisConditionEffectItems; + } + + public List getVanChartAlertLineEffectItems() { + return vanChartAlertValueEffectItems; + } + + public List getEffectItems() { + return effectItems; + } + + public void add(ConditionEffectItem conditionEffectItem) { + conditionEffectItems.add(conditionEffectItem); + effectItems.add(conditionEffectItem); + } + + public void add(HighlightEffectItem highlightEffectItem) { + highlightEffectItems.add(highlightEffectItem); + effectItems.add(highlightEffectItem); + } + + public void add(HyperlinkEffectItem hyperlinkEffectItem) { + hyperlinkEffectItems.add(hyperlinkEffectItem); + effectItems.add(hyperlinkEffectItem); + } + + public void add(ListenerEffectItem listenerEffectItem) { + listenerEffectItems.add(listenerEffectItem); + effectItems.add(listenerEffectItem); + } + + public void add(StackAndAxisConditionEffectItem stackAndAxisConditionEffectItem) { + stackAndAxisConditionEffectItems.add(stackAndAxisConditionEffectItem); + effectItems.add(stackAndAxisConditionEffectItem); + } + + public void add(VanChartAlertValueEffectItem vanChartAlertLineEffectItem) { + vanChartAlertValueEffectItems.add(vanChartAlertLineEffectItem); + effectItems.add(vanChartAlertLineEffectItem); + } + + public LinkedHashMap> getEffectItemsWithClassify() { + if (effectItemsMap != null) { + return effectItemsMap; + } + effectItemsMap = new LinkedHashMap>(); + + if (listenerEffectItems.size() > 0) { + effectItemsMap.put(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Event"), listenerEffectItems); + } + if (highlightEffectItems.size() > 0 || conditionEffectItems.size() > 0) { + List tmpEffectItems = new ArrayList<>(); + tmpEffectItems.addAll(highlightEffectItems); + tmpEffectItems.addAll(conditionEffectItems); + effectItemsMap.put(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Condition_Attributes"), tmpEffectItems); + } + if (hyperlinkEffectItems.size() > 0) { + effectItemsMap.put(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Hyperlink"), hyperlinkEffectItems); + } + if (vanChartAlertValueEffectItems.size() > 0 || stackAndAxisConditionEffectItems.size() > 0) { + List tmpEffectItems = new ArrayList<>(); + tmpEffectItems.addAll(vanChartAlertValueEffectItems); + tmpEffectItems.addAll(stackAndAxisConditionEffectItems); + effectItemsMap.put(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Other"), tmpEffectItems); + } + return effectItemsMap; + } + + public void save() { + for (EffectItem effectItem : this.effectItems) { + effectItem.save(); + } + } +} diff --git a/designer-realize/src/main/java/com/fr/design/share/effect/HighlightEffectItem.java b/designer-realize/src/main/java/com/fr/design/share/effect/HighlightEffectItem.java new file mode 100644 index 000000000..806e2e51a --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/effect/HighlightEffectItem.java @@ -0,0 +1,56 @@ +package com.fr.design.share.effect; + +import com.fr.design.condition.HighLightConditionAttributesPane; +import com.fr.design.gui.controlpane.NameObjectCreator; +import com.fr.design.share.effect.source.SourceNode; +import com.fr.report.cell.cellattr.highlight.DefaultHighlight; + +public class HighlightEffectItem extends BaseEffectItem{ + private DefaultHighlight highlight; + + public HighlightEffectItem(DefaultHighlight highlight, SourceNode sourceNode) { + this.highlight = highlight; + this.setSourceNode(sourceNode); + this.init(); + } + + private void init() { + DefaultHighlight object; + try { + object = (DefaultHighlight) highlight.clone(); + } catch (CloneNotSupportedException e) { + object = new DefaultHighlight(); + object.setName(highlight.getName()); + object.setCondition(highlight.getCondition()); + for (int i = 0; i < highlight.actionCount(); i++) { + object.addHighlightAction(highlight.getHighlightAction(i)); + } + } + setObject(object); + + this.setName(highlight.getName()); + this.setNameableCreator(new NameObjectCreator(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Condition_Attributes"), DefaultHighlight.class, HighLightConditionAttributesPane.class)); + } + + public void setName(String name) { + super.setName(name); + getObject().setName(name); + } + + @Override + public void updateBean(Object bean) { + DefaultHighlight highlight = (DefaultHighlight) bean; + highlight.setName(this.getName()); + setObject(highlight); + } + + @Override + public void save() { + highlight.setCondition(getObject().getCondition()); + highlight.setName(getObject().getName()); + highlight.removeActions(); + for (int i = 0; i < getObject().actionCount(); i++) { + highlight.addHighlightAction(getObject().getHighlightAction(i)); + } + } +} diff --git a/designer-realize/src/main/java/com/fr/design/share/effect/HyperlinkEffectItem.java b/designer-realize/src/main/java/com/fr/design/share/effect/HyperlinkEffectItem.java new file mode 100644 index 000000000..d7a572664 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/effect/HyperlinkEffectItem.java @@ -0,0 +1,93 @@ +package com.fr.design.share.effect; + +import com.fr.design.ExtraDesignClassManager; +import com.fr.design.form.javascript.FormEmailPane; +import com.fr.design.fun.HyperlinkProvider; +import com.fr.design.gui.controlpane.NameObjectCreator; +import com.fr.design.gui.controlpane.NameableCreator; +import com.fr.design.module.DesignModuleFactory; +import com.fr.design.share.effect.source.SourceNode; +import com.fr.general.ComparatorUtils; +import com.fr.js.EmailJavaScript; +import com.fr.js.JavaScript; +import com.fr.js.NameJavaScript; +import com.fr.stable.ListMap; + +import java.util.Map; +import java.util.Set; + +public class HyperlinkEffectItem extends BaseEffectItem{ + private NameJavaScript javaScript; + + public HyperlinkEffectItem(NameJavaScript javaScript, SourceNode sourceNode) { + this.javaScript = javaScript; + this.setSourceNode(sourceNode); + this.init(); + } + + private void init() { + NameJavaScript object; + try { + object = (NameJavaScript) javaScript.clone(); + } catch (CloneNotSupportedException e) { + object = new NameJavaScript(javaScript.getName(), javaScript.getJavaScript()); + } + setObject(object); + + this.setName(this.javaScript.getName()); + NameableCreator[] creators = createNameableCreator(); + for (NameableCreator creator : creators) { + if (creator.acceptObject2Populate(javaScript.getJavaScript()) != null) { + this.setNameableCreator(creator); + return; + } + } + } + + public void setName(String name) { + super.setName(name); + getObject().setName(name); + } + + private NameableCreator[] createNameableCreator() { + Map nameCreators = new ListMap<>(); + NameableCreator[] creators = DesignModuleFactory.getHyperlinkGroupType().getHyperlinkCreators(); + for (NameableCreator creator : creators) { + nameCreators.put(creator.menuName(), creator); + } + Set providers = ExtraDesignClassManager.getInstance().getArray(HyperlinkProvider.XML_TAG); + for (HyperlinkProvider provider : providers) { + NameableCreator nc = provider.createHyperlinkCreator(); + nameCreators.put(nc.menuName(), nc); + } + + creators = nameCreators.values().toArray(new NameableCreator[nameCreators.size()]); + for (int i = 0; i < creators.length; i++) { + if (ComparatorUtils.equals(creators[i].menuName(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Email"))) { + creators[i] = new NameObjectCreator(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Email"), EmailJavaScript.class, FormEmailPane.class); + break; + } + } + + return creators; + } + + @Override + public Object getPopulateBean() { + return getObject().getObject(); + } + + @Override + public void updateBean(Object bean) { + JavaScript javaScript = (JavaScript) bean; + getObject().setJavaScript(javaScript); + getObject().setObject(bean); + } + + @Override + public void save() { + javaScript.setName(getObject().getName()); + javaScript.setObject(getObject().getObject()); + javaScript.setJavaScript(getObject().getJavaScript()); + } +} diff --git a/designer-realize/src/main/java/com/fr/design/share/effect/ListenerEffectItem.java b/designer-realize/src/main/java/com/fr/design/share/effect/ListenerEffectItem.java new file mode 100644 index 000000000..38d635424 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/effect/ListenerEffectItem.java @@ -0,0 +1,41 @@ +package com.fr.design.share.effect; + +import com.fr.design.designer.properties.EventPropertyTable; +import com.fr.design.share.effect.source.SourceNode; +import com.fr.design.widget.EventCreator; +import com.fr.form.event.Listener; +import com.fr.form.ui.Widget; + +public class ListenerEffectItem extends BaseEffectItem { + private Listener listener; + + public ListenerEffectItem(Listener listener, SourceNode sourceNode, String name) { + this.listener = listener; + this.setSourceNode(sourceNode); + this.setName(name); + init(); + } + + private void init() { + Listener object; + try { + object = (Listener) listener.clone(); + } catch (CloneNotSupportedException e) { + object = new Listener(listener.getTargetWidget(), listener.getEventName(), listener.getAction(), listener.isInvokeOnce()); + } + setObject(object); + this.setNameableCreator(new EventCreator(Widget.EVENT_STATECHANGE, EventPropertyTable.WidgetEventListenerUpdatePane.class)); + } + + @Override + public void updateBean(Object bean) { + setObject((Listener) bean); + } + + public void save() { + listener.setEventName(getObject().getEventName()); + listener.setAction(getObject().getAction()); + listener.setInvokeOnce(getObject().isInvokeOnce()); + listener.setTargetWidget(getObject().getTargetWidget()); + } +} diff --git a/designer-realize/src/main/java/com/fr/design/share/effect/StackAndAxisConditionEffectItem.java b/designer-realize/src/main/java/com/fr/design/share/effect/StackAndAxisConditionEffectItem.java new file mode 100644 index 000000000..a4b8804ae --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/effect/StackAndAxisConditionEffectItem.java @@ -0,0 +1,73 @@ +package com.fr.design.share.effect; + +import com.fr.chart.chartglyph.ConditionAttr; +import com.fr.design.share.effect.source.SourceNode; +import com.fr.plugin.chart.attr.DefaultAxisHelper; +import com.fr.plugin.chart.attr.plot.VanChartRectanglePlot; +import com.fr.plugin.chart.base.AttrSeriesStackAndAxis; +import com.fr.van.chart.column.VanChartCustomStackAndAxisConditionPane; +import com.fr.van.chart.designer.style.series.StackedAndAxisNameObjectCreator; + +public class StackAndAxisConditionEffectItem extends BaseEffectItem { + private ConditionAttr condition; + private VanChartRectanglePlot plot; + + public StackAndAxisConditionEffectItem(ConditionAttr condition, SourceNode sourceNode, VanChartRectanglePlot plot) { + this.condition = condition; + this.plot = plot; + this.setSourceNode(sourceNode); + + init(); + } + + private void init() { + setAxisNamesArray(condition); + + ConditionAttr object; + try { + object = (ConditionAttr) condition.clone(); + } catch (CloneNotSupportedException e) { + object = new ConditionAttr(); + object.setName(condition.getName()); + object.setCondition(condition.getCondition()); + for (int i = 0; i < condition.getDataSeriesConditionCount(); i++) { + object.addDataSeriesCondition(condition.getDataSeriesCondition(i)); + } + } + setObject(object); + + this.setName(condition.getName()); + this.setNameableCreator(new StackedAndAxisNameObjectCreator(new AttrSeriesStackAndAxis(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Stack_And_Series"), ConditionAttr.class, VanChartCustomStackAndAxisConditionPane.class)); + } + + @Override + public void setName(String name) { + super.setName(name); + getObject().setName(name); + } + + @Override + public void updateBean(Object bean) { + ConditionAttr conditionAttr = (ConditionAttr) bean; + conditionAttr.setName(getName()); + setAxisNamesArray(conditionAttr); + setObject(conditionAttr); + } + + public void save() { + condition.setName(getObject().getName()); + condition.setCondition(getObject().getCondition()); + condition.removeAll(); + for (int i = 0; i < getObject().getDataSeriesConditionCount(); i++) { + condition.addDataSeriesCondition(getObject().getDataSeriesCondition(i)); + } + } + + private void setAxisNamesArray(ConditionAttr conditionAttr) { + String[] axisXNames = DefaultAxisHelper.getXAxisNames(plot); + String[] axisYNames = DefaultAxisHelper.getYAxisNames(plot); + AttrSeriesStackAndAxis stackAndAxis = (AttrSeriesStackAndAxis) conditionAttr.getExisted(AttrSeriesStackAndAxis.class); + stackAndAxis.setXAxisNamesArray(axisXNames); + stackAndAxis.setYAxisNameArray(axisYNames); + } +} diff --git a/designer-realize/src/main/java/com/fr/design/share/effect/VanChartAlertValueEffectItem.java b/designer-realize/src/main/java/com/fr/design/share/effect/VanChartAlertValueEffectItem.java new file mode 100644 index 000000000..349ec91eb --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/effect/VanChartAlertValueEffectItem.java @@ -0,0 +1,94 @@ +package com.fr.design.share.effect; + +import com.fr.design.share.effect.source.SourceNode; +import com.fr.plugin.chart.attr.DefaultAxisHelper; +import com.fr.plugin.chart.attr.axis.VanChartAlertValue; +import com.fr.plugin.chart.attr.axis.VanChartAxis; +import com.fr.plugin.chart.attr.plot.VanChartRectanglePlot; +import com.fr.van.chart.designer.style.background.ChartNameObjectCreator; +import com.fr.van.chart.designer.style.background.VanChartAlertValuePane; + +import java.util.List; + +public class VanChartAlertValueEffectItem extends BaseEffectItem { + private VanChartAlertValue alertValue; + private VanChartRectanglePlot plot; + + public VanChartAlertValueEffectItem(VanChartAlertValue alertValue, SourceNode sourceNode, VanChartRectanglePlot plot) { + this.alertValue = alertValue; + this.plot = plot; + this.setSourceNode(sourceNode); + init(); + } + + private void init() { + List xAxisList = plot.getXAxisList(); + List yAxisList = plot.getYAxisList(); + String[] axisNames = DefaultAxisHelper.getAllAxisNames(plot); + for (VanChartAxis axis : xAxisList) { + List values = axis.getAlertValues(); + for (VanChartAlertValue alertValue : values) { + alertValue.setAxisNamesArray(axisNames); + alertValue.setAxisName(plot.getXAxisName(axis)); + } + } + for (VanChartAxis axis : yAxisList) { + List values = axis.getAlertValues(); + for (VanChartAlertValue alertValue : values) { + alertValue.setAxisNamesArray(axisNames); + alertValue.setAxisName(plot.getYAxisName(axis)); + } + } + + VanChartAlertValue object; + try{ + object = (VanChartAlertValue) alertValue.clone(); + }catch (CloneNotSupportedException e) { + object = new VanChartAlertValue(); + object.setAxisNamesArray(alertValue.getAxisNamesArray()); + object.setAxisName(alertValue.getAxisName()); + object.setAlertContentFormula(alertValue.getAlertContentFormula()); + object.setAlertContent(alertValue.getAlertContent()); + object.setAlertPosition(alertValue.getAlertPosition()); + object.setAlertValueFormula(alertValue.getAlertValueFormula()); + object.setAlertFont(alertValue.getAlertFont()); + object.setAlertLineAlpha(alertValue.getAlertLineAlpha()); + object.setAlertPaneSelectName(alertValue.getAlertPaneSelectName()); + object.setLineColor(alertValue.getLineColor()); + object.setLineStyle(alertValue.getLineStyle()); + } + setObject(object); + + this.setName(alertValue.getAlertPaneSelectName()); + this.setNameableCreator(new ChartNameObjectCreator(axisNames, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Alert_Line"), VanChartAlertValue.class, VanChartAlertValuePane.class)); + } + + @Override + public void setName(String name) { + super.setName(name); + getObject().setAlertPaneSelectName(name); + } + + @Override + public void updateBean(Object bean) { + VanChartAlertValue alertValue = (VanChartAlertValue) bean; + alertValue.setAlertPaneSelectName(getName()); + setObject(alertValue); + } + + @Override + public void save() { + VanChartAlertValue object = getObject(); + alertValue.setAxisNamesArray(object.getAxisNamesArray()); + alertValue.setAxisName(object.getAxisName()); + alertValue.setAlertContentFormula(object.getAlertContentFormula()); + alertValue.setAlertContent(object.getAlertContent()); + alertValue.setAlertPosition(object.getAlertPosition()); + alertValue.setAlertValueFormula(object.getAlertValueFormula()); + alertValue.setAlertFont(object.getAlertFont()); + alertValue.setAlertLineAlpha(object.getAlertLineAlpha()); + alertValue.setAlertPaneSelectName(object.getAlertPaneSelectName()); + alertValue.setLineColor(object.getLineColor()); + alertValue.setLineStyle(object.getLineStyle()); + } +} diff --git a/designer-realize/src/main/java/com/fr/design/share/effect/source/BaseSourceNode.java b/designer-realize/src/main/java/com/fr/design/share/effect/source/BaseSourceNode.java new file mode 100644 index 000000000..feac2413b --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/effect/source/BaseSourceNode.java @@ -0,0 +1,42 @@ +package com.fr.design.share.effect.source; + +public class BaseSourceNode implements SourceNode { + private String path; + private SourceNode parent; + private T target; + + @Override + public String toString() { + if (getParent() != null) { + return getParent().toString() + "-" + path; + } + return path; + } + + @Override + public T getTarget() { + return target; + } + + public void setTarget(T target) { + this.target = target; + } + + @Override + public SourceNode getParent() { + return parent; + } + + @Override + public void setParent(SourceNode parent) { + this.parent = parent; + } + + public void setPath(String path) { + this.path = path; + } + + public String getPath() { + return path; + } +} diff --git a/designer-realize/src/main/java/com/fr/design/share/effect/source/CellSourceNode.java b/designer-realize/src/main/java/com/fr/design/share/effect/source/CellSourceNode.java new file mode 100644 index 000000000..52cff5251 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/effect/source/CellSourceNode.java @@ -0,0 +1,21 @@ +package com.fr.design.share.effect.source; + + +import com.fr.report.cell.DefaultTemplateCellElement; + +public class CellSourceNode extends BaseSourceNode { + + public CellSourceNode(DefaultTemplateCellElement cellElement) { + this(cellElement, null); + } + + public CellSourceNode(DefaultTemplateCellElement cellElement, SourceNode parent) { + this(cellElement, cellElement.toString(), parent); + } + + public CellSourceNode(DefaultTemplateCellElement cellElement, String path, SourceNode parent) { + this.setTarget(cellElement); + this.setPath(path); + this.setParent(parent); + } +} diff --git a/designer-realize/src/main/java/com/fr/design/share/effect/source/EventSourceNode.java b/designer-realize/src/main/java/com/fr/design/share/effect/source/EventSourceNode.java new file mode 100644 index 000000000..7f30a2d8a --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/effect/source/EventSourceNode.java @@ -0,0 +1,25 @@ +package com.fr.design.share.effect.source; + +import com.fr.form.ui.Widget; + +public class EventSourceNode extends BaseSourceNode { + static final private String DEFAULT_PATH = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Event"); + + public EventSourceNode(Widget widget) { + this(widget, DEFAULT_PATH, null); + } + + public EventSourceNode(Widget widget, String path) { + this(widget, path, null); + } + + public EventSourceNode(Widget widget, SourceNode parent) { + this(widget, DEFAULT_PATH, parent); + } + + public EventSourceNode(Widget widget, String path, SourceNode parent) { + this.setTarget(widget); + this.setPath(path); + this.setParent(parent); + } +} diff --git a/designer-realize/src/main/java/com/fr/design/share/effect/source/PlotSourceNode.java b/designer-realize/src/main/java/com/fr/design/share/effect/source/PlotSourceNode.java new file mode 100644 index 000000000..c4698fd24 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/effect/source/PlotSourceNode.java @@ -0,0 +1,31 @@ +package com.fr.design.share.effect.source; + +import com.fr.chart.chartattr.Plot; +import com.fr.design.ChartTypeInterfaceManager; +import com.fr.stable.StringUtils; + +public class PlotSourceNode extends BaseSourceNode { + + public PlotSourceNode(Plot plot) { + this(plot, StringUtils.EMPTY, null); + } + + public PlotSourceNode(Plot plot, SourceNode parent) { + this(plot, StringUtils.EMPTY, parent); + } + + public PlotSourceNode(Plot plot, String chartName) { + this(plot, chartName, null); + } + + public PlotSourceNode(Plot plot, String chartName, SourceNode parent) { + String path = ChartTypeInterfaceManager.getInstance().getName(plot.getPlotID()); + if (StringUtils.isNotEmpty(chartName)) { + path = path + "-" + chartName; + } + this.setPath(path); + this.setTarget(plot); + this.setParent(parent); + } + +} diff --git a/designer-realize/src/main/java/com/fr/design/share/effect/source/SourceNode.java b/designer-realize/src/main/java/com/fr/design/share/effect/source/SourceNode.java new file mode 100644 index 000000000..7094a6959 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/effect/source/SourceNode.java @@ -0,0 +1,14 @@ +package com.fr.design.share.effect.source; + + + +public interface SourceNode { + String toString(); + + T getTarget(); + + SourceNode getParent(); + + void setParent(SourceNode parent); +} + diff --git a/designer-realize/src/main/java/com/fr/design/share/effect/source/SourceNodeUtils.java b/designer-realize/src/main/java/com/fr/design/share/effect/source/SourceNodeUtils.java new file mode 100644 index 000000000..9d988710f --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/effect/source/SourceNodeUtils.java @@ -0,0 +1,34 @@ +package com.fr.design.share.effect.source; + +import com.fr.chart.chartattr.Plot; +import com.fr.form.ui.Widget; +import com.fr.report.cell.DefaultTemplateCellElement; + +public class SourceNodeUtils { + static public SourceNode createSourceNode(Widget widget, SourceNode parent) { + return new EventSourceNode(widget, parent); + } + + static public SourceNode createSourceNode(DefaultTemplateCellElement cellElement, SourceNode parent) { + return new CellSourceNode(cellElement, parent); + } + + + static public SourceNode createSourceNode(Plot plot, SourceNode parent) { + return new PlotSourceNode(plot, parent); + } + + static public SourceNode createSourceNode(Plot plot, String chartName, SourceNode parent) { + return new PlotSourceNode(plot, chartName, parent); + } + + static public SourceNode getCellSourceNode(SourceNode sourceNode) { + if (sourceNode instanceof CellSourceNode) { + return sourceNode; + } + if (sourceNode.getParent() != null) { + return getCellSourceNode(sourceNode.getParent()); + } + return null; + } +} diff --git a/designer-realize/src/main/java/com/fr/design/share/ui/config/ShareConfigContentPane.java b/designer-realize/src/main/java/com/fr/design/share/ui/config/ShareConfigContentPane.java new file mode 100644 index 000000000..fefb5649d --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/ui/config/ShareConfigContentPane.java @@ -0,0 +1,175 @@ +package com.fr.design.share.ui.config; + +import com.fr.design.gui.icontainer.UIScrollPane; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.layout.VerticalFlowLayout; +import com.fr.design.mainframe.share.ui.base.PlaceholderTextArea; +import com.fr.design.share.effect.EffectItem; +import com.fr.design.share.effect.EffectItemGroup; +import com.fr.design.share.effect.source.SourceNode; +import com.fr.design.share.effect.source.SourceNodeUtils; +import com.fr.design.share.ui.config.table.ExpandEffectTable; +import com.fr.design.share.ui.effect.PreviewPane; +import com.fr.form.ui.Widget; +import com.fr.grid.selection.CellSelection; +import com.fr.locale.InterProviderFactory; +import com.fr.report.cell.DefaultTemplateCellElement; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.JTable; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.event.ComponentEvent; +import java.awt.event.ComponentListener; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class ShareConfigContentPane extends JPanel { + private EffectItemGroup effectItemGroup; + private PreviewPane previewPane; + private String info; + private List expandEffectTables = new ArrayList<>(); + + public ShareConfigContentPane(EffectItemGroup effectItemGroup, String info) { + this.effectItemGroup = effectItemGroup; + this.info = info; + initComponent(); + } + + private void initComponent() { + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + JPanel leftPane = createLeftPane(); + JPanel rightPane = createRightPane(); + this.add(leftPane, BorderLayout.WEST); + this.add(rightPane, BorderLayout.CENTER); + } + + private JPanel createLeftPane() { + JPanel leftPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + leftPane.add(createPreviewPane(), BorderLayout.NORTH); + leftPane.add(createInfoPane(), BorderLayout.CENTER); + return leftPane; + } + + private JPanel createRightPane() { + JPanel rightPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + rightPane.setBorder(BorderFactory.createEmptyBorder(0, 3, 0, 0)); + rightPane.add(createEffectPane(), BorderLayout.CENTER); + return rightPane; + } + + private JPanel createPreviewPane() { + + JPanel pane= FRGUIPaneFactory.createTitledBorderPane(Toolkit.i18nText(Toolkit.i18nText("Fine-Design_Share_Preview"))); + previewPane = new PreviewPane(getWidget()); + pane.add(previewPane, BorderLayout.CENTER); + return pane; + } + + private JPanel createInfoPane() { + JPanel infoPane = FRGUIPaneFactory.createTitledBorderPane(Toolkit.i18nText("Fine-Design_Share_Introduce")); + PlaceholderTextArea textArea = new PlaceholderTextArea(); + textArea.setText(this.info); + textArea.setPlaceholder(Toolkit.i18nText("Fine-Design_Share_No_Introduction")); + textArea.setEditable(false); + UIScrollPane scrollPane = new UIScrollPane(textArea); + scrollPane.setPreferredSize(new Dimension(373, 176)); + infoPane.add(scrollPane, BorderLayout.CENTER); + return infoPane; + } + + private JPanel createEffectPane() { + JPanel effectPane = FRGUIPaneFactory.createTitledBorderPane(Toolkit.i18nText(Toolkit.i18nText("Fine-Design_Share_Effects"))); + JPanel effectContainer = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, VerticalFlowLayout.TOP,0, 0); + + EffectItemGroup effectItemGroup = getEffectItemGroup(); + LinkedHashMap> effectItemsMap = effectItemGroup.getEffectItemsWithClassify(); + + Set>> entrySet = effectItemsMap.entrySet(); + Iterator>> iterator = entrySet.iterator(); + + expandEffectTables.clear(); + while (iterator.hasNext()) { + Map.Entry> entry= iterator.next(); + String title = entry.getKey(); + List effectItems = entry.getValue(); + ExpandEffectTable expandEffectTable= new ExpandEffectTable(effectItems, title); + expandEffectTables.add(expandEffectTable); + JTable table = expandEffectTable.getTable(); + if (previewPane.isElementCaseEditor()) { + table.getSelectionModel().addListSelectionListener(new ListSelectionListener() { + @Override + public void valueChanged(ListSelectionEvent e) { + if (table.getSelectedRow() >= 0) { + EffectItem effectItem= effectItems.get(table.getSelectedRow()); + SourceNode cellSourceNode = SourceNodeUtils.getCellSourceNode(effectItem.getSourceNode()); + if (cellSourceNode != null) { + DefaultTemplateCellElement cellElement = (DefaultTemplateCellElement) cellSourceNode.getTarget(); + previewPane.getElementCasePane().setSelection(new CellSelection(cellElement.getColumn(), cellElement.getRow(), cellElement.getColumnSpan(), cellElement.getRowSpan())); + } + } + } + }); + } + effectContainer.add(expandEffectTable); + + } + + UIScrollPane scrollPane = new UIScrollPane(effectContainer); + scrollPane.setPreferredSize(new Dimension(465, 545)); + scrollPane.getViewport().addComponentListener(new ComponentListener() { + @Override + public void componentResized(ComponentEvent e) { + Component component = e.getComponent(); + if (component != null) { + for(ExpandEffectTable expandEffectTable : expandEffectTables) { + for(Component co : expandEffectTable.getComponents()) { + co.setPreferredSize(new Dimension(component.getWidth(), co.getHeight())); + co.setSize(new Dimension(component.getWidth(), co.getHeight())); + } + } + } + } + @Override + public void componentMoved(ComponentEvent e) { + + } + @Override + public void componentShown(ComponentEvent e) { + + } + @Override + public void componentHidden(ComponentEvent e) { + + } + }); + scrollPane.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0)); + + effectPane.add(scrollPane, BorderLayout.CENTER); + return effectPane; + } + + private Widget getWidget() { + return getEffectItemGroup().getWidget(); + } + + private EffectItemGroup getEffectItemGroup() { + return effectItemGroup; + } + + public void reset() { + if (previewPane.isElementCaseEditor() && (previewPane.getElementCasePane() != null)) { + previewPane.getElementCasePane().setSelection(new CellSelection(0, 0, 0, 0)); + } + } + +} diff --git a/designer-realize/src/main/java/com/fr/design/share/ui/config/ShareConfigPane.java b/designer-realize/src/main/java/com/fr/design/share/ui/config/ShareConfigPane.java new file mode 100644 index 000000000..fa5606fe8 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/ui/config/ShareConfigPane.java @@ -0,0 +1,239 @@ +package com.fr.design.share.ui.config; + +import com.fr.design.constants.UIConstants; +import com.fr.design.dialog.BasicDialog; +import com.fr.design.dialog.BasicPane; +import com.fr.design.dialog.DialogActionAdapter; +import com.fr.design.file.HistoryTemplateListCache; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.ibutton.UIButtonUI; +import com.fr.design.gui.icontainer.UIScrollPane; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.layout.VerticalFlowLayout; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.DesignerFrame; +import com.fr.design.mainframe.share.collect.ComponentCollector; +import com.fr.design.mainframe.share.ui.base.PlaceholderTextArea; +import com.fr.design.mainframe.share.util.ShareComponentUtils; +import com.fr.design.share.effect.EffectItemGroup; +import com.fr.design.share.utils.EffectItemUtils; +import com.fr.design.share.utils.ShareDialogUtils; +import com.fr.design.utils.gui.GUIPaintUtils; +import com.fr.form.ui.Widget; +import com.fr.form.ui.container.WTitleLayout; +import com.fr.locale.InterProviderFactory; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.border.Border; +import java.awt.BorderLayout; +import java.awt.CardLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Graphics2D; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.HashMap; +import java.util.List; + +public class ShareConfigPane extends BasicPane { + private static final Dimension DIALOG_SIZE = new Dimension(900, 680); + private static final Border DIALOG_BORDER = BorderFactory.createEmptyBorder(0, 6, 4, 6); + private static final Color EMPTY_TEXT_COLOR = new Color(51, 51, 51, 128); + + private Widget widget; + private List effectItemGroups; + private HashMap quickConfigContentPaneMap = new HashMap(); + + private BasicDialog dialog; + private int selectIndex = 0; + private CardLayout cardLayout; + private JPanel contentPane; + private UILabel nameLabel; + private UIButton preButton; + private UIButton nextButton; + + + + public ShareConfigPane(Widget widget) { + this.widget = widget; + effectItemGroups = EffectItemUtils.getEffectItemGroupsByWidget(widget); + initComponent(); + } + + private void initComponent() { + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + this.setBorder(DIALOG_BORDER); + this.setPreferredSize(DIALOG_SIZE); + + if (effectItemGroups.size() > 0) { + this.add(createNaviPane(), BorderLayout.NORTH); + this.add(createContentPane(), BorderLayout.CENTER); + } else { + this.add(createInfoPane(), BorderLayout.WEST); + this.add(createEffectEmptyPane(), BorderLayout.EAST); + } + + } + + private JPanel createNaviPane() { + JPanel naviPane = new JPanel(); + naviPane.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 0)); + naviPane.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 0)); + + preButton = new UIButton(Toolkit.i18nText("Fine-Design_Share_Prev")); + preButton.setPreferredSize(new Dimension(62, 20)); + preButton.setUI(disabledUIButtonUI); + preButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + quickConfigContentPaneMap.get(getSelectWidget().getWidgetName()).reset(); + selectIndex--; + TogglePage(); + } + }); + preButton.setEnabled(hasPreview()); + + nextButton = new UIButton(Toolkit.i18nText("Fine-Design_Share_Next")); + nextButton.setPreferredSize(new Dimension(62, 20)); + nextButton.setUI(disabledUIButtonUI); + nextButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + quickConfigContentPaneMap.get(getSelectWidget().getWidgetName()).reset(); + selectIndex++; + TogglePage(); + } + }); + nextButton.setEnabled(hasNext()); + + nameLabel = new UILabel(""); + nameLabel.setPreferredSize(new Dimension(nameLabel.getFont().getSize() * 20, 15)); + + naviPane.add(preButton); + naviPane.add(nextButton); + naviPane.add(nameLabel); + + return naviPane; + } + + private JPanel createContentPane() { + contentPane = new JPanel(); + cardLayout = new CardLayout(); + contentPane.setLayout(cardLayout); + addContent(); + return contentPane; + } + + private void addContent() { + ShareConfigContentPane content = new ShareConfigContentPane(getSelectEffectItemGroup(), getDescription()); + contentPane.add(getSelectWidget().getWidgetName(), content); + quickConfigContentPaneMap.put(getSelectWidget().getWidgetName(), content); + updateContent(); + } + + private void updateContent() { + cardLayout.show(contentPane, getSelectWidget().getWidgetName()); + nameLabel.setText(getSelectWidget().getWidgetName()); + nameLabel.setToolTipText(getSelectWidget().getWidgetName()); + } + + private void TogglePage() { + preButton.setEnabled(hasPreview()); + nextButton.setEnabled(hasNext()); + if (quickConfigContentPaneMap.containsKey(getSelectWidget().getWidgetName())) { + updateContent(); + } else { + addContent(); + } + } + + private JPanel createInfoPane() { + JPanel infoPane = FRGUIPaneFactory.createTitledBorderPane(Toolkit.i18nText("Fine-Design_Share_Introduce")); + PlaceholderTextArea textArea = new PlaceholderTextArea(); + textArea.setText(getDescription()); + textArea.setPlaceholder(Toolkit.i18nText("Fine-Design_Share_No_Introduction")); + textArea.setEditable(false); + UIScrollPane scrollPane = new UIScrollPane(textArea); + scrollPane.setPreferredSize(new Dimension(373, 176)); + infoPane.add(scrollPane, BorderLayout.CENTER); + return infoPane; + } + + private String getDescription() { + if (this.widget instanceof WTitleLayout) { + return ((WTitleLayout) this.widget).getBodyBoundsWidget().getWidget().getDescription(); + } + return this.widget.getDescription(); + } + + private JPanel createEffectEmptyPane() { + JPanel effectPane = FRGUIPaneFactory.createTitledBorderPane(Toolkit.i18nText("Fine-Design_Share_Effects")); + effectPane.setLayout(new VerticalFlowLayout(FlowLayout.CENTER,0 , 0)); + effectPane.setPreferredSize(new Dimension(480, 545)); + UILabel label = new UILabel(Toolkit.i18nText("Fine-Design_Share_Empty")); + label.setAlignmentX(Component.CENTER_ALIGNMENT); + label.setPreferredSize(new Dimension(480, 22)); + label.setHorizontalAlignment(UILabel.CENTER); + label.setForeground(EMPTY_TEXT_COLOR); + effectPane.add(label); + return effectPane; + } + + @Override + protected String title4PopupWindow() { + return Toolkit.i18nText("Fine-Design_Share_Help_Settings"); + } + + public void show() { + final DesignerFrame designerFrame = DesignerContext.getDesignerFrame(); + dialog = this.showWindowWithCustomSize(designerFrame, null, DIALOG_SIZE); + ShareDialogUtils.getInstance().setConfigDialog(dialog); + dialog.addDialogActionListener(new DialogActionAdapter() { + @Override + public void doOk() { + for(EffectItemGroup effectItemGroup : effectItemGroups) { + effectItemGroup.save(); + } + HistoryTemplateListCache.getInstance().getCurrentEditingTemplate().saveTemplate(); + ComponentCollector.getInstance().setHelpConfigUseInfo(ShareComponentUtils.getCurrentTemplateID(), ShareComponentUtils.getWidgetId(widget)); + } + }); + dialog.setVisible(true); + } + + private boolean hasPreview() { + return selectIndex > 0; + } + + private boolean hasNext() { + return selectIndex < effectItemGroups.size() - 1; + } + + private Widget getSelectWidget() { + return getSelectEffectItemGroup().getWidget(); + } + + private EffectItemGroup getSelectEffectItemGroup() { + return effectItemGroups.get(selectIndex); + } + + private UIButtonUI disabledUIButtonUI = new UIButtonUI() { + protected void doExtraPainting(UIButton b, Graphics2D g2d, int w, int h, String selectedRoles) { + if (!b.isEnabled()) { + GUIPaintUtils.fillPaint(g2d, 0, 0, w, h, b.isRoundBorder(), b.getRectDirection(), new Color(240, 240, 241), UIConstants.ARC); + } else if (isPressed(b) && b.isPressedPainted()) { + GUIPaintUtils.fillPressed(g2d, 0, 0, w, h, b.isRoundBorder(), b.getRectDirection(), b.isDoneAuthorityEdited(selectedRoles)); + } else if (isRollOver(b)) { + GUIPaintUtils.fillRollOver(g2d, 0, 0, w, h, b.isRoundBorder(), b.getRectDirection(), b.isDoneAuthorityEdited(selectedRoles), b.isPressedPainted()); + } else if (b.isNormalPainted()) { + GUIPaintUtils.fillNormal(g2d, 0, 0, w, h, b.isRoundBorder(), b.getRectDirection(), b.isDoneAuthorityEdited(selectedRoles), b.isPressedPainted()); + } + } + }; + +} diff --git a/designer-realize/src/main/java/com/fr/design/share/ui/config/table/ConfigItemRender.java b/designer-realize/src/main/java/com/fr/design/share/ui/config/table/ConfigItemRender.java new file mode 100644 index 000000000..1d8874afa --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/ui/config/table/ConfigItemRender.java @@ -0,0 +1,87 @@ +package com.fr.design.share.ui.config.table; + +import com.fr.base.BaseUtils; +import com.fr.design.i18n.Toolkit; +import com.fr.locale.InterProviderFactory; +import com.fr.stable.StringUtils; + +import javax.swing.BorderFactory; +import javax.swing.Icon; +import javax.swing.JComponent; +import javax.swing.JTable; +import javax.swing.border.Border; +import javax.swing.table.DefaultTableCellRenderer; +import java.awt.Color; +import java.awt.Component; +import java.awt.Cursor; + +public class ConfigItemRender extends DefaultTableCellRenderer { + static final private Color PLACEHOLDER_COLOR = new Color(193, 193, 193); + static final private Color NO_EDITABLE_BG = new Color(240, 240, 241); + + static final private Border DEFAULT_NO_FOCUS_BORDER = BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(1, 5, 1, 5), BorderFactory.createEmptyBorder(0, 4, 0, 4)); + static final private Border SELECTED_BORDER = BorderFactory.createLineBorder(new Color(160,190,240)); + + private final Icon editIcon = BaseUtils.readIcon("com/fr/base/images/share/edit.png"); + + public ConfigItemRender() { + super(); + setBorder(DEFAULT_NO_FOCUS_BORDER); + } + + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + setText(StringUtils.EMPTY); + setToolTipText(null); + setBorder(DEFAULT_NO_FOCUS_BORDER); + setBackground(null); + setForeground(null); + setIcon(null); + setAlignmentX(JComponent.LEFT_ALIGNMENT); + + if (column == 2) { + setIcon(editIcon); + setAlignmentX(JComponent.CENTER_ALIGNMENT); + return this; + } + + if (value == null) { + return this; + } + + if (StringUtils.isNotEmpty(value.toString())) { + setValue(value); + } + setForeground(Color.black); + + if (column == 1) { + if (!table.isCellEditable(row, column)) { + setForeground(PLACEHOLDER_COLOR); + setBackground(NO_EDITABLE_BG); + setToolTipText(Toolkit.i18nText("Fine-Design_Share_Not_Support_Rename")); + } + if (StringUtils.isEmpty(value.toString())) { + setValue(Toolkit.i18nText("Fine-Design_Share_Need_Rename")); + setForeground(PLACEHOLDER_COLOR); + } + } + + if (table.getSelectedRow() == row && table.getSelectedColumn() == column && table.isCellEditable(row, column) ) { + setBorder(SELECTED_BORDER); + setBackground(null); + table.setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR)); + } else { + if (isSelected) { + setBackground(table.getSelectionBackground()); + } + table.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + } + + return this; + } + + + public void setValue(Object value) { + super.setValue(value); + setToolTipText((value == null) ? null : value.toString()); + } +} diff --git a/designer-realize/src/main/java/com/fr/design/share/ui/config/table/ConfigTableModel.java b/designer-realize/src/main/java/com/fr/design/share/ui/config/table/ConfigTableModel.java new file mode 100644 index 000000000..29fe8e125 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/ui/config/table/ConfigTableModel.java @@ -0,0 +1,70 @@ +package com.fr.design.share.ui.config.table; + +import com.fr.design.share.effect.EffectItem; +import com.fr.design.share.effect.ListenerEffectItem; + +import javax.swing.table.AbstractTableModel; +import java.util.List; + +public class ConfigTableModel extends AbstractTableModel { + private Object[] columnNames; + private List effectItems; + + public ConfigTableModel(List effectItems, Object[] columnNames) { + this.effectItems = effectItems; + this.columnNames = columnNames; + } + @Override + public int getRowCount() { + return this.effectItems.size(); + } + + @Override + public int getColumnCount() { + return this.columnNames.length; + } + + @Override + public String getColumnName(int columnIndex) { + if (columnNames == null) { + return null; + } + return columnNames[columnIndex].toString(); + } + + @Override + public Class getColumnClass(int columnIndex) { + return ConfigTableModel.class; + } + + @Override + public boolean isCellEditable(int rowIndex, int columnIndex) { + EffectItem effectItem = effectItems.get(rowIndex); + return columnIndex == 1 && !(effectItem instanceof ListenerEffectItem); + } + + @Override + public Object getValueAt(int rowIndex, int columnIndex) { + if (rowIndex >= getRowCount() || columnIndex >= getColumnCount()) { + return null; + } + EffectItem effectItem = effectItems.get(rowIndex); + if (columnIndex == 0) { + return effectItem.getConfigPath(); + } else if (columnIndex == 1) { + return effectItem.getName(); + } + return null; + } + + @Override + public void setValueAt(Object aValue, int rowIndex, int columnIndex) { + if (rowIndex >= effectItems.size() || columnIndex >= getColumnCount()) { + return; + } + EffectItem effectItem = effectItems.get(rowIndex); + if (columnIndex == 1) { + effectItem.setName(aValue.toString()); + } + } +} diff --git a/designer-realize/src/main/java/com/fr/design/share/ui/config/table/ExpandEffectTable.java b/designer-realize/src/main/java/com/fr/design/share/ui/config/table/ExpandEffectTable.java new file mode 100644 index 000000000..1479d8437 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/ui/config/table/ExpandEffectTable.java @@ -0,0 +1,163 @@ +package com.fr.design.share.ui.config.table; + +import com.fr.design.dialog.DialogActionAdapter; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.layout.VerticalFlowLayout; +import com.fr.design.share.effect.EffectItem; +import com.fr.design.share.ui.effect.EffectControlUpdatePane; +import com.fr.design.share.ui.effect.EffectPopupEditDialog; +import com.fr.design.share.ui.table.EffectItemEditor; +import com.fr.design.share.utils.ShareDialogUtils; +import com.fr.general.IOUtils; +import com.fr.locale.InterProviderFactory; + +import javax.swing.BorderFactory; +import javax.swing.Icon; +import javax.swing.JPanel; +import javax.swing.JTable; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Toolkit; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseMotionAdapter; +import java.util.List; + +public class ExpandEffectTable extends JPanel { + private static final Icon downIcon = IOUtils.readIcon("com/fr/base/images/share/arrow_down.png"); + private static final Icon rightIcon = IOUtils.readIcon("com/fr/base/images/share/arrow_left.png"); + private static final int WIDTH = 460; + private List effectItems; + private String title; + private boolean expand; + private UILabel arrow; + private JPanel contentPane; + private EffectPopupEditDialog effectPopupEditDialog; + private EffectControlUpdatePane effectControlUpdatePane; + private JTable table; + + public ExpandEffectTable(List effectItems, String title) { + this.effectItems = effectItems; + this.title = title; + + initComponent(); + } + + private void initComponent() { + VerticalFlowLayout layout = new VerticalFlowLayout(VerticalFlowLayout.TOP, 0, 4); + this.setLayout(layout); + this.expand = true; + + JPanel headerPane = createHeader(); + contentPane = createContent(); + + this.add(headerPane); + this.add(contentPane); + + this.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + setExpand(!expand); + } + }); + } + + private JPanel createHeader() { + JPanel headerPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + headerPane.setPreferredSize(new Dimension(WIDTH, 24)); + headerPane.setBackground(new Color(232,232,232)); + UILabel headerTitle = new UILabel(this.title); + headerTitle.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0)); + + arrow = new UILabel(downIcon); + arrow.setOpaque(false); + arrow.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5)); + + headerPane.add(headerTitle, BorderLayout.WEST); + headerPane.add(arrow, BorderLayout.EAST); + return headerPane; + } + + + private JPanel createContent() { + JPanel content = FRGUIPaneFactory.createBorderLayout_S_Pane(); + + // 效果列表 + Object[] columnNames = { + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Share_From"), + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Share_Rename"), + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Share_Edit") + }; + ConfigTableModel tableModel = new ConfigTableModel(effectItems, columnNames); + table = new JTable(tableModel); + + table.setRowHeight(24); + table.getColumnModel().getColumn(0).setPreferredWidth(180); + table.getColumnModel().getColumn(1).setPreferredWidth(252); + table.getColumnModel().getColumn(2).setPreferredWidth(33); + + table.setDefaultEditor(ConfigTableModel.class, new EffectItemEditor(table)); + table.setDefaultRenderer(ConfigTableModel.class, new ConfigItemRender()); + table.getTableHeader().setResizingAllowed(false); + table.getTableHeader().setReorderingAllowed(false); + table.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + int selectColumn = table.getSelectedColumn(); + if (selectColumn == 2) { + int selectRow = table.getSelectedRow(); + EffectItem selectEffectItem = effectItems.get(selectRow); + + effectControlUpdatePane = EffectControlUpdatePane.newInstance(selectEffectItem); + effectControlUpdatePane.populate(); + effectPopupEditDialog = EffectPopupEditDialog.newInstance(ShareDialogUtils.getInstance().getConfigDialog(), effectControlUpdatePane); + effectPopupEditDialog.setTitle(selectEffectItem.getName()); + Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); + effectPopupEditDialog.setLocation((d.width - effectPopupEditDialog.getSize().width) / 2, (d.height - effectPopupEditDialog.getSize().height) / 2); + effectPopupEditDialog.setVisible(true); + effectPopupEditDialog.addDialogActionListener(new DialogActionAdapter() { + @Override + public void doOk() { + effectControlUpdatePane.update(); + } + }); + } + } + public void mouseExited(MouseEvent e) { + int row = table.rowAtPoint(e.getPoint()); + int col = table.columnAtPoint(e.getPoint()); + if ((e.getPoint().getY() < 0) || row < 0 || col < 0) { + table.clearSelection(); + } + } + }); + table.addMouseMotionListener(new MouseMotionAdapter() { + @Override + public void mouseMoved(MouseEvent e) { + int row = table.rowAtPoint(e.getPoint()); + int col = table.columnAtPoint(e.getPoint()); + table.setRowSelectionInterval(row, row); + table.setColumnSelectionInterval(col, col); + } + }); + content.add(table.getTableHeader(), BorderLayout.NORTH); + content.add(table,BorderLayout.CENTER); + return content; + } + + public void setExpand(boolean isExpand) { + this.expand = isExpand; + arrow.setIcon(isExpand ? downIcon : rightIcon); + contentPane.setVisible(isExpand); + } + + public JTable getTable() { + return table; + } + + public boolean isExpand() { + return expand; + } +} diff --git a/designer-realize/src/main/java/com/fr/design/share/ui/effect/EffectControlUpdatePane.java b/designer-realize/src/main/java/com/fr/design/share/ui/effect/EffectControlUpdatePane.java new file mode 100644 index 000000000..46a9de7fb --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/ui/effect/EffectControlUpdatePane.java @@ -0,0 +1,85 @@ +package com.fr.design.share.ui.effect; + +import com.fr.design.DesignerEnvManager; +import com.fr.design.beans.BasicBeanPane; +import com.fr.design.data.tabledata.tabledatapane.GlobalMultiTDTableDataPane; +import com.fr.design.data.tabledata.tabledatapane.GlobalTreeTableDataPane; +import com.fr.design.data.tabledata.tabledatapane.MultiTDTableDataPane; +import com.fr.design.data.tabledata.tabledatapane.TreeTableDataPane; +import com.fr.design.env.DesignerWorkspaceInfo; +import com.fr.design.env.RemoteDesignerWorkspaceInfo; +import com.fr.design.gui.controlpane.NameableCreator; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.share.effect.EffectItem; +import com.fr.general.ComparatorUtils; +import com.fr.log.FineLoggerFactory; + +import javax.swing.JPanel; +import java.awt.BorderLayout; + +public class EffectControlUpdatePane extends JPanel { + private EffectItem effectItem; + private BasicBeanPane updatePane; + + private EffectControlUpdatePane(EffectItem effectItem) { + this.effectItem = effectItem; + initUpdatePane(); + } + + public static EffectControlUpdatePane newInstance(EffectItem effectItem) { + return new EffectControlUpdatePane(effectItem); + } + + private void initUpdatePane() { + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + NameableCreator creator = effectItem.creator(); + if (creator == null) { + return; + } else { + if (isMulti(creator.getUpdatePane()) || isTree(creator.getUpdatePane())) { + updatePane = effectItem.createPaneByCreators(creator, effectItem.getName()); + } else { + updatePane = effectItem.createPaneByCreators(creator); + } + this.add(updatePane, BorderLayout.CENTER); + } + } + + public void populate() { + try{ + updatePane.populateBean(effectItem.getPopulateBean()); + }catch (Exception e){ + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + } + + + public boolean isMulti(Class _class) { + return ComparatorUtils.equals(_class, GlobalMultiTDTableDataPane.class) || ComparatorUtils.equals(_class, MultiTDTableDataPane.class); + } + + public boolean isTree(Class _class) { + return ComparatorUtils.equals(_class, GlobalTreeTableDataPane.class) || ComparatorUtils.equals(_class, TreeTableDataPane.class); + } + + public void update() { + BasicBeanPane pane = updatePane; + if (pane != null && pane.isVisible()) { + Object bean = pane.updateBean(); + try { + if (bean instanceof RemoteDesignerWorkspaceInfo) { + DesignerWorkspaceInfo info = DesignerEnvManager.getEnvManager().getWorkspaceInfo(effectItem.getName()); + String remindTime = info.getRemindTime(); + ((RemoteDesignerWorkspaceInfo) bean).setRemindTime(remindTime); + } + }catch (Exception e){ + FineLoggerFactory.getLogger().info("remindTime is not exist"); + } + effectItem.updateBean(bean); + } + } + + public void checkValid() throws Exception { + updatePane.checkValid(); + } +} diff --git a/designer-realize/src/main/java/com/fr/design/share/ui/effect/EffectPopupEditDialog.java b/designer-realize/src/main/java/com/fr/design/share/ui/effect/EffectPopupEditDialog.java new file mode 100644 index 000000000..9abd9ba61 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/ui/effect/EffectPopupEditDialog.java @@ -0,0 +1,206 @@ +package com.fr.design.share.ui.effect; + +import com.fr.design.constants.UIConstants; +import com.fr.design.dialog.UIDialog; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.stable.StringUtils; + +import javax.swing.BorderFactory; +import javax.swing.JComponent; +import javax.swing.JDialog; +import javax.swing.JPanel; +import javax.swing.border.EmptyBorder; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Cursor; +import java.awt.Dialog; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Font; +import java.awt.GraphicsEnvironment; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Toolkit; +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; +import java.awt.event.MouseMotionListener; + +public class EffectPopupEditDialog extends UIDialog { + private JComponent editPane; + private PopupToolPane popupToolPane; + private UIButton okButton; + private static final int WIDTH = 570; + private static final int HEIGHT = 510; + + public EffectPopupEditDialog(Dialog parent, JComponent pane) { + super(parent); + setUndecorated(true); + pane.setBorder(BorderFactory.createEmptyBorder(20, 10, 10, 10)); + + this.editPane = pane; + JPanel editPaneWrapper = new JPanel(new BorderLayout()); + popupToolPane = new PopupToolPane(this); + editPaneWrapper.add(popupToolPane, BorderLayout.NORTH); + editPaneWrapper.add(editPane, BorderLayout.CENTER); + editPaneWrapper.setBorder(BorderFactory.createLineBorder(UIConstants.POP_DIALOG_BORDER, 1)); + editPaneWrapper.add(this.createControlButtonPane(), BorderLayout.SOUTH); + this.getContentPane().add(editPaneWrapper, BorderLayout.CENTER); + + setSize(WIDTH, HEIGHT); +// pack(); + this.setVisible(false); + } + + public static EffectPopupEditDialog newInstance(Dialog parent, JComponent pane) { + return new EffectPopupEditDialog(parent, pane); + } + + + @Override + public void setTitle(String title) { + popupToolPane.setTitle(title); + } + + + @Override + public void checkValid() throws Exception { + + } + + // 移动弹出编辑面板的工具条 + private class PopupToolPane extends JPanel { + private JDialog parentDialog; // 如果不在对话框中,值为null + private Color originColor; // 初始背景 + private JPanel contentPane; + private UILabel titleLabel; + private Point mouseDownCompCoords; // 存储按下左键的位置,移动对话框时会用到 + + private static final int MIN_X = -150; + private static final int MAX_X_SHIFT = 50; + private static final int MAX_Y_SHIFT = 50; + + private MouseListener mouseListener = new MouseAdapter() { + @Override + public void mouseExited(MouseEvent e) { + setCursor(Cursor.getDefaultCursor()); + if (mouseDownCompCoords == null) { + contentPane.setBackground(originColor); + } + repaint(); + } + + @Override + public void mouseReleased(MouseEvent e) { + mouseDownCompCoords = null; + if (!getBounds().contains(e.getPoint())) { + contentPane.setBackground(originColor); + } + } + + @Override + public void mousePressed(MouseEvent e) { + mouseDownCompCoords = e.getPoint(); + } + }; + + private MouseMotionListener mouseMotionListener = new MouseMotionListener() { + @Override + public void mouseMoved(MouseEvent e) { + setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR)); + contentPane.setBackground(UIConstants.POPUP_TITLE_BACKGROUND); + repaint(); + } + + @Override + public void mouseDragged(MouseEvent e) { + if (mouseDownCompCoords != null) { + Point currCoords = e.getLocationOnScreen(); + int x = currCoords.x - mouseDownCompCoords.x; + int y = currCoords.y - mouseDownCompCoords.y; + //屏幕可用区域 + Rectangle screen = GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds(); + + int minY = screen.y; + int maxX = Toolkit.getDefaultToolkit().getScreenSize().width - MAX_X_SHIFT; + int maxY = Toolkit.getDefaultToolkit().getScreenSize().height - MAX_Y_SHIFT; + if (x < MIN_X) { + x = MIN_X; + } else if (x > maxX) { + x = maxX; + } + if (y < minY) { + y = minY; + } else if (y > maxY) { + y = maxY; + } + // 移动到屏幕边缘时,需要校正位置 + parentDialog.setLocation(x, y); + } + } + }; + + PopupToolPane(JDialog parentDialog) { + this(StringUtils.EMPTY, parentDialog); + } + + PopupToolPane(String title, JDialog parentDialog) { + super(); + this.parentDialog = parentDialog; + originColor = UIConstants.DIALOG_TITLEBAR_BACKGROUND; + + contentPane = new JPanel(); + contentPane.setBackground(originColor); + contentPane.setLayout(new BorderLayout()); + titleLabel = new UILabel(title); + Font font = new Font("SimSun", Font.PLAIN, 12); + titleLabel.setFont(font); + contentPane.add(titleLabel, BorderLayout.WEST); + contentPane.setBorder(new EmptyBorder(5, 14, 6, 0)); + + setLayout(new BorderLayout()); + add(contentPane, BorderLayout.CENTER); + setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, UIConstants.TOOLBAR_BORDER_COLOR)); + + addMouseListener(mouseListener); + addMouseMotionListener(mouseMotionListener); + } + + public void setTitle(String title) { + titleLabel.setText(title); + } + + @Override + public Dimension getPreferredSize() { + return new Dimension(super.getPreferredSize().width, 28); + } + } + + private JPanel createControlButtonPane() { + JPanel controlPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + + JPanel buttonsPane = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 5)); + controlPane.add(buttonsPane, BorderLayout.EAST); + + //确定 + addOkButton(buttonsPane); + + return controlPane; + } + + private void addOkButton(JPanel buttonsPane) { + okButton = new UIButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_OK")); + okButton.setName(OK_BUTTON); + okButton.setMnemonic('O'); + buttonsPane.add(okButton); + okButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt) { + doOK(); + } + }); + } +} diff --git a/designer-realize/src/main/java/com/fr/design/share/ui/effect/PreviewPane.java b/designer-realize/src/main/java/com/fr/design/share/ui/effect/PreviewPane.java new file mode 100644 index 000000000..68cd025e3 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/ui/effect/PreviewPane.java @@ -0,0 +1,356 @@ +package com.fr.design.share.ui.effect; + +import com.fr.base.BaseUtils; +import com.fr.base.DynamicUnitList; +import com.fr.base.ScreenResolution; +import com.fr.base.chart.BaseChartCollection; +import com.fr.base.chart.chartdata.CallbackEvent; +import com.fr.common.inputevent.InputEventBaseOnOS; +import com.fr.design.cell.bar.DynamicScrollBar; +import com.fr.design.designer.creator.XCreator; +import com.fr.design.file.HistoryTemplateListCache; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.ElementCasePane; +import com.fr.design.mainframe.FormSelection; +import com.fr.design.mainframe.JForm; +import com.fr.design.mainframe.JTemplate; +import com.fr.design.mainframe.form.FormElementCaseDesigner; +import com.fr.design.mainframe.share.ui.base.ChartIcon; +import com.fr.design.utils.DesignUtils; +import com.fr.form.main.Form; +import com.fr.form.ui.ChartEditor; +import com.fr.form.ui.ElementCaseEditor; +import com.fr.form.ui.Widget; +import com.fr.general.IOUtils; +import com.fr.grid.Grid; +import com.fr.grid.GridUtils; +import com.fr.grid.selection.CellSelection; +import com.fr.report.ReportHelper; +import com.fr.report.worksheet.FormElementCase; + +import javax.swing.BorderFactory; +import javax.swing.Icon; +import javax.swing.ImageIcon; +import javax.swing.JPanel; +import javax.swing.JScrollBar; +import javax.swing.SwingConstants; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Cursor; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Image; +import java.awt.Point; +import java.awt.Toolkit; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseEvent; +import java.awt.event.MouseMotionAdapter; +import java.awt.event.MouseWheelEvent; +import java.awt.event.MouseWheelListener; +import java.awt.image.BufferedImage; + +public class PreviewPane extends JPanel implements CallbackEvent{ + public static final Cursor SCALE_CURSOR = Toolkit.getDefaultToolkit().createCustomCursor( + IOUtils.readImage("com/fr/base/images/share/scale.png"), + new Point(16, 16), "ScaleCursor"); + private static final Icon PLUS_ICON = BaseUtils.readIcon("com/fr/base/images/share/add.png"); + private static final Icon PLUS_CLICK_ICON = BaseUtils.readIcon("com/fr/base/images/share/add_click.png"); + private static final Icon PLUS_HOVER_ICON = BaseUtils.readIcon("com/fr/base/images/share/add_hover.png"); + private static final Icon PLUS_DISABLED_ICON = BaseUtils.readIcon("com/fr/base/images/share/add_disabled.png"); + private static final Icon MINUS_CLICK_ICON = BaseUtils.readIcon("com/fr/base/images/share/minus_click.png"); + private static final Icon MINUS_HOVER_ICON = BaseUtils.readIcon("com/fr/base/images/share/minus_hover.png"); + private static final Icon MINUS_ICON = BaseUtils.readIcon("com/fr/base/images/share/minus.png"); + private static final Icon MINUS_DISABLED_ICON = BaseUtils.readIcon("com/fr/base/images/share/minus_disabled.png"); + private static final Dimension BUTTON_SIZE = new Dimension(20, 20); + private static final Dimension PREVIEW_SIZE = new Dimension(373, 310); + private static final int MAX = 400; + private static final int HUND = 100; + private static final int MIN = 10; + private static final int DIR = 10; + private static final double MIN_TIME = 0.4; + + private Widget widget; + private UIButton plusButton; + private UIButton minusButton; + private JPanel preview; + private int scaleValue = 100; + private ElementCasePane elementCasePane; + private Image previewImage; + private int resolution; + private Dimension previewSize; + private boolean enabled; + + public PreviewPane(Widget widget) { + this(widget, PREVIEW_SIZE, true); + } + + public PreviewPane(Widget widget, Dimension previewSize, boolean enabled) { + this.widget = widget; + + this.enabled = enabled; + this.previewSize = previewSize; + this.resolution = ScreenResolution.getScreenResolution(); + initComponent(); + } + + + private void initComponent() { + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + + if (enabled) { + this.add(createTopToolbarPane(), BorderLayout.NORTH); + } else { + this.add(createRightToolbarPane(), BorderLayout.EAST); + } + this.add(createViewPane(), BorderLayout.CENTER); + + } + + private JPanel createTopToolbarPane() { + JPanel toolbarPane = FRGUIPaneFactory.createRightFlowInnerContainer_S_Pane(); + FlowLayout layout = new FlowLayout(FlowLayout.RIGHT, 10 ,0); + toolbarPane.setLayout(layout); + toolbarPane.setPreferredSize(new Dimension(previewSize.width, 22)); + addScaleButton(toolbarPane); + return toolbarPane; + } + + private JPanel createRightToolbarPane() { + JPanel toolbarPane = FRGUIPaneFactory.createRightFlowInnerContainer_S_Pane(); + FlowLayout layout = new FlowLayout(FlowLayout.LEFT, 10 ,0); + toolbarPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 0, 0)); + toolbarPane.setLayout(layout); + addScaleButton(toolbarPane); + return toolbarPane; + } + + private void addScaleButton(JPanel toolbarPane) { + if (isElementCaseEditor()) { + plusButton = new UIButton(PLUS_ICON); + plusButton.setDisabledIcon(PLUS_DISABLED_ICON); + plusButton.setPressedIcon(PLUS_CLICK_ICON); + plusButton.setRolloverIcon(PLUS_HOVER_ICON); + plusButton.setPreferredSize(BUTTON_SIZE); + plusButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + addScale(10); + } + }); + + minusButton = new UIButton(MINUS_ICON); + minusButton.setDisabledIcon(MINUS_DISABLED_ICON); + minusButton.setPressedIcon(MINUS_CLICK_ICON); + minusButton.setRolloverIcon(MINUS_HOVER_ICON); + minusButton.setPreferredSize(BUTTON_SIZE); + minusButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + addScale(-10); + } + }); + + toolbarPane.add(minusButton); + toolbarPane.add(plusButton); + } + } + + private JPanel createViewPane() { + preview = FRGUIPaneFactory.createBorderLayout_S_Pane(); + preview.setBorder(BorderFactory.createEmptyBorder(5, 0 , 0 , 0)); + preview.setPreferredSize(this.previewSize); + preview.setSize(previewSize); + + if (isElementCaseEditor()) { + elementCasePreview(); + } else if (isChartEditor()) { + chartPreview(); + } else { + widgetPreview(); + } + + return preview; + } + + private void elementCasePreview() { + ElementCaseEditor editor = (ElementCaseEditor) widget; + FormElementCase elementCase = (FormElementCase) editor.getElementCase(); + FormElementCaseDesigner designer = new FormElementCaseDesigner(elementCase, new Form()); + designer.setForeground(Color.BLACK); + designer.setBackground(new Color(245, 245, 247)); + designer.setFont(DesignUtils.getDefaultGUIFont().applySize(12)); + elementCasePane = designer.getEditingElementCasePane(); + + elementCasePane.setPreferredSize(new Dimension(previewSize.width, getInnerPreviewSize().height)); + elementCasePane.setSelection(new CellSelection(0, 0, 0, 0)); + + Grid grid = elementCasePane.getGrid(); + grid.setEditable(false); + grid.removeMouseWheelListener(grid.getGridMouseAdapter()); + grid.removeMouseMotionListener(grid.getGridMouseAdapter()); + grid.removeMouseListener(grid.getGridMouseAdapter()); + + grid.addMouseWheelListener(new MouseWheelListener() { + @Override + public void mouseWheelMoved(MouseWheelEvent e) { + if (!InputEventBaseOnOS.isControlDown(e)) { + ElementCasePane reportPane = grid.getElementCasePane(); + if (reportPane.isVerticalScrollBarVisible()) { + JScrollBar scrollBar = reportPane.getVerticalScrollBar(); + int maxValue = scrollBar.getModel().getMaximum(); + int newValue = reportPane.getVerticalScrollBar().getValue() + e.getWheelRotation(); + int extendValue = GridUtils.getExtentValue(newValue, elementCase.getRowHeightList_DEC(), grid.getHeight(), getResolution()); + if (extendValue <= maxValue) { + reportPane.getVerticalScrollBar().setValue(newValue); + } + } + } else { + int dir = e.getWheelRotation(); + addScale( - dir * DIR); + grid.setCursor(SCALE_CURSOR); + } + } + }); + + grid.addMouseMotionListener(new MouseMotionAdapter() { + @Override + public void mouseMoved(MouseEvent e) { + grid.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + } + }); + + elementCasePane.getGridColumn().setEnabled(false); + elementCasePane.getGridRow().setEnabled(false); + + preview.add(designer, BorderLayout.CENTER); + preview.add(elementCasePane.getHorizontalScrollBar(), BorderLayout.SOUTH); + } + + private Dimension getInnerPreviewSize() { + if (isElementCaseEditor()) { + int width = previewSize.width - (enabled ? elementCasePane.getVerticalScrollBar().getPreferredSize().width : 0); + int height = previewSize.height - (enabled ? elementCasePane.getHorizontalScrollBar().getPreferredSize().height : 0); + return new Dimension(width, height); + } + return previewSize; + } + + private void chartPreview() { + ChartEditor editor = (ChartEditor) widget; + BaseChartCollection chartCollection = editor.getChartCollection(); + ChartIcon chartIcon = new ChartIcon(chartCollection, previewSize.width, previewSize.height); + chartIcon.registerCallBackEvent(PreviewPane.this); + UILabel label = new UILabel(chartIcon); + preview.add(label, BorderLayout.CENTER); + } + + private void widgetPreview(){ + JPanel widgetView = new JPanel(FRGUIPaneFactory.createBorderLayout()); + widgetView.setPreferredSize(previewSize); + widgetView.setBackground(Color.WHITE); + + XCreator xCreator = getWidgetXCreator(); + if (xCreator != null) { + previewImage = new BufferedImage(xCreator.getWidth(), xCreator.getHeight(), BufferedImage.TYPE_INT_RGB); + xCreator.paint(previewImage.getGraphics()); + Icon icon = new ImageIcon(previewImage); + UILabel label = new UILabel(icon); + label.setAlignmentY(SwingConstants.CENTER); + widgetView.add(label, BorderLayout.CENTER); + } + + preview.add(widgetView, BorderLayout.CENTER); + } + + private XCreator getWidgetXCreator() { + JTemplate jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + FormSelection selection = ((JForm) jt).getFormDesign().getSelectionModel().getSelection(); + XCreator[] xCreators = selection.getSelectedCreators(); + return getWidgetXCreator(xCreators, widget); + } + private XCreator getWidgetXCreator(Component[] components, Widget widget) { + for (Component component : components) { + if (component instanceof XCreator) { + XCreator xCreator = (XCreator) component; + if (xCreator.toData().getWidgetName() == widget.getWidgetName()) { + return xCreator; + } + XCreator subXCreator = getWidgetXCreator(xCreator.getComponents(), widget); + if (subXCreator != null) { + return subXCreator; + } + } + } + return null; + } + + @Override + public void callback() { + this.repaint(); + } + + private void setScale(int resolution) { + //网格线 + if (resolution < ScreenResolution.getScreenResolution() * MIN_TIME) { + elementCasePane.getGrid().setShowGridLine(false); + } else { + elementCasePane.getGrid().setShowGridLine(true); + } + elementCasePane.setResolution(resolution); + elementCasePane.getGrid().getGridMouseAdapter().setResolution(resolution); + elementCasePane.getGrid().setResolution(resolution); + //更新Grid + Grid grid = elementCasePane.getGrid(); + DynamicUnitList rowHeightList = ReportHelper.getRowHeightList(elementCasePane.getEditingElementCase()); + DynamicUnitList columnWidthList = ReportHelper.getColumnWidthList(elementCasePane.getEditingElementCase()); + grid.setVerticalExtent(GridUtils.getExtentValue(0, rowHeightList, grid.getHeight(), resolution)); + grid.setHorizontalExtent(GridUtils.getExtentValue(0, columnWidthList, grid.getWidth(), resolution)); + elementCasePane.getGrid().updateUI(); + //更新Column和Row + ((DynamicScrollBar) elementCasePane.getVerticalScrollBar()).setDpi(resolution); + ((DynamicScrollBar) elementCasePane.getHorizontalScrollBar()).setDpi(resolution); + elementCasePane.getGridColumn().setResolution(resolution); + elementCasePane.getGridColumn().updateUI(); + elementCasePane.getGridRow().setResolution(resolution); + elementCasePane.getGridRow().updateUI(); + elementCasePane.repaint(); + } + + private void addScale(int step) { + scaleValue += step; + scaleValue = fixedScale(scaleValue); + plusButton.setEnabled(scaleValue < MAX); + minusButton.setEnabled(scaleValue > MIN); + setScale(getResolution()); + } + + private int fixedScale(int value) { + if (value < MIN) { + value = MIN; + } + if (value > MAX) { + value = MAX; + } + return value; + } + + private int getResolution() { + return (int) (resolution * scaleValue / HUND); + } + + public boolean isElementCaseEditor() { + return widget instanceof ElementCaseEditor; + } + + public boolean isChartEditor() { + return widget instanceof ChartEditor; + } + + public ElementCasePane getElementCasePane() { + return elementCasePane; + } +} diff --git a/designer-realize/src/main/java/com/fr/design/share/ui/generate/CoverUploadPane.java b/designer-realize/src/main/java/com/fr/design/share/ui/generate/CoverUploadPane.java new file mode 100644 index 000000000..01d0c06a0 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/ui/generate/CoverUploadPane.java @@ -0,0 +1,59 @@ +package com.fr.design.share.ui.generate; + +import com.fr.base.background.ImageBackground; +import com.fr.design.beans.BasicBeanPane; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.share.ui.base.ImageBackgroundPane; +import com.fr.log.FineLoggerFactory; + +import javax.swing.BorderFactory; +import javax.swing.border.Border; +import javax.swing.border.MatteBorder; +import javax.swing.plaf.ColorUIResource; +import java.awt.BorderLayout; +import java.awt.Image; + +/** + * 上传封面的面板 + * Coder: zack + * Date: 2016/10/11 + * Time: 21:36 + */ +public class CoverUploadPane extends BasicBeanPane { + private static final ColorUIResource BORDER_COLOR = new ColorUIResource(168, 172, 180); + private static final Border DIALOG_BORDER = BorderFactory.createEmptyBorder(0, 6, 4, 6); + private ImageBackgroundPane backgroundPane; + + @Override + protected String title4PopupWindow() { + return Toolkit.i18nText("Fine-Design_Share_Select_Upload_Cover"); + } + + public CoverUploadPane() { + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + backgroundPane = new ImageBackgroundPane(); + backgroundPane.setBorder(new MatteBorder(1, 1, 1, 1, BORDER_COLOR)); + this.add(backgroundPane, BorderLayout.CENTER); + this.setBorder(DIALOG_BORDER); + } + + @Override + public void populateBean(Image ob) { + if (ob != null) { + backgroundPane.populate(new ImageBackground(ob)); + } + } + + @Override + public Image updateBean() { + ImageBackground imageBackground = new ImageBackground(); + try { + imageBackground = (ImageBackground) backgroundPane.update(); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + //返回原图 + return imageBackground.getImage(); + } +} diff --git a/designer-realize/src/main/java/com/fr/design/share/ui/generate/EffectContent.java b/designer-realize/src/main/java/com/fr/design/share/ui/generate/EffectContent.java new file mode 100644 index 000000000..4fef5f51a --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/ui/generate/EffectContent.java @@ -0,0 +1,170 @@ +package com.fr.design.share.ui.generate; + +import com.fr.design.gui.icontainer.UIScrollPane; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.share.effect.EffectItem; +import com.fr.design.share.effect.EffectItemGroup; +import com.fr.design.share.ui.effect.PreviewPane; +import com.fr.design.share.ui.effect.EffectControlUpdatePane; +import com.fr.design.share.ui.effect.EffectPopupEditDialog; +import com.fr.design.share.ui.generate.table.EffectItemRender; +import com.fr.design.share.ui.generate.table.EffectTableModel; +import com.fr.design.share.ui.table.EffectItemEditor; +import com.fr.design.share.utils.ShareDialogUtils; +import com.fr.form.ui.Widget; +import com.fr.locale.InterProviderFactory; + +import javax.swing.BorderFactory; +import javax.swing.JComponent; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.JTree; +import javax.swing.event.TreeSelectionListener; +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Toolkit; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseMotionAdapter; +import java.util.List; + +public class EffectContent extends JPanel { + static final private Dimension PREVIEW_SIZE = new Dimension(340, 120); + + private EffectItemGroup effectItemGroup; + private EffectPopupEditDialog effectPopupEditDialog; + private EffectControlUpdatePane effectControlUpdatePane; + + public EffectContent(EffectItemGroup effectItemGroup) { + this.effectItemGroup = effectItemGroup; + this.init(); + } + + private void init() { + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + + if (getEffectItems().size() > 0) { + // 预览图 + JPanel imageContainer = FRGUIPaneFactory.createLeftFlowZeroGapBorderPane(); + PreviewPane previewPane = new PreviewPane(getWidget(), PREVIEW_SIZE, false); + imageContainer.add(previewPane); + this.add(imageContainer, BorderLayout.NORTH); + + // 效果列表 + Object[] columnNames = {com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Share_From"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Share_Rename")}; + JTable table = new JTable(new EffectTableModel(effectItemGroup, columnNames)); + table.setRowHeight(25); + table.getColumnModel().getColumn(0).setPreferredWidth(235); + table.getColumnModel().getColumn(1).setPreferredWidth(325); + + + table.setDefaultEditor(EffectTableModel.class, new EffectItemEditor(table)); + table.setDefaultRenderer(EffectTableModel.class, new EffectItemRender()); + table.getTableHeader().setResizingAllowed(false); + table.getTableHeader().setReorderingAllowed(false); + table.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + int selectColumn = table.getSelectedColumn(); + if (selectColumn == 0) { + int selectRow = table.getSelectedRow(); + EffectItem selectEffectItem = getEffectItems().get(selectRow); + effectControlUpdatePane = EffectControlUpdatePane.newInstance(selectEffectItem); + effectControlUpdatePane.populate(); + setPaneDisabled(effectControlUpdatePane); + effectPopupEditDialog = EffectPopupEditDialog.newInstance(ShareDialogUtils.getInstance().getShareDialog(), effectControlUpdatePane); + effectPopupEditDialog.setTitle(selectEffectItem.getName()); + Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); + effectPopupEditDialog.setLocation((d.width - effectPopupEditDialog.getSize().width) / 2, (d.height - effectPopupEditDialog.getSize().height) / 2); + effectPopupEditDialog.setVisible(true); + } + } + public void mouseExited(MouseEvent e) { + int tableContentHeight = table.getParent().getHeight() - table.getTableHeader().getHeight(); + if ((e.getPoint().getY() < 0) || (e.getPoint().getY() > tableContentHeight)) { + table.clearSelection(); + } + int row = table.rowAtPoint(e.getPoint()); + int col = table.columnAtPoint(e.getPoint()); + if (row < 0 || col < 0) { + table.clearSelection(); + } + } + }); + table.addMouseMotionListener(new MouseMotionAdapter() { + @Override + public void mouseMoved(MouseEvent e) { + int row = table.rowAtPoint(e.getPoint()); + int col = table.columnAtPoint(e.getPoint()); + table.setRowSelectionInterval(row, row); + table.setColumnSelectionInterval(col, col); + } + }); + +// if (previewPane.isElementCaseEditor()) { +// table.getSelectionModel().addListSelectionListener(new ListSelectionListener() { +// @Override +// public void valueChanged(ListSelectionEvent e) { +// if (table.getSelectedRow() >= 0) { +// EffectItem effectItem= getEffectItems().get(table.getSelectedRow()); +// SourceNode cellSourceNode = SourceNodeUtils.getCellSourceNode(effectItem.getSourceNode()); +// if (cellSourceNode != null) { +// DefaultTemplateCellElement cellElement = (DefaultTemplateCellElement) cellSourceNode.getTarget(); +// previewPane.getElementCasePane().setSelection(new CellSelection(cellElement.getColumn(), cellElement.getRow(), cellElement.getColumnSpan(), cellElement.getRowSpan())); +// } +// } +// } +// }); +// } + + JPanel tableContainer = FRGUIPaneFactory.createBorderLayout_S_Pane(); + tableContainer.setBorder(BorderFactory.createEmptyBorder(10,0,5,0)); + if (getEffectItems().size() > 5) { + UIScrollPane scrollPane = new UIScrollPane(table); + scrollPane.setPreferredSize(new Dimension(550, 160)); + tableContainer.add(scrollPane, BorderLayout.CENTER); + } else { + JPanel tablePane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + tablePane.add(table.getTableHeader(), BorderLayout.NORTH); + tablePane.add(table, BorderLayout.CENTER); + tableContainer.add(tablePane, BorderLayout.CENTER); + } + this.add(tableContainer, BorderLayout.CENTER); + + } + } + + private List getEffectItems() { + return effectItemGroup.getEffectItems(); + } + + private Widget getWidget() { + return effectItemGroup.getWidget(); + } + + private void setPaneDisabled(Component component) { + if (component instanceof JScrollPane) { + JScrollPane pane = (JScrollPane) component; + setPaneDisabled(pane.getViewport().getView()); + return; + } + if (component instanceof JTree) { + JTree tree = (JTree) component; + TreeSelectionListener[] treeSelectionListeners = tree.getTreeSelectionListeners(); + for (TreeSelectionListener treeSelectionListener : treeSelectionListeners) { + tree.removeTreeSelectionListener(treeSelectionListener); + } + return; + } + component.setEnabled(false); + if (component instanceof JComponent) { + Component[] components = ((JComponent) component).getComponents(); + for (Component co : components) { + setPaneDisabled(co); + } + } + } + +} diff --git a/designer-realize/src/main/java/com/fr/design/share/ui/generate/EffectPane.java b/designer-realize/src/main/java/com/fr/design/share/ui/generate/EffectPane.java new file mode 100644 index 000000000..f5ebd5edc --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/ui/generate/EffectPane.java @@ -0,0 +1,147 @@ +package com.fr.design.share.ui.generate; + +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.share.ui.base.PageableButton; +import com.fr.design.share.effect.EffectItemGroup; +import com.fr.form.ui.Widget; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.SwingConstants; +import javax.swing.plaf.basic.BasicArrowButton; +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.ArrayList; +import java.util.List; + + +public class EffectPane extends JPanel { + private List effectItemGroups; + private JPanel contentPane; + private int selectIndex = 0; + private BasicArrowButton previewButton; + private BasicArrowButton nextButton; + private UILabel nameLabel; + private List contents = new ArrayList<>(); + + + public EffectPane(List effectItemGroups) { + this.effectItemGroups = effectItemGroups; + if (effectItemGroups.size() > 0) { + initComponent(); + } + } + + private void initComponent() { + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + createContentPane(); + + JPanel rightPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + + JPanel headerPane = createHeaderPane(); + contentPane = createContentPane(); + addContent(); + rightPane.add(headerPane, BorderLayout.NORTH); + rightPane.add(contentPane, BorderLayout.CENTER); + this.add(rightPane, BorderLayout.CENTER); + } + + private JPanel createHeaderPane() { + JPanel headerPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + JPanel naviPane = createNaviPane(); + headerPane.add(naviPane, BorderLayout.EAST); + return headerPane; + } + + private JPanel createNaviPane() { + JPanel naviPane = new JPanel(FRGUIPaneFactory.createRightFlowLayout()); + nameLabel = new UILabel(""); + nameLabel.setPreferredSize(new Dimension(nameLabel.getFont().getSize() * 20, 15)); + nameLabel.setHorizontalAlignment(SwingConstants.RIGHT); + + previewButton = new PageableButton(SwingConstants.WEST) { + @Override + public Dimension getPreferredSize() { + return new Dimension(15, 15); + } + }; + previewButton.setEnabled(hasPreview()); + previewButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + selectIndex--; + EffectPane.this.TogglePage(); + } + }); + + nextButton = new PageableButton(SwingConstants.EAST) { + @Override + public Dimension getPreferredSize() { + return new Dimension(15, 15); + } + }; + nextButton.setEnabled(hasNext()); + nextButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + selectIndex++; + EffectPane.this.TogglePage(); + } + }); + + naviPane.add(nameLabel); + naviPane.add(previewButton); + naviPane.add(nextButton); + return naviPane; + } + + private JPanel createContentPane() { + JPanel contentPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + contentPane.setBorder(BorderFactory.createEmptyBorder(10, 0 , 0, 0)); + return contentPane; + } + + private void addContent() { + JPanel content = new EffectContent(getSelectEffectItemGroup()); + contents.add(selectIndex, content); + updateContent(); + } + + private Widget getSelectWidget() { + return getSelectEffectItemGroup().getWidget(); + } + + private EffectItemGroup getSelectEffectItemGroup() { + return effectItemGroups.get(selectIndex); + } + + private boolean hasPreview() { + return selectIndex > 0; + } + + private boolean hasNext() { + return selectIndex < effectItemGroups.size() - 1; + } + + private void TogglePage() { + previewButton.setEnabled(hasPreview()); + nextButton.setEnabled(hasNext()); + if (selectIndex < contents.size()) { + updateContent(); + } else { + addContent(); + } + } + + private void updateContent() { + // 添加contentPane + contentPane.removeAll(); + contentPane.add(contents.get(selectIndex)); + nameLabel.setText(getSelectWidget().getWidgetName()); + nameLabel.setToolTipText(getSelectWidget().getWidgetName()); + this.repaint(); + } +} diff --git a/designer-realize/src/main/java/com/fr/design/share/ui/generate/PriceExpectPane.java b/designer-realize/src/main/java/com/fr/design/share/ui/generate/PriceExpectPane.java new file mode 100644 index 000000000..7371c8e53 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/ui/generate/PriceExpectPane.java @@ -0,0 +1,87 @@ +package com.fr.design.share.ui.generate; + +import com.fr.design.gui.ibutton.UIRadioButton; +import com.fr.design.gui.itextfield.UITextField; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.stable.StringUtils; + +import javax.swing.ButtonGroup; +import javax.swing.JPanel; +import java.awt.Dimension; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/** + * Created by kerry on 2020-06-23 + */ +public class PriceExpectPane extends JPanel { + private static final int TEXT_FILED_WIDTH = 160; + private static final int TEXT_FILED_HEIGHT = 20; + private static final String FREE_PRICE = "0"; + private static final String PRICE_FORMAT = "%.2f"; + private UITextField priceFiled; + private UIRadioButton freeRadio; + private UIRadioButton chargeRadio; + + public PriceExpectPane() { + freeRadio = new UIRadioButton(Toolkit.i18nText("Fine-Design_Share_Price_Free")); + chargeRadio = new UIRadioButton(Toolkit.i18nText("Fine-Design_Share_Price_Charge")); + priceFiled = new UITextField(); + priceFiled.setPlaceholder(Toolkit.i18nText("Fine-Design_Share_Price_Charge_Tip")); + ButtonGroup radioGroup = new ButtonGroup(); + radioGroup.add(freeRadio); + radioGroup.add(chargeRadio); + this.setLayout(FRGUIPaneFactory.createBoxFlowLayout()); + this.add(freeRadio); + this.add(chargeRadio); + final JPanel panel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + panel.add(priceFiled); + this.add(panel); + panel.setPreferredSize(new Dimension(TEXT_FILED_WIDTH, TEXT_FILED_HEIGHT)); + panel.setVisible(false); + this.freeRadio.setSelected(true); + freeRadio.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + panel.setVisible(false); + + } + }); + chargeRadio.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + panel.setVisible(true); + } + }); + } + + public String getPrice() { + if (this.freeRadio.isSelected()) { + return FREE_PRICE; + } + float priceNumber = Float.parseFloat(this.priceFiled.getText()); + return String.format(PRICE_FORMAT, priceNumber); + } + + + public boolean check() { + if (freeRadio.isSelected()) { + return true; + } + String price = this.priceFiled.getText(); + if (StringUtils.isEmpty(price)) { + return false; + } + try { + float priceNumber = Float.parseFloat(price); + if (priceNumber <= 0) { + return false; + } + } catch (NumberFormatException e) { + return false; + } + return true; + } + +} diff --git a/designer-realize/src/main/java/com/fr/design/share/ui/generate/ShareGeneratePane.java b/designer-realize/src/main/java/com/fr/design/share/ui/generate/ShareGeneratePane.java new file mode 100644 index 000000000..82eb60f08 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/ui/generate/ShareGeneratePane.java @@ -0,0 +1,308 @@ +package com.fr.design.share.ui.generate; + +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.gui.icheckbox.UICheckBox; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.DesignerFrame; +import com.fr.design.mainframe.JTemplate; +import com.fr.design.mainframe.share.Bean.ComponentGenerateInfo; +import com.fr.design.mainframe.share.action.ShareUIAspect; +import com.fr.design.mainframe.share.collect.ComponentCollector; +import com.fr.design.mainframe.share.exception.LackOfValueException; +import com.fr.design.mainframe.share.generate.ComponentGeneratorCenter; +import com.fr.form.share.exception.NetWorkFailedException; +import com.fr.form.share.group.DefaultShareGroup; +import com.fr.design.mainframe.share.util.ShareUIUtils; +import com.fr.design.share.effect.EffectItemGroup; +import com.fr.design.share.utils.EffectItemUtils; +import com.fr.design.share.utils.ShareDialogUtils; +import com.fr.form.share.DefaultSharableWidget; +import com.fr.form.share.config.ComponentReuseConfigManager; +import com.fr.form.share.group.DefaultShareGroupManager; +import com.fr.form.share.Group; +import com.fr.form.share.record.ShareWidgetInfoManager; +import com.fr.form.ui.Widget; +import com.fr.log.FineLoggerFactory; +import com.fr.stable.StringUtils; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.SwingWorker; +import javax.swing.UIManager; +import javax.swing.border.Border; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import java.awt.BorderLayout; +import java.awt.CardLayout; +import java.awt.Dimension; +import java.awt.Image; +import java.awt.Rectangle; +import java.awt.event.ItemEvent; +import java.util.HashMap; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static javax.swing.JOptionPane.ERROR_MESSAGE; + +/** + * created by Harrison on 2020/04/20 + **/ +public class ShareGeneratePane extends BasicPane { + + private static final Dimension DIALOG_SIZE = new Dimension(670, 740); + private static final Dimension DIALOG_NORMAL_SIZE = new Dimension(670, 610); + private static final Border DIALOG_BORDER = BorderFactory.createEmptyBorder(0, 6, 4, 6); + + private JPanel mainPane = null; + private ShareMainPane uploadPane = null; + private ShareMainPane simplePane = null; + + private UICheckBox uploadCheckbox = null; + + private BasicDialog dialog; + + private final JTemplate jt; + //报表块控件 + private final Widget shareWidget; + //报表块数据集相关的参数 + private final HashMap paraMap; + + private List effectItemGroups; + + private final ShareUIAspect aspect; + + private final boolean supportUpload = ComponentReuseConfigManager.getInstance().supportUploadReu(); + + public ShareGeneratePane(JTemplate jt, Widget shareWidget, Rectangle rec, Image shareCover, HashMap paraMap, ShareUIAspect aspect) { + this.jt = jt; + this.shareWidget = shareWidget; + effectItemGroups = EffectItemUtils.getEffectItemGroupsByWidget(shareWidget); + this.paraMap = paraMap; + this.aspect = aspect; + + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + this.setBorder(DIALOG_BORDER); + this.setPreferredSize(getDialogSize()); + + JPanel guidePane = initGuidePane(shareCover, rec); + this.add(guidePane, BorderLayout.CENTER); + } + + private JPanel initGuidePane(Image shareCover, Rectangle rec) { + + JPanel pane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + + this.mainPane = FRGUIPaneFactory.createCardLayout_S_Pane(); + this.simplePane = new ShareMainPane(shareCover, rec, false, effectItemGroups); + this.uploadPane = new ShareMainPane(shareCover, rec, true, effectItemGroups); + //暂时换一下,目前不用上传 + this.mainPane.add(simplePane, ShareUIUtils.convertStateChange(ItemEvent.DESELECTED)); + this.mainPane.add(uploadPane, ShareUIUtils.convertStateChange(ItemEvent.SELECTED)); + + simplePane.getNameField().getDocument().addDocumentListener(new DocumentListener() { + + @Override + public void changedUpdate(DocumentEvent e) { + validInput(); + } + + @Override + public void insertUpdate(DocumentEvent e) { + validInput(); + } + + @Override + public void removeUpdate(DocumentEvent e) { + validInput(); + } + }); + + uploadPane.getNameField().getDocument().addDocumentListener(new DocumentListener() { + + @Override + public void changedUpdate(DocumentEvent e) { + validInput(); + } + + @Override + public void insertUpdate(DocumentEvent e) { + validInput(); + } + + @Override + public void removeUpdate(DocumentEvent e) { + validInput(); + } + }); + + //后面创建,因为需要依赖 mainPane 的创建 + JPanel uploadCheckBox = createUploadCheckBox(); + if (supportUpload) { + pane.add(uploadCheckBox, BorderLayout.NORTH); + } + pane.add(mainPane, BorderLayout.CENTER); + return pane; + } + + private void validInput() { + String userInput = getSelectMainPane().getNameField().getText().trim(); + + if (StringUtils.isEmpty(userInput)) { + dialog.setButtonEnabled(false); + } else { + dialog.setButtonEnabled(true); + } + } + + private JPanel createUploadCheckBox() { + + JPanel panel = FRGUIPaneFactory.createBoxFlowInnerContainer_S_Pane(); + String label = Toolkit.i18nText("Fine-Design_Share_Upload_Meanwhile"); + this.uploadCheckbox = new UICheckBox(label); + uploadCheckbox.addItemListener(e -> { + int stateChange = e.getStateChange(); + CardLayout cl = (CardLayout) (mainPane.getLayout()); + cl.show(mainPane, ShareUIUtils.convertStateChange(stateChange)); + repaint(); + }); + uploadCheckbox.setSelected(false); + + UILabel tipsLabel = ShareUIUtils.createTipsLabel(Toolkit.i18nText("Fine-Design_Share_Upload_Meanwhile_Tips")); + panel.add(uploadCheckbox); + panel.add(tipsLabel); + panel.setPreferredSize(new Dimension(585, 30)); + return panel; + } + + /* show 相关 */ + @Override + public void show() { + final DesignerFrame designerFrame = DesignerContext.getDesignerFrame(); + dialog = this.showWindowWithCustomSize(designerFrame, null, getDialogSize()); + dialog.setButtonEnabled(false); + ShareDialogUtils.getInstance().setShareDialog(dialog); + dialog.addDialogActionListener(new DialogActionAdapter() { + + @Override + public void doOk() { + ShareMainPane mainPane = getSelectMainPane(); + if (doCheck(mainPane)) { + dialog.setVisible(false); + doOk0(mainPane); + } else { + // 抛出,从而防止页面关闭 + throw new LackOfValueException(); + } + } + }); + dialog.setVisible(true); + } + + private ShareMainPane getSelectMainPane() { + + ShareMainPane mainPane; + if (uploadCheckbox.isSelected()) { + mainPane = uploadPane; + } else { + mainPane = simplePane; + } + return mainPane; + } + + private boolean doCheck(ShareMainPane mainPane) { + + return mainPane.check(); + } + + private void doOk0(final ShareMainPane mainPane) { + for(EffectItemGroup effectItemGroup : effectItemGroups) { + effectItemGroup.save(); + } + SwingWorker worker = new SwingWorker() { + @Override + protected Void doInBackground() throws Exception { + DefaultSharableWidget provider = mainPane.generate(); + Group selectGroup = mainPane.getSelectGroup(); + boolean success = false; + try { + success = generateModule(provider); + if (success) { + //先读文件然后移动到指定分组 + Group defaultGroup = DefaultShareGroupManager.getInstance().getGroup(DefaultShareGroup.GROUP_NAME); + if (defaultGroup != null) { + defaultGroup.loadModule(provider.getFileName()); + defaultGroup.moveModule(selectGroup, Stream.of(provider.getId()).collect(Collectors.toList())); + } + collect(provider); + ShareWidgetInfoManager.getInstance().addCompCreateInfo(provider); + } + } catch (NetWorkFailedException exception) { + FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), ShareUIUtils.formatWidthString(Toolkit.i18nText("Fine-Design_Share_NetWorkError"), 200), + Toolkit.i18nText("Fine-Design_Basic_Error"), ERROR_MESSAGE, UIManager.getIcon("OptionPane.errorIcon")); + return null; + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } finally { + //成功失败,都要处理 + aspect.afterOk(); + } + if (!success) { + FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Design_Share_Module_Failed"), + Toolkit.i18nText("Fine-Design_Basic_Error"), ERROR_MESSAGE, UIManager.getIcon("OptionPane.errorIcon")); + } + return null; + } + }; + worker.execute(); + } + + private void collect(DefaultSharableWidget provider) { + + ComponentCollector.getInstance().collectGenerateCmpNumber(); + ComponentCollector.getInstance().collectGenerateCmpRecord(provider); + if (uploadCheckbox.isSelected()) { + ComponentCollector.getInstance().collectUploadCmpNumber(); + } + } + + private boolean generateModule(DefaultSharableWidget info) throws Exception { + + DefaultSharableWidget transformInfo = transform(info); + ComponentGenerateInfo generateInfo = new ComponentGenerateInfo(uploadCheckbox.isSelected(), jt, paraMap, shareWidget, transformInfo); + ComponentGeneratorCenter center = new ComponentGeneratorCenter(generateInfo); + return center.generate(); + } + + private DefaultSharableWidget transform(DefaultSharableWidget info) { + + //先屏蔽 + //if (shareWidget instanceof AbstractBorderStyleWidget) { + // AbstractBorderStyleWidget styleWidget = (AbstractBorderStyleWidget) shareWidget; + // ExtendSharableAttrMark attrMark = styleWidget.getWidgetAttrMark(ExtendSharableAttrMark.XML_TAG); + // if (attrMark != null) { + // String shareId = attrMark.getShareId(); + // info.setId(shareId); + // } + //} + return info; + } + + + @Override + protected String title4PopupWindow() { + return Toolkit.i18nText("Fine-Design_Share_Module_Msg"); + } + + private Dimension getDialogSize() { + return effectItemGroups.size() > 0 ? DIALOG_SIZE : DIALOG_NORMAL_SIZE; + } + + +} diff --git a/designer-realize/src/main/java/com/fr/design/share/ui/generate/ShareLoginLabel.java b/designer-realize/src/main/java/com/fr/design/share/ui/generate/ShareLoginLabel.java new file mode 100644 index 000000000..14ad32415 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/ui/generate/ShareLoginLabel.java @@ -0,0 +1,50 @@ +package com.fr.design.share.ui.generate; + +import com.fr.config.MarketConfig; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.mainframe.bbs.UserInfoPane; +import com.fr.stable.StringUtils; + +import javax.swing.JPanel; + +/** + * created by Harrison on 2020/04/20 + **/ +public class ShareLoginLabel extends UILabel { + + private JPanel vendorPane; + + private UILabel unLoginLabel; + + private UILabel loginLabel; + + public ShareLoginLabel(JPanel vendorPane, UILabel unLoginLabel, UILabel loginLabel) { + this.vendorPane = vendorPane; + this.unLoginLabel = unLoginLabel; + this.loginLabel = loginLabel; + setVisible(false); + } + + @Override + public void setText(String text) { + super.setText(text); + if (StringUtils.isNotEmpty(text)) { + tryGetLogin(); + } + } + + private void tryGetLogin() { + + String bbsUsername = MarketConfig.getInstance().getBbsUsername(); + if (StringUtils.isNotEmpty(bbsUsername)) { + vendorPane.remove(unLoginLabel); + loginLabel.setText(bbsUsername); + vendorPane.add(loginLabel); + // 像这种 remove , 再 add 的, 需要 validate() + vendorPane.validate(); + vendorPane.repaint(); + //同步刷新页面 + UserInfoPane.getInstance().updateBBSUserInfo(); + } + } +} diff --git a/designer-realize/src/main/java/com/fr/design/share/ui/generate/ShareMainPane.java b/designer-realize/src/main/java/com/fr/design/share/ui/generate/ShareMainPane.java new file mode 100644 index 000000000..e9b5a25e2 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/ui/generate/ShareMainPane.java @@ -0,0 +1,702 @@ +package com.fr.design.share.ui.generate; + +import com.fr.config.MarketConfig; +import com.fr.design.constants.LayoutConstants; +import com.fr.design.dialog.BasicDialog; +import com.fr.design.dialog.DialogActionAdapter; +import com.fr.design.dialog.FineJOptionPane; +import com.fr.design.extra.LoginWebBridge; +import com.fr.design.extra.WebViewDlgHelper; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.icheckbox.UICheckBox; +import com.fr.design.gui.icombobox.UIComboBox; +import com.fr.design.gui.icombocheckbox.UIComboCheckBox; +import com.fr.design.gui.icontainer.UIScrollPane; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.gui.itextfield.UITextField; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.layout.TableLayout; +import com.fr.design.layout.TableLayoutHelper; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.share.constants.ComponentType; +import com.fr.design.mainframe.share.constants.ComponentTypes; +import com.fr.design.mainframe.share.constants.DisplayDevice; +import com.fr.design.mainframe.share.constants.StyleTheme; +import com.fr.design.mainframe.share.ui.base.DictionaryComboCheckBox; +import com.fr.design.mainframe.share.ui.base.LeftWordsTextArea; +import com.fr.design.mainframe.share.ui.base.PlaceholderTextArea; +import com.fr.design.mainframe.share.ui.base.ui.PlaceHolderUI; +import com.fr.design.mainframe.share.util.ShareUIUtils; +import com.fr.design.share.effect.EffectItemGroup; +import com.fr.design.share.utils.ShareDialogUtils; +import com.fr.form.share.DefaultSharableWidget; +import com.fr.form.share.bean.StyleThemeBean; +import com.fr.form.share.constants.ShareComponentConstants; +import com.fr.form.share.group.DefaultShareGroupManager; +import com.fr.form.share.Group; +import com.fr.plugin.context.PluginContext; +import com.fr.plugin.manage.PluginFilter; +import com.fr.plugin.manage.PluginManager; +import com.fr.stable.ArrayUtils; +import com.fr.stable.ProductConstants; +import com.fr.stable.StringUtils; +import com.fr.stable.collections.combination.Pair; +import com.fr.stable.pinyin.PinyinHelper; +import org.jetbrains.annotations.NotNull; + +import javax.swing.BorderFactory; +import javax.swing.Icon; +import javax.swing.ImageIcon; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.UIManager; +import javax.swing.border.MatteBorder; +import javax.swing.text.AttributeSet; +import javax.swing.text.BadLocationException; +import javax.swing.text.PlainDocument; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dialog; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Image; +import java.awt.ItemSelectable; +import java.awt.Rectangle; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.LinkedList; +import java.util.List; +import java.util.UUID; + +import static javax.swing.JOptionPane.ERROR_MESSAGE; + +/** + * created by Harrison on 2020/04/20 + **/ +public class ShareMainPane extends JPanel { + + private static final int COLUMN_ITEM_SIZE = 60; + private static final int COLUMN_FIELD_WIDTH = 555; + private static final int TEXT_FIELD_WIDTH = 160; + private static final int TEXT_FIELD_HEIGHT = 21; + private static final int NAME_MAX_LENGTH = 50; + private static final int GROUP_WIDTH = 160; + private static final int COMBO_WIDTH = 90; + private static final int COMBO_WIDTH_PLUS = 150; + private static final int COMBO_HEIGHT = 20; + private static final int BTN_WIDTH = 70; + private static final int BTN_HEIGHT = 20; + private static final int BASEPANE_VERTICAL_GAP = 2; + + private UIScrollPane mainPane = null; + + private UICheckBox pluginCheckBox = new UICheckBox(Toolkit.i18nText("Fine-Design_Share_Make_Relate_To_Plugin")); + private PriceExpectPane priceExpectPane = null; + + private UIComboBox parentClassify = null; + private UIComboBox childClassify = null; + + private UIComboBox localGroup = null; + + private UILabel loginLabel = ShareUIUtils.createCenterRightUILabel(StringUtils.EMPTY); + + private UICheckBox pc = new UICheckBox(Toolkit.i18nText("Fine-Design_Share_PC_Device")); + private UICheckBox mobile = new UICheckBox(Toolkit.i18nText("Fine-Design_Share_Mobile_Device")); + + private UIComboCheckBox pluginComboCheckBox = null; + + private UIComboBox styleComboBox = null; + + private UITextField nameField = new UITextField(); + + private PlaceholderTextArea content = new LeftWordsTextArea(); + + private PlaceholderTextArea help = new PlaceholderTextArea(); + private UILabel cover; + private UIButton uploadBtn; + //控件的缩略图 + private Image shareCover; + private Rectangle rec; + private boolean upload; + + private List effectItemGroups; + + public ShareMainPane(Image shareCover, Rectangle rec, boolean upload, List effectItemGroups) { + + this.shareCover = shareCover; + this.rec = rec; + this.upload = upload; + this.effectItemGroups = effectItemGroups; + + initCover(shareCover); + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + this.setBorder(BorderFactory.createEmptyBorder()); + + this.mainPane = createMainPane(upload); + this.add(this.mainPane, BorderLayout.CENTER); + } + + private void initCover(Image shareCover) { + this.cover = new UILabel(getShowIcon(shareCover)); + MatteBorder matteBorder = BorderFactory.createMatteBorder(3, 3, 3, 3, Color.WHITE); + this.cover.setBorder(matteBorder); + this.cover.setHorizontalAlignment(JLabel.CENTER); + } + + private Icon getShowIcon(Image image) { + Image scaleImage = image.getScaledInstance(ShareComponentConstants.SHARE_THUMB_WIDTH, ShareComponentConstants.SHARE_THUMB_HEIGHT, Image.SCALE_SMOOTH); + return new ImageIcon(scaleImage); + } + + + @NotNull + private UIScrollPane createMainPane(boolean upload) { + JPanel mainPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + UIScrollPane scrollPane = new UIScrollPane(mainPane); + JPanel overviewPane = createOverviewPane(upload); + JPanel basePane = createBasePane(upload); + mainPane.add(basePane, BorderLayout.NORTH); + mainPane.add(overviewPane, BorderLayout.CENTER); + return scrollPane; + } + + private JPanel createOverviewPane(boolean upload) { + JPanel componentPane = createComponentOverviewPane(upload); + String title = Toolkit.i18nText("Fine-Design_Share_Overview"); + JPanel overviewPane = FRGUIPaneFactory.createTitledBorderPane(title); + overviewPane.add(componentPane, BorderLayout.CENTER); + + return overviewPane; + + } + + private JPanel createBasePane(boolean upload) { + // 提示 + UILabel tipsLabel = ShareUIUtils.createTipsLabel(Toolkit.i18nText("Fine-Design_Share_Generate_Help_Tips")); + tipsLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 10, 0)); + // 组件名称 + UILabel nameLabel = ShareUIUtils.createTopRightUILabel(Toolkit.i18nText("Fine-Design_Share_Name")); + JPanel symbolTextField = createNameFiledPane(); + //显示封面 + UILabel coverLabel = ShareUIUtils.createTopRightUILabel(Toolkit.i18nText("Fine-Design_Share_Show_Cover")); + JPanel coverImagePane = getCoverImagePane(); + //制作者 + UILabel vendorLabel = ShareUIUtils.createCenterRightUILabel(Toolkit.i18nText("Fine-Design_Share_Share_Vendor")); + JPanel vendorPane = createVendorPane(); + //适用终端 + UILabel deviceLabel = ShareUIUtils.createCenterRightUILabel(Toolkit.i18nText("Fine-Design_Share_Device")); + JPanel devicePane = createDevicePane(); + //组件分类 + UILabel classifyLabel = ShareUIUtils.createCenterRightUILabel(Toolkit.i18nText("Fine-Design_Share_Classify")); + JPanel classifyPane = createClassifyPane(); + + //样式风格 + UILabel styleThemeLabel = ShareUIUtils.createCenterRightUILabel(Toolkit.i18nText("Fine-Design_Share_Style_Theme")); + JPanel styleThemePane = createStyleThemePane(); + //本地分组 + UILabel localGroupLabel = ShareUIUtils.createCenterRightUILabel(Toolkit.i18nText("Fine-Design_Share_Local_Group")); + JPanel localGroupPane = createLocalGroupPane(); + //使用插件 + UILabel pluginLabel = ShareUIUtils.createCenterRightUILabel(Toolkit.i18nText("Fine-Design_Share_Use_Plugin")); + JPanel pluginPane = createPluginPane(); + //期望价格 + UILabel priceLabel = ShareUIUtils.createCenterRightUILabel(Toolkit.i18nText("Fine-Design_Share_Expect_Price")); + JPanel pricePane = createPricePane(); + + double p = TableLayout.PREFERRED; + + JPanel innerPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + JPanel infoPane; + if (upload) { + Component[][] components = new Component[][]{ + new Component[]{nameLabel, symbolTextField}, + new Component[]{coverLabel, coverImagePane}, + new Component[]{vendorLabel, vendorPane}, + new Component[]{deviceLabel, devicePane}, + new Component[]{classifyLabel, classifyPane}, + new Component[]{styleThemeLabel, styleThemePane}, + new Component[]{pluginLabel, pluginPane}, + new Component[]{priceLabel, pricePane}, + }; + double[] rowSize = {p, p, p, p, p, p, p, p}; + double[] columnSize = {COLUMN_ITEM_SIZE, p}; + int[][] rowCount = {{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1},{1, 1}, {1, 1}}; + infoPane = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, LayoutConstants.HGAP_SMALL, BASEPANE_VERTICAL_GAP); + } else { + Component[][] components = new Component[][]{ + new Component[]{nameLabel, symbolTextField}, + new Component[]{coverLabel, coverImagePane}, + new Component[]{deviceLabel, devicePane}, + new Component[]{classifyLabel, classifyPane}, + new Component[]{localGroupLabel, localGroupPane} + }; + double[] rowSize = {p, p, p, p, p}; + double[] columnSize = {COLUMN_ITEM_SIZE, p}; + int[][] rowCount = {{1, 1}, {1, 1}, {1, 1},{1, 1}, {1, 1}}; + infoPane = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, LayoutConstants.HGAP_SMALL, BASEPANE_VERTICAL_GAP); + } + + String title = Toolkit.i18nText("Fine-Design_Share_Base_Info"); + JPanel overviewPane = FRGUIPaneFactory.createTitledBorderPane(title); + + innerPane.add(tipsLabel, BorderLayout.NORTH); + innerPane.add(infoPane, BorderLayout.CENTER); + overviewPane.add(innerPane, BorderLayout.CENTER); + + return overviewPane; + } + + private JPanel createEffectPane(List effectItemGroups) { + return new EffectPane(effectItemGroups); + } + + private JPanel createPricePane() { + + JPanel pane = FRGUIPaneFactory.createBoxFlowInnerContainer_S_Pane(); + this.priceExpectPane = new PriceExpectPane(); + pane.add(priceExpectPane); + return pane; + } + + private JPanel createStyleThemePane() { + JPanel pane = FRGUIPaneFactory.createBoxFlowInnerContainer_S_Pane(); + PlaceHolderUI placeHolderUI = new PlaceHolderUI( + Toolkit.i18nText("Fine-Design_Share_Style_Theme_Place_Holder")) { + @Override + protected boolean validate(UIComboBox uiComboBox) { + return styleComboBox.getSelectedItem() != null; + } + }; + this.styleComboBox = ShareUIUtils.wrapUI(placeHolderUI, new UIComboBox()); + this.styleComboBox.refreshBoxItems(StyleTheme.getStyleThemeTypeInfo()); + styleComboBox.setPreferredSize(new Dimension(COMBO_WIDTH, COMBO_HEIGHT)); + pane.add(styleComboBox); + return pane; + } + + private JPanel createPluginPane() { + + JPanel pane = FRGUIPaneFactory.createBoxFlowInnerContainer_S_Pane(); + + List contexts = PluginManager.getContexts(new PluginFilter() { + @Override + public boolean accept(PluginContext pluginContext) { + + return pluginContext.isRunning(); + } + }); + String[] displays = new String[contexts.size()]; + String[] values = new String[contexts.size()]; + Pair[] pairs = new Pair[contexts.size()]; + for (int i = 0; i < contexts.size(); i++) { + PluginContext context = contexts.get(i); + String display = context.getName(); + String value = context.getID() + "-" + context.getVersion(); + pairs[i] = new Pair<>(display, value); + } + //按照顺序展示 + //转换一下中文为拼音 + Arrays.sort(pairs, new Comparator>() { + @Override + public int compare(Pair pair1, Pair pair2) { + String o1 = pair1.getFirst(); + String o2 = pair2.getFirst(); + String pinyin1 = PinyinHelper.getShortPinyin(o1); + String pinyin2 = PinyinHelper.getShortPinyin(o2); + return pinyin1.compareToIgnoreCase(pinyin2); + } + }); + for (int i = 0; i < pairs.length; i++) { + displays[i] = pairs[i].getFirst(); + values[i] = pairs[i].getSecond(); + } + this.pluginComboCheckBox = new DictionaryComboCheckBox(values, displays, "Fine-Design_Share_Select_Plugin"); + + pluginComboCheckBox.setPopupMaxDisplayNumber(10); + pluginComboCheckBox.setVisible(false); + + pluginCheckBox.addItemListener(new ItemListener() { + @Override + public void itemStateChanged(ItemEvent e) { + int stateChange = e.getStateChange(); + pluginComboCheckBox.setVisible(stateChange == ItemEvent.SELECTED); + pluginComboCheckBox.repaint(); + } + }); + + pane.add(pluginCheckBox); + pane.add(pluginComboCheckBox); + return pane; + } + + private JPanel createClassifyPane() { + + JPanel pane = new JPanel(); + //距离远一点 + pane.setLayout(new FlowLayout(FlowLayout.LEFT, 2, 5)); + this.parentClassify = new UIComboBox(ComponentTypes.values()); + this.parentClassify.setPreferredSize(new Dimension(COMBO_WIDTH, COMBO_HEIGHT)); + + List children = ComponentTypes.CHART.children(-1); + final String placeHolderText = Toolkit.i18nText("Fine-Design_Share_Select_Type"); + PlaceHolderUI placeHolderUI = new PlaceHolderUI(placeHolderText) { + @Override + protected boolean validate(UIComboBox comboBox) { + return childClassify.getSelectedItem() != null; + } + }; + this.childClassify = ShareUIUtils.wrapUI(placeHolderUI, new UIComboBox()); + this.childClassify.refreshBoxItems(children); + this.childClassify.setPreferredSize(new Dimension(COMBO_WIDTH_PLUS, COMBO_HEIGHT)); + this.childClassify.setBorder(BorderFactory.createEmptyBorder()); + + parentClassify.addItemListener(new ItemListener() { + + @Override + public void itemStateChanged(ItemEvent e) { + + ItemSelectable itemSelectable = e.getItemSelectable(); + ComponentType selectedItem = (ComponentType) ((UIComboBox) itemSelectable).getSelectedItem(); + if (selectedItem != null) { + int device = displayDevice(); + List children = selectedItem.children(device); + childClassify.clearBoxItems(); + childClassify.refreshBoxItems(children); + } + } + }); + + //设置默认值 + this.parentClassify.setSelectedItem(ComponentTypes.CHART); + + pane.add(parentClassify); + pane.add(childClassify); + return pane; + } + + private JPanel createLocalGroupPane() { + + JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT, 2, 2)); + this.localGroup = new UIComboBox(DefaultShareGroupManager.getInstance().getAllGroup()); + this.localGroup.setPreferredSize(new Dimension(GROUP_WIDTH, COMBO_HEIGHT)); + + panel.add(localGroup); + return panel; + } + + private JPanel createDevicePane() { + + JPanel pane = FRGUIPaneFactory.createBoxFlowInnerContainer_S_Pane(); + pc.setSelected(true); + mobile.setSelected(true); + + ItemListener parentClassifyRefresh = new ItemListener() { + @Override + public void itemStateChanged(ItemEvent e) { + parentClassify.setSelectedItem(ComponentTypes.CHART); + } + }; + + pc.addItemListener(parentClassifyRefresh); + + mobile.addItemListener(parentClassifyRefresh); + pane.add(pc); + pane.add(mobile); + return pane; + } + + @NotNull + private JPanel createVendorPane() { + + final JPanel vendorPane = FRGUIPaneFactory.createBoxFlowInnerContainer_S_Pane(); + + String bbsUsername = MarketConfig.getInstance().getBbsUsername(); + if (StringUtils.isEmpty(bbsUsername)) { + UILabel unLoginLabel = ShareUIUtils.createHyperlinkLabel(Toolkit.i18nText("Fine-Design_Share_Click_Login")); + + final UILabel hidden = new ShareLoginLabel(vendorPane, unLoginLabel, loginLabel); + + unLoginLabel.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + LoginWebBridge.getHelper().setUILabel(hidden); + Dialog shareDialog = ShareDialogUtils.getInstance().getShareDialog(); + //必须这样创建,不然窗口优先级不对 + WebViewDlgHelper.createLoginDialog(shareDialog); + } + }); + vendorPane.add(unLoginLabel); + } else { + loginLabel.setText(bbsUsername); + vendorPane.add(loginLabel); + } + + return vendorPane; + } + + @NotNull + private JPanel createComponentOverviewPane(boolean upload) { + //功能介绍 + UILabel effectLabel = ShareUIUtils.createTopRightUILabel(Toolkit.i18nText("Fine-Design_Share_Special_Effects")); + JPanel effectPane = createEffectPane(effectItemGroups); + + content.setDocument( + new LimitedDocument(200, 500) + ); + String contentTip = Toolkit.i18nText("Fine-Design_Share_Content_Introduction_Placeholder"); + content.setAutoscrolls(true); + content.setPlaceholder(contentTip); + UIScrollPane contentPane = new UIScrollPane(content); + contentPane.setPreferredSize(new Dimension(COLUMN_FIELD_WIDTH, 50)); + contentPane.setBorder(null); + + help.setDocument( + new LimitedDocument(1000) + ); + String helpTip = Toolkit.i18nText("Fine-Design_Share_Help_Msg_Placeholder"); + help.setPlaceholder(helpTip); + UIScrollPane helpPane = new UIScrollPane(help); + helpPane.setPreferredSize(new Dimension(COLUMN_FIELD_WIDTH, 50)); + helpPane.setBorder(null); + + UILabel helpLabel = ShareUIUtils.createTopRightUILabel(Toolkit.i18nText("Fine-Design_Share_Help_Msg")); + UILabel contentLabel = ShareUIUtils.createTopRightUILabel(Toolkit.i18nText("Fine-Design_Share_Content_Introduction")); + + + double p = TableLayout.PREFERRED; + int[] row = {1, 1}; + double[] columnSize = {COLUMN_ITEM_SIZE, p}; + List componentList= new LinkedList(); + List rowSizeList = new LinkedList(); + List rowCountList = new LinkedList(); + + if (effectItemGroups.size() > 0 ) { + componentList.add(new Component[]{effectLabel, effectPane}); + } + + componentList.add(new Component[]{helpLabel, helpPane}); + + if (upload) { + componentList.add(new Component[]{contentLabel, contentPane}); + } + for (int i = 0; i < componentList.size(); i++) { + rowSizeList.add(p); + rowCountList.add(row); + } + + return TableLayoutHelper.createGapTableLayoutPane( + componentList.toArray(new Component[componentList.size()][]), + ArrayUtils.toPrimitive(rowSizeList.toArray(new Double[rowSizeList.size()])), + columnSize, + rowCountList.toArray(new int[rowCountList.size()][]), + LayoutConstants.VGAP_MEDIUM, LayoutConstants.VGAP_MEDIUM); + } + + private JPanel createNameFiledPane() { + LimitedDocument nameLimited = new LimitedDocument(NAME_MAX_LENGTH); + nameField.setPlaceholder(Toolkit.i18nText("Fine-Design_Share_Name_Placeholder")); + nameField.setPreferredSize(new Dimension(TEXT_FIELD_WIDTH, TEXT_FIELD_HEIGHT)); + nameField.setDocument(nameLimited); + JPanel symbolTextFiled = FRGUIPaneFactory.createBorderLayout_S_Pane(); + UILabel validSymbol = new UILabel(" *"); + symbolTextFiled.add(nameField, BorderLayout.CENTER); + symbolTextFiled.add(validSymbol, BorderLayout.EAST); + + return symbolTextFiled; + } + + + private void initUploadCoverBtn() { + + this.uploadBtn = new UIButton(Toolkit.i18nText("Fine-Design_Share_Select_Upload_Cover")); + this.uploadBtn.setPreferredSize(new Dimension(BTN_WIDTH, BTN_HEIGHT)); + uploadBtn.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + final CoverUploadPane pane = new CoverUploadPane(); + BasicDialog basicDialog = pane.showWindow(DesignerContext.getDesignerFrame(), true); + pane.setSize(BasicDialog.MEDIUM); + pane.populateBean(shareCover); + basicDialog.addDialogActionListener(new DialogActionAdapter() { + @Override + public void doOk() { + shareCover = pane.updateBean(); + cover.setIcon(getShowIcon(shareCover)); + cover.repaint(); + } + }); + basicDialog.setVisible(true); + } + }); + } + + private JPanel getCoverImagePane() { + + initUploadCoverBtn(); + JPanel coverImagePane = FRGUIPaneFactory.createNormalFlowInnerContainer_S_Pane(); + cover.setPreferredSize(new Dimension(ShareComponentConstants.SHARE_THUMB_WIDTH, ShareComponentConstants.SHARE_THUMB_HEIGHT)); + coverImagePane.add(cover); + + JPanel uploadBtnPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + uploadBtnPane.setPreferredSize(new Dimension(BTN_WIDTH, ShareComponentConstants.SHARE_THUMB_HEIGHT)); + uploadBtnPane.add(uploadBtn, BorderLayout.SOUTH); + coverImagePane.add(uploadBtnPane); + + return coverImagePane; + + } + + /* 校验 */ + + public boolean check() { + + Dialog shareDialog = ShareDialogUtils.getInstance().getShareDialog(); + String name = nameField.getText(); + if (StringUtils.isEmpty(name)) { + FineJOptionPane.showMessageDialog(shareDialog, Toolkit.i18nText("Fine-Design_Share_Lack_Name"), + Toolkit.i18nText("Fine-Design_Basic_Error"), ERROR_MESSAGE, UIManager.getIcon("OptionPane.errorIcon")); + return false; + } + if (upload && StringUtils.isEmpty(content.getText())) { + FineJOptionPane.showMessageDialog(shareDialog, Toolkit.i18nText("Fine-Design_Share_Lack_Content"), + Toolkit.i18nText("Fine-Design_Basic_Error"), ERROR_MESSAGE, UIManager.getIcon("OptionPane.errorIcon")); + return false; + } + if (upload && StringUtils.isEmpty(loginLabel.getText())) { + FineJOptionPane.showMessageDialog(shareDialog, Toolkit.i18nText("Fine-Design_Share_Lack_Login"), + Toolkit.i18nText("Fine-Design_Basic_Error"), ERROR_MESSAGE, UIManager.getIcon("OptionPane.errorIcon")); + return false; + } + if (upload && styleComboBox.getSelectedItem() == null) { + FineJOptionPane.showMessageDialog(shareDialog, Toolkit.i18nText("Fine-Design_Share_Style_Theme_Tip"), + Toolkit.i18nText("Fine-Design_Basic_Error"), ERROR_MESSAGE, UIManager.getIcon("OptionPane.errorIcon")); + return false; + } + if (!pc.isSelected() && !mobile.isSelected()) { + FineJOptionPane.showMessageDialog(shareDialog, Toolkit.i18nText("Fine-Design_Share_Lack_Device"), + Toolkit.i18nText("Fine-Design_Basic_Error"), ERROR_MESSAGE, UIManager.getIcon("OptionPane.errorIcon")); + return false; + } + if (pluginCheckBox.isSelected() && ArrayUtils.isEmpty(pluginComboCheckBox.getSelectedValues())) { + FineJOptionPane.showMessageDialog(shareDialog, Toolkit.i18nText("Fine-Design_Share_Lack_Plugins"), + Toolkit.i18nText("Fine-Design_Basic_Error"), ERROR_MESSAGE, UIManager.getIcon("OptionPane.errorIcon")); + return false; + } + if (!priceExpectPane.check()) { + FineJOptionPane.showMessageDialog(shareDialog, Toolkit.i18nText("Fine-Design_Share_Lack_Price"), + Toolkit.i18nText("Fine-Design_Basic_Error"), ERROR_MESSAGE, UIManager.getIcon("OptionPane.errorIcon")); + return false; + } + return true; + } + + /* 生成 */ + + public DefaultSharableWidget generate() { + + String uuid = UUID.randomUUID().toString(); + DefaultSharableWidget provider = new DefaultSharableWidget(uuid, nameField.getText(), help.getText(), shareCover, rec.width, rec.height); + provider.setDisplayDevice(displayDevice()); + provider.setParentClassify(classify(parentClassify.getSelectedItem())); + provider.setChildClassify(classify(childClassify.getSelectedItem())); + provider.setDesignerVersion(ProductConstants.VERSION); + provider.setVendor(loginLabel.getText()); + provider.setFileName(provider.getNameWithID()); + + if (upload) { + provider.setSummary(content.getText()); + Object selectStyle = styleComboBox.getSelectedItem(); + provider.setStyleTheme(selectStyle == null ? null : ((StyleThemeBean) selectStyle).getId()); + provider.setInvolvePlugins(pluginComboCheckBox.getText()); + provider.setPriceExpect(priceExpectPane.getPrice()); + } + + return provider; + } + + public Group getSelectGroup() { + return (Group) localGroup.getSelectedItem(); + } + + public UITextField getNameField() { + return nameField; + } + + private String classify(Object classify) { + + return classify == null ? StringUtils.EMPTY : classify.toString(); + } + + private int displayDevice() { + + List types = new ArrayList<>(8); + if (pc.isSelected()) { + types.add(DisplayDevice.PC); + } + if (mobile.isSelected()) { + types.add(DisplayDevice.MOBILE); + } + return DisplayDevice.buildDevice(types); + } + + private class LimitedDocument extends PlainDocument { + private static final long serialVersionUID = 1L; + private int maxLength = -1;// 允许的最大长度 + private int errorLength = -1; + private int loop = 5; + private String allowCharAsString = null;// 允许的字符串格式(0123456789) + + public LimitedDocument(int maxLength) { + this(-1, maxLength); + } + + public LimitedDocument(int errorLength, int maxLength) { + super(); + this.errorLength = errorLength; + this.maxLength = maxLength; + } + + @Override + public void insertString(int offset, String str, AttributeSet attrSet) throws BadLocationException { + if (str == null) { + return; + } + if (allowCharAsString != null && str.length() == 1) { + if (allowCharAsString.indexOf(str) == -1) { + java.awt.Toolkit.getDefaultToolkit().beep();// 发出一个警告声 + return;// 不是所要求的字符格式,就直接返回,不进行下面的添加 + } + } + char[] charVal = str.toCharArray(); + String strOldValue = getText(0, getLength()); + char[] tmp = strOldValue.toCharArray(); + int currentLength = tmp.length + charVal.length; + if (errorLength != -1 && currentLength > errorLength && ++loop >= 5) { + this.loop = 0; + FineJOptionPane.showMessageDialog(ShareDialogUtils.getInstance().getShareDialog(), + ShareUIUtils.formatWidthString(Toolkit.i18nText("Fine-Design_Share_Input_Errors", String.valueOf(errorLength)), 200), + Toolkit.i18nText("Fine-Design_Basic_Error"), ERROR_MESSAGE, UIManager.getIcon("OptionPane.errorIcon")); + //只提示,不报错 + } + if (maxLength != -1 && (currentLength > maxLength)) { + java.awt.Toolkit.getDefaultToolkit().beep();// 发出一个警告声 + return;// 长度大于指定的长度maxLength,也直接返回,不进行下面的添加 + } + super.insertString(offset, str, attrSet); + } + + public void setAllowChar(String str) { + allowCharAsString = str; + } + } + +} diff --git a/designer-realize/src/main/java/com/fr/design/share/ui/generate/table/EffectItemRender.java b/designer-realize/src/main/java/com/fr/design/share/ui/generate/table/EffectItemRender.java new file mode 100644 index 000000000..f31169da1 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/ui/generate/table/EffectItemRender.java @@ -0,0 +1,117 @@ +package com.fr.design.share.ui.generate.table; + +import com.fr.base.BaseUtils; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.stable.StringUtils; + +import javax.swing.BorderFactory; +import javax.swing.ImageIcon; +import javax.swing.JPanel; +import javax.swing.JTable; +import javax.swing.border.Border; +import javax.swing.table.DefaultTableCellRenderer; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Cursor; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Image; +import java.awt.Rectangle; + +public class EffectItemRender extends DefaultTableCellRenderer { + static final private Color HEADER_COLOR = new Color(221, 221, 221); + static final private Color PLACEHOLDER_COLOR = new Color(193, 193, 193); + static final private Color NO_EDITABLE_BG = new Color(240, 240, 241); + static final private Border DEFAULT_NO_FOCUS_BORDER = BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(1, 5, 1, 5), BorderFactory.createEmptyBorder(0, 4, 0, 4)); + static final private Border SELECTED_BORDER = BorderFactory.createLineBorder(new Color(160,190,240)); + + private PreviewPanel preViewPanel; + + public EffectItemRender() { + setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 10)); + setLayout(new FlowLayout()); + preViewPanel = new PreviewPanel(StringUtils.EMPTY); + } + + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + setText(StringUtils.EMPTY); + setToolTipText(null); + setBorder(DEFAULT_NO_FOCUS_BORDER); + setBackground(null); + if (column > 0) { + if (StringUtils.isNotEmpty(value.toString())) { + setValue(value); + setToolTipText(value); + if (!table.isCellEditable(row, column)) { + setForeground(PLACEHOLDER_COLOR); + setBackground(NO_EDITABLE_BG); + setToolTipText(Toolkit.i18nText("Fine-Design_Share_Not_Support_Rename")); + } else { + setForeground(Color.black); + } + + if (table.getSelectedRow() == row && table.getSelectedColumn() == column && table.isCellEditable(row, column) ) { + setBorder(SELECTED_BORDER); + setBackground(null); + table.setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR)); + } else { + if (isSelected) { + setBackground(table.getSelectionBackground()); + } + + table.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + } + } else { + setValue(Toolkit.i18nText("Fine-Design_Share_Need_Rename")); + setForeground(PLACEHOLDER_COLOR); + } + return this; + } else { + Rectangle rect = table.getCellRect(row, column, false); + preViewPanel.populate(value.toString()); + preViewPanel.getTextLabel().setPreferredSize(new Dimension(rect.width - preViewPanel.ICON_SIZE - 20, rect.height)); + return preViewPanel; + } + } + + public void setValue(Object value) { + setText((value == null) ? "" : value.toString()); + } + + private void setToolTipText(Object value) { setToolTipText((value == null) ? "" : value.toString()); } + + private class PreviewPanel extends JPanel { + public static final int ICON_SIZE = 10; + private UILabel textLabel; + + public PreviewPanel(String text) { + init(text); + } + + private void init(String text) { + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + this.setBackground(HEADER_COLOR); + textLabel = new UILabel(text); + textLabel.setToolTipText(text); + textLabel.setBorder(BorderFactory.createEmptyBorder(0,5,0,0)); + Image image = BaseUtils.readImage("com/fr/base/images/share/view.png"); + image.getScaledInstance(ICON_SIZE, ICON_SIZE, Image.SCALE_DEFAULT); + UILabel imageLabel = new UILabel(new ImageIcon(image)); + imageLabel.setBorder(BorderFactory.createEmptyBorder(0,10,0,10)); + this.add(textLabel, BorderLayout.WEST); + this.add(imageLabel, BorderLayout.EAST); + } + + public UILabel getTextLabel() { + return textLabel; + } + + public void populate(String text) { + textLabel.setText(text); + this.setToolTipText(text); + } + } +} diff --git a/designer-realize/src/main/java/com/fr/design/share/ui/generate/table/EffectTableModel.java b/designer-realize/src/main/java/com/fr/design/share/ui/generate/table/EffectTableModel.java new file mode 100644 index 000000000..042159c69 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/ui/generate/table/EffectTableModel.java @@ -0,0 +1,76 @@ +package com.fr.design.share.ui.generate.table; + +import com.fr.design.share.effect.EffectItem; +import com.fr.design.share.effect.EffectItemGroup; +import com.fr.design.share.effect.ListenerEffectItem; + +import javax.swing.table.AbstractTableModel; +import java.util.List; + +public class EffectTableModel extends AbstractTableModel { + private Object[] columnNames; + private List effectItems; + + public EffectTableModel(EffectItemGroup itemGroup, Object[] columnNames) { + if (itemGroup == null) { + this.effectItems = new EffectItemGroup().getEffectItems(); + } else { + this.effectItems = itemGroup.getEffectItems(); + } + this.columnNames = columnNames; + } + @Override + public int getRowCount() { + return this.effectItems.size(); + } + + @Override + public int getColumnCount() { + return this.columnNames.length; + } + + @Override + public String getColumnName(int columnIndex) { + if (columnNames == null) { + return null; + } + return columnNames[columnIndex].toString(); + } + + @Override + public Class getColumnClass(int columnIndex) { + return EffectTableModel.class; + } + + @Override + public boolean isCellEditable(int rowIndex, int columnIndex) { + EffectItem effectItem = effectItems.get(rowIndex); + return columnIndex == 1 && !(effectItem instanceof ListenerEffectItem); + } + + @Override + public Object getValueAt(int rowIndex, int columnIndex) { + + if (rowIndex >= getRowCount() || columnIndex >= getColumnCount()) { + return null; + } + EffectItem effectItem = effectItems.get(rowIndex); + if (columnIndex == 0) { + return effectItem.getConfigPath(); + } else if (columnIndex == 1) { + return effectItem.getName(); + } + return null; + } + + @Override + public void setValueAt(Object aValue, int rowIndex, int columnIndex) { + if (rowIndex >= effectItems.size() || columnIndex >= getColumnCount()) { + return; + } + EffectItem effectItem = effectItems.get(rowIndex); + if (columnIndex == 1) { + effectItem.setName(aValue.toString()); + } + } +} diff --git a/designer-realize/src/main/java/com/fr/design/share/ui/table/EffectItemEditor.java b/designer-realize/src/main/java/com/fr/design/share/ui/table/EffectItemEditor.java new file mode 100644 index 000000000..8fc0464e2 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/ui/table/EffectItemEditor.java @@ -0,0 +1,65 @@ +package com.fr.design.share.ui.table; + +import com.fr.design.gui.itextfield.UITextField; + +import javax.swing.AbstractCellEditor; +import javax.swing.JTable; +import javax.swing.table.TableCellEditor; +import java.awt.Component; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseMotionAdapter; + +public class EffectItemEditor extends AbstractCellEditor implements TableCellEditor { + private UITextField textField; + + public EffectItemEditor(JTable table) { + textField = new UITextField(); + textField.addMouseListener(new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + table.setRowSelectionInterval(table.getEditingRow(), table.getEditingRow()); + table.setColumnSelectionInterval(table.getEditingColumn(), table.getEditingColumn()); + } + @Override + public void mouseExited(MouseEvent e) { + table.clearSelection(); + } + + }); + textField.addMouseMotionListener(new MouseMotionAdapter() { + @Override + public void mouseMoved(MouseEvent e) { + table.setRowSelectionInterval(table.getEditingRow(), table.getEditingRow()); + table.setColumnSelectionInterval(table.getEditingColumn(), table.getEditingColumn()); + } + }); + textField.addFocusListener(new FocusAdapter() { + public void focusGained(FocusEvent e) { + table.setRowSelectionInterval(table.getEditingRow(), table.getEditingRow()); + table.setColumnSelectionInterval(table.getEditingColumn(), table.getEditingColumn()); + } + @Override + public void focusLost(FocusEvent e) { + if ((table.getSelectedRow() < 0) || (table.getSelectedColumn() < 0)) { + table.getCellEditor().stopCellEditing(); + } + } + }); + } + @Override + public Object getCellEditorValue() { + return textField.getText(); + } + + private void setValue(Object value) { + textField.setText((value != null) ? value.toString() : ""); + } + + @Override + public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { + setValue(value); + return textField; + } +} diff --git a/designer-realize/src/main/java/com/fr/design/share/utils/EffectItemUtils.java b/designer-realize/src/main/java/com/fr/design/share/utils/EffectItemUtils.java new file mode 100644 index 000000000..010828cf1 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/utils/EffectItemUtils.java @@ -0,0 +1,22 @@ +package com.fr.design.share.utils; + +import com.fr.design.share.effect.EffectItemGroup; +import com.fr.form.share.utils.ShareUtils; +import com.fr.form.ui.Widget; + +import java.util.ArrayList; +import java.util.List; + +public class EffectItemUtils { + public static List getEffectItemGroupsByWidget(Widget widget) { + List widgetList = ShareUtils.getAllLeafWidget(widget); + List effectItemGroupList = new ArrayList(); + for (Widget w : widgetList) { + EffectItemGroup effectItemGroup = new EffectItemGroup(w); + if (effectItemGroup.getEffectItems().size() > 0) { + effectItemGroupList.add(effectItemGroup); + } + } + return effectItemGroupList; + } +} diff --git a/designer-realize/src/main/java/com/fr/design/share/utils/ShareDialogUtils.java b/designer-realize/src/main/java/com/fr/design/share/utils/ShareDialogUtils.java new file mode 100644 index 000000000..4b7cfb845 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/utils/ShareDialogUtils.java @@ -0,0 +1,36 @@ +package com.fr.design.share.utils; + +import java.awt.Dialog; + +public class ShareDialogUtils { + private static class InstanceHolder { + + private static ShareDialogUtils helper = new ShareDialogUtils(); + } + + public static ShareDialogUtils getInstance() { + + return InstanceHolder.helper; + } + + private Dialog shareDialog; + private Dialog ConfigDialog; + + public void setShareDialog(Dialog shareDialog) { + + this.shareDialog = shareDialog; + } + + public Dialog getShareDialog() { + + return this.shareDialog; + } + + public void setConfigDialog(Dialog configDialog) { + ConfigDialog = configDialog; + } + + public Dialog getConfigDialog() { + return ConfigDialog; + } +} diff --git a/designer-realize/src/main/java/com/fr/grid/Grid.java b/designer-realize/src/main/java/com/fr/grid/Grid.java index dc414f673..abbd60928 100644 --- a/designer-realize/src/main/java/com/fr/grid/Grid.java +++ b/designer-realize/src/main/java/com/fr/grid/Grid.java @@ -15,9 +15,11 @@ import com.fr.design.constants.UIConstants; import com.fr.design.file.HistoryTemplateListPane; import com.fr.design.fun.GridUIProcessor; import com.fr.design.gui.itextfield.UITextField; +import com.fr.design.mainframe.DesignOperationEvent; import com.fr.design.mainframe.ElementCasePane; import com.fr.design.mainframe.JTemplate; import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.event.EventDispatcher; import com.fr.general.ComparatorUtils; import com.fr.grid.event.CellEditorEvent; import com.fr.grid.event.CellEditorListener; @@ -1083,6 +1085,7 @@ public class Grid extends BaseGridComponent { imageChange = true; } if (styleChange || imageChange) { + EventDispatcher.fire(DesignOperationEvent.CELL_IMAGE_VALUE_MODIFY); return true; } } else { diff --git a/designer-realize/src/main/java/com/fr/grid/selection/CellSelection.java b/designer-realize/src/main/java/com/fr/grid/selection/CellSelection.java index 7f5d86ef1..fe24109ad 100644 --- a/designer-realize/src/main/java/com/fr/grid/selection/CellSelection.java +++ b/designer-realize/src/main/java/com/fr/grid/selection/CellSelection.java @@ -733,6 +733,16 @@ public class CellSelection extends Selection { @Override public QuickEditor getQuickEditor(TargetComponent tc) { + QuickEditor editor = getQuickEditorWithoutPopulate(tc); + if (editor == null) { + return null; + } + editor.populate(tc); + return editor; + } + + @Override + public QuickEditor getQuickEditorWithoutPopulate(TargetComponent tc) { ElementCasePane ePane = (ElementCasePane) tc; TemplateElementCase tplEC = ePane.getEditingElementCase(); TemplateCellElement cellElement = tplEC.getTemplateCellElement(column, row); @@ -744,10 +754,6 @@ public class CellSelection extends Selection { value = value == null ? StringUtils.EMPTY : value; //之前是少了个bigInteger,刚kunsnat又发现少了个bigDecimal,数字类型的都用stringEditor,没必要那个样子 QuickEditor editor = ActionFactory.getCellEditor((value instanceof Number) ? (Number.class) : (value.getClass())); - if (editor == null) { - return null; - } - editor.populate(tc); return editor; } diff --git a/designer-realize/src/main/java/com/fr/grid/selection/FloatSelection.java b/designer-realize/src/main/java/com/fr/grid/selection/FloatSelection.java index 4ea3e41de..d225a239c 100644 --- a/designer-realize/src/main/java/com/fr/grid/selection/FloatSelection.java +++ b/designer-realize/src/main/java/com/fr/grid/selection/FloatSelection.java @@ -236,6 +236,15 @@ public class FloatSelection extends Selection { @Override public QuickEditor getQuickEditor(TargetComponent tc) { + QuickEditor editor = getQuickEditorWithoutPopulate(tc); + if (editor == null) + return null; + editor.populate(tc); + return editor; + } + + @Override + public QuickEditor getQuickEditorWithoutPopulate(TargetComponent tc) { ElementCasePane ePane = (ElementCasePane) tc; FloatElement selectedFloat = ePane.getEditingElementCase().getFloatElement(selectedFloatName); Object value = null; @@ -246,10 +255,10 @@ public class FloatSelection extends Selection { value = value == null ? "" : value; value = value instanceof Number ? value.toString() : value; QuickEditor editor = ActionFactory.getFloatEditor(value.getClass()); - editor.populate(tc); return editor; } + @Override public void populatePropertyPane(ElementCasePane ePane) { CellElementPropertyPane.getInstance().removeAll(); 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 162a2044f..5d3964771 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.file.MutilTempalteTabPane; import com.fr.design.fun.MenuHandler; import com.fr.design.gui.ibutton.UIButton; import com.fr.design.gui.ibutton.UIPreviewButton; +import com.fr.design.gui.ibutton.UISaveForbiddenButton; import com.fr.design.gui.imenu.UIMenuItem; import com.fr.design.gui.imenu.UIPopupMenu; import com.fr.design.gui.itoolbar.UILargeToolbar; @@ -232,7 +233,7 @@ public class MainDesigner extends BaseDesigner { public void actionPerformed(ActionEvent e) { JTemplate jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); jt.stopEditing(); - jt.saveTemplate(); + jt.saveDirectly(); jt.requestFocus(); } }); @@ -270,12 +271,12 @@ public class MainDesigner extends BaseDesigner { } private void createRunButton(UILargeToolbar largeToolbar) { - run = new UIPreviewButton(new UIButton(UIConstants.PAGE_BIG_ICON) { + run = new UIPreviewButton(new UISaveForbiddenButton(UIConstants.PAGE_BIG_ICON) { @Override public Dimension getPreferredSize() { return new Dimension(34, 34); } - }, new UIButton(UIConstants.PREVIEW_DOWN) { + }, new UISaveForbiddenButton(UIConstants.PREVIEW_DOWN) { @Override public Dimension getPreferredSize() { return new Dimension(34, 10); diff --git a/designer-realize/src/main/java/com/fr/start/module/DesignerActivator.java b/designer-realize/src/main/java/com/fr/start/module/DesignerActivator.java index 3f1aa2663..5c7a20efc 100644 --- a/designer-realize/src/main/java/com/fr/start/module/DesignerActivator.java +++ b/designer-realize/src/main/java/com/fr/start/module/DesignerActivator.java @@ -27,6 +27,7 @@ import com.fr.design.actions.insert.flot.ImageFloatAction; import com.fr.design.actions.insert.flot.TextBoxFloatAction; import com.fr.design.bridge.DesignToolbarProvider; import com.fr.design.constants.DesignerLaunchStatus; +import com.fr.design.env.DesignerWorkspaceLoader; import com.fr.design.form.parameter.FormParaDesigner; import com.fr.design.fun.ElementUIProvider; import com.fr.design.gui.controlpane.NameObjectCreator; @@ -39,7 +40,6 @@ import com.fr.design.javascript.JavaScriptImplPane; import com.fr.design.javascript.ParameterJavaScriptPane; import com.fr.design.javascript.ProcessTransitionAdapter; import com.fr.design.mainframe.BaseJForm; -import com.fr.design.mainframe.ElementCaseThumbnail; import com.fr.design.mainframe.FormHierarchyTreePane; import com.fr.design.mainframe.InformationCollector; import com.fr.design.mainframe.JForm; @@ -53,12 +53,15 @@ import com.fr.design.mainframe.form.FormECDesignerProvider; import com.fr.design.mainframe.form.FormElementCaseDesigner; import com.fr.design.mainframe.form.FormReportComponentComposite; import com.fr.design.mainframe.loghandler.DesignerLogAppender; +import com.fr.design.mainframe.share.constants.ShareEntryKey; import com.fr.design.mainframe.socketio.DesignerSocketIO; import com.fr.design.module.DesignModuleFactory; import com.fr.design.os.impl.SupportOSImpl; import com.fr.design.parameter.FormParameterReader; import com.fr.design.parameter.ParameterPropertyPane; import com.fr.design.parameter.WorkBookParameterReader; +import com.fr.design.share.ui.config.ShareConfigPane; +import com.fr.design.share.ui.generate.ShareGeneratePane; import com.fr.design.update.actions.RecoverForDesigner; import com.fr.design.update.push.DesignerPushUpdateManager; import com.fr.design.widget.ui.btn.FormSubmitButtonDetailPane; @@ -145,6 +148,7 @@ public class DesignerActivator extends Activator { designerModuleStart(); loadLogAppender(); DesignerSocketIO.update(); + DesignerWorkspaceLoader.init(); OSSupportCenter.buildAction(new OSBasedAction() { @Override public void execute(Object... objects) { @@ -160,6 +164,9 @@ public class DesignerActivator extends Activator { @Override public void afterAllStart() { DesignerLaunchStatus.setStatus(DesignerLaunchStatus.DESIGNER_INIT_COMPLETE); + //生成BasicChartQuickEditor对象,需要用到ChartDesignerActivator的注册信息(DesignModuleFactory.registerChartPropertyPaneClass(ChartPropertyPane.class);) + //所以不能在registerCellEditor函数中进行注册 + ActionFactory.registerCellEditor(ChartCollection.class, new BasicChartQuickEditor()); } private void loadLogAppender() { @@ -344,8 +351,6 @@ public class DesignerActivator extends Activator { ActionFactory.registerCellEditor(BiasTextPainter.class, new CellBiasTextPainterEditor()); ActionFactory.registerCellEditor(BufferedImage.class, new CellImageQuickEditor()); ActionFactory.registerCellEditor(CellImagePainter.class, new CellImageQuickEditor()); - //todo 图表编辑器populate没能实现刷新面板显示 - ActionFactory.registerCellEditorClass(ChartCollection.class, BasicChartQuickEditor.class); Set providers = ExtraDesignClassManager.getInstance().getArray(ElementUIProvider.MARK_STRING); for (ElementUIProvider provider : providers) { @@ -379,6 +384,8 @@ public class DesignerActivator extends Activator { private static void registerData4Form() { StableFactory.registerMarkedClass(FormECDesignerProvider.XML_TAG, FormElementCaseDesigner.class); StableFactory.registerMarkedClass(FormECCompositeProvider.XML_TAG, FormReportComponentComposite.class); + StableFactory.registerMarkedClass(ShareEntryKey.SHARE_GENERATE, ShareGeneratePane.class); + StableFactory.registerMarkedClass(ShareEntryKey.SHARE_CONFIG, ShareConfigPane.class); DesignModuleFactory.registerParameterReader(new WorkBookParameterReader()); } @@ -396,8 +403,6 @@ public class DesignerActivator extends Activator { DesignModuleFactory.registerParameterReader(new FormParameterReader()); StableFactory.registerMarkedClass(BaseJForm.XML_TAG, JForm.class); - - StableFactory.registerMarkedObject(ElementCaseThumbnailProcessor.MARK_STRING, new ElementCaseThumbnail()); } private static void storePassport() { diff --git a/designer-realize/src/main/java/com/fr/start/module/DesignerWorkspaceActivator.java b/designer-realize/src/main/java/com/fr/start/module/DesignerWorkspaceActivator.java index 7154de982..24d918951 100644 --- a/designer-realize/src/main/java/com/fr/start/module/DesignerWorkspaceActivator.java +++ b/designer-realize/src/main/java/com/fr/start/module/DesignerWorkspaceActivator.java @@ -61,7 +61,6 @@ public class DesignerWorkspaceActivator extends Activator { @Override public void on(Event event, Workspace workspace) { - HistoryTemplateListCache.getInstance().load(); PluginClassRefreshManager.getInstance().addPluginListener(); }