Merge in DESIGN/design from ~ZHENG/c-design:feature/big-screen to feature/big-screen * commit '4f34fc2697c3b57882f552746f15645e585b3aaf': (144 commits) omport 处理冲突错了 更改 REPORT-52843 && REPORT-52844 组件复用-合入主版本-read和clicked都是false时,点击提示的组件复用蓝字,弹出新手引导,关闭引导后,弹出了已合入主版本的提示; 组件复用-合入主版本-鼠标悬浮工具栏套用组件时,tooltip显示“套用组件”,交互文档以及和交互确认了下,应该是“复用组件” REPORT-52824 10.0.16 模板另存不会生成新的模板id REPORT-52264 修改弹窗的父窗口为DesignerContext.getDesignerFrame() REPORT-52629 组件展示排序逻辑的保存 REPORT-52512 共享组件删除后删除对应的数据集 颜色修改 CHART-19306 默认渐变色修改 REPORT-52699 组件复用-合入主版本-feature主jar,一些第三方插件控件,右侧点击事件/移动端,显示的还是属性设置页面内容 CHART-19306 公式增加等于号 REPORT-52539 组件生成面板出现横向滚动条 CHART-19344 取色器改为点击之后确定颜色 REPORT-52264 模版权限编辑警告弹窗不在页面中间 REPORT-51992 设计器性能提升-缩略图占内存优化 REPORT-51992 设计器性能提升-缩略图占内存优化 CHART-19306 仪表盘配色面板修改 REPORT-52538 组件复用-合入主版本-事件的常规设置处,切换组件后再查看,事件设置面板就不显示内容了 REPORT-51992 设计器性能提升-缩略图占内存优化 REPORT-51244【10.0.17】复用组件接触点优化 ...feature/big-screen
@ -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; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,52 @@ |
|||||||
|
package com.fr.design.actions.community; |
||||||
|
|
||||||
|
import com.fr.base.BaseUtils; |
||||||
|
import com.fr.design.actions.UpdateAction; |
||||||
|
import com.fr.design.mainframe.share.collect.ComponentCollector; |
||||||
|
import com.fr.design.menu.MenuKeySet; |
||||||
|
import com.fr.design.utils.BrowseUtils; |
||||||
|
import com.fr.general.CloudCenter; |
||||||
|
|
||||||
|
import javax.swing.KeyStroke; |
||||||
|
import java.awt.event.ActionEvent; |
||||||
|
|
||||||
|
/** |
||||||
|
* created by Harrison on 2020/03/24 |
||||||
|
**/ |
||||||
|
public class TemplateStoreAction extends UpdateAction { |
||||||
|
|
||||||
|
public TemplateStoreAction() { |
||||||
|
|
||||||
|
this.setMenuKeySet(TEMPLATE); |
||||||
|
this.setName(getMenuKeySet().getMenuName()); |
||||||
|
this.setMnemonic(getMenuKeySet().getMnemonic()); |
||||||
|
this.setSmallIcon(BaseUtils.readIcon("/com/fr/base/images/share/template_store.png")); |
||||||
|
} |
||||||
|
|
||||||
|
public static final MenuKeySet TEMPLATE = new MenuKeySet() { |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getMenuName() { |
||||||
|
|
||||||
|
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Share_Template_Store"); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public KeyStroke getKeyStroke() { |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public char getMnemonic() { |
||||||
|
|
||||||
|
return 'T'; |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
ComponentCollector.getInstance().collectTepMenuEnterClick(); |
||||||
|
String url = CloudCenter.getInstance().acquireUrlByKind("design.market.template"); |
||||||
|
BrowseUtils.browser(url); |
||||||
|
} |
||||||
|
} |
@ -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());
}
} |
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()); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -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"); |
||||||
|
} |
||||||
|
} |
@ -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(); |
||||||
|
} |
||||||
|
} |
@ -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(); |
||||||
|
} |
||||||
|
} |
@ -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(); |
||||||
|
} |
||||||
|
} |
@ -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()); |
||||||
|
} |
||||||
|
} |
@ -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(); |
||||||
|
} |
||||||
|
} |
@ -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()); |
||||||
|
} |
||||||
|
} |
@ -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<Void> preSearchTask; |
||||||
|
|
||||||
|
public SearchPreTaskTreeComboBox(JTree tree, TreeCellRenderer renderer, boolean editable) { |
||||||
|
super(tree, renderer, editable); |
||||||
|
} |
||||||
|
|
||||||
|
public FutureTask<Void> getPreSearchTask() { |
||||||
|
return preSearchTask; |
||||||
|
} |
||||||
|
|
||||||
|
public void setPreSearchTask(FutureTask<Void> 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<Void, Void>() { |
||||||
|
@Override |
||||||
|
protected Void doInBackground() { |
||||||
|
FutureTask<Void> 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(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -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(); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
@ -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<Null> { |
||||||
|
|
||||||
|
CELL_STYLE_MODIFY, |
||||||
|
|
||||||
|
CELL_IMAGE_VALUE_MODIFY |
||||||
|
|
||||||
|
} |
@ -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(); |
||||||
|
|
||||||
|
} |
@ -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); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} |
@ -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); |
||||||
|
|
||||||
|
} |
||||||
|
} |
@ -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<String> 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<String> getSavingTemplate() { |
||||||
|
List<String> result = new ArrayList<>(); |
||||||
|
for (JTemplate<?, ?> template : HistoryTemplateListCache.getInstance().getHistoryList()) { |
||||||
|
if (template.isSaving()) { |
||||||
|
result.add(template.getEditingFILE().getName()); |
||||||
|
} |
||||||
|
} |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -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; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -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<Set<String>, Void> checkThread = new SwingWorker<Set<String>, Void>() { |
||||||
|
@Override |
||||||
|
protected Set<String> doInBackground() throws Exception { |
||||||
|
// 返回校验结果
|
||||||
|
return check(DesignerContext.getDesignerFrame().getSelectedJTemplate()); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void done() { |
||||||
|
try { |
||||||
|
Set<String> set = get(); |
||||||
|
if (set == null) { |
||||||
|
return; |
||||||
|
} |
||||||
|
if (set.isEmpty()) { |
||||||
|
okButton.setEnabled(true); |
||||||
|
uiLabel.setIcon(BaseUtils.readIcon("com/fr/design/images/correct.png")); |
||||||
|
message.setText("<html>" + Toolkit.i18nText("Fine_Designer_Check_Font_Success") + "</html>"); |
||||||
|
} 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<Set<String>, Void> checkThread) { |
||||||
|
initDialogPane(); |
||||||
|
dialog.addWindowListener(new WindowAdapter() { |
||||||
|
public void windowClosed(WindowEvent e) { |
||||||
|
checkThread.cancel(true); |
||||||
|
} |
||||||
|
}); |
||||||
|
checkThread.execute(); |
||||||
|
dialog.setVisible(true); |
||||||
|
dialog.dispose(); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
private Set<String> check(JTemplate jtemplate) { |
||||||
|
String path = jtemplate.getEditingFILE().getEnvFullName(); |
||||||
|
Set<String> fontSet = WorkContext.getCurrent().get(TemplateChecker.class, new ExceptionHandler<Void>() { |
||||||
|
|
||||||
|
@Override |
||||||
|
public Void callHandler(RPCInvokerExceptionInfo rpcInvokerExceptionInfo) { |
||||||
|
uiLabel.setIcon(BaseUtils.readIcon("com/fr/design/images/error.png")); |
||||||
|
message.setText("<html>" + Toolkit.i18nText("Fine_Designer_Check_Font_Upgrade") + "</html>"); |
||||||
|
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)); |
||||||
|
} |
||||||
|
} |
@ -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(); |
||||||
|
} |
||||||
|
} |
@ -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(); |
||||||
|
} |
||||||
|
} |
@ -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() { |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -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; |
||||||
|
} |
||||||
|
} |
@ -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; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
@ -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<Object> 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(); |
||||||
|
} |
||||||
|
} |
@ -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<String, Object> 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; |
||||||
|
} |
||||||
|
} |
@ -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("<html>" + text + "</html>"); |
||||||
|
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("<div style='width:").append(width) |
||||||
|
.append("px;height:100%").append(getFontWrapStyle(font)).append(";'>"); |
||||||
|
return getHtmlContentDimension(content, limitDiv).height; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private static Dimension getHtmlContentDimension(String content, StringBuffer limitDiv) { |
||||||
|
content = limitDiv.append(content).append("</div>").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(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -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(); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
@ -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<String, SwingWorker> 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); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -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<T extends BaseBook, R> { |
||||||
|
|
||||||
|
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; |
||||||
|
} |
||||||
|
} |
@ -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<T> extends SwingWorker<T, Void> { |
||||||
|
|
||||||
|
private static final int TIME_OUT = 400; |
||||||
|
|
||||||
|
private final Callable<T> callable; |
||||||
|
|
||||||
|
private final JTemplate<?, ?> template; |
||||||
|
|
||||||
|
private Callable<JTemplate<?, ?>> templateCallable; |
||||||
|
|
||||||
|
private boolean slowly = false; |
||||||
|
|
||||||
|
private String taskName; |
||||||
|
|
||||||
|
private T result; |
||||||
|
|
||||||
|
public OpenWorker(Callable<T> 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<JTemplate<?, ?>> 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; |
||||||
|
} |
||||||
|
} |
@ -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<Runnable> successRunnableList; |
||||||
|
|
||||||
|
private List<Runnable> failRunnableList; |
||||||
|
|
||||||
|
public CallbackSaveWorker(Callable<Boolean> 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<Runnable> list) { |
||||||
|
if (Collections.isEmpty(list)) { |
||||||
|
return; |
||||||
|
} |
||||||
|
for (Runnable runnable : list) { |
||||||
|
runnable.run(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void addCallback(List<Runnable> 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); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -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<Boolean> 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
|
||||||
|
} |
||||||
|
} |
@ -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<Boolean, Void> { |
||||||
|
|
||||||
|
private static final int TIME_OUT = 400; |
||||||
|
|
||||||
|
private final Callable<Boolean> callable; |
||||||
|
|
||||||
|
private String taskName; |
||||||
|
|
||||||
|
private final JTemplate<?, ?> template; |
||||||
|
|
||||||
|
protected boolean success; |
||||||
|
|
||||||
|
private boolean slowly; |
||||||
|
|
||||||
|
public SaveWorker(Callable<Boolean> 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); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
After Width: | Height: | Size: 386 B |
Before Width: | Height: | Size: 942 B After Width: | Height: | Size: 736 B |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 864 B After Width: | Height: | Size: 864 B |
Before Width: | Height: | Size: 804 B After Width: | Height: | Size: 804 B |
After Width: | Height: | Size: 785 B |
After Width: | Height: | Size: 768 B |