forked from fanruan/design
Browse Source
Merge in DESIGN/design from ~KERRY/design_10.0:feature/10.0 to feature/10.0 * commit '9525ae797e3977a20cd0c67bb0c636aee090a4a7': 魔法数字 删除调试信息 REPORT-51244 【10.0.17】复用组件接触点优化feature/10.0
24 changed files with 931 additions and 13 deletions
@ -0,0 +1,39 @@ |
|||||||
|
package com.fr.design.mainframe; |
||||||
|
|
||||||
|
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 enterWidgetLib() { |
||||||
|
EastRegionContainerPane.getInstance().switchTabTo(EastRegionContainerPane.KEY_WIDGET_LIB); |
||||||
|
enterWidgetLibExtraAction(); |
||||||
|
} |
||||||
|
|
||||||
|
public static void enterWidgetLibExtraAction() { |
||||||
|
if (ComponentReuseNotificationInfo.getInstance().isClickedWidgetLib()) { |
||||||
|
return; |
||||||
|
} |
||||||
|
SnapChat snapChat = SnapChatFactory.createSnapChat(false, new SnapChatKey() { |
||||||
|
@Override |
||||||
|
public String calc() { |
||||||
|
return COMPONENT_SNAP_CHAT_KEY; |
||||||
|
} |
||||||
|
}); |
||||||
|
if (snapChat.hasRead()) { |
||||||
|
DesignerToastMsgUtil.toastPrompt(Toolkit.i18nText("Fine-Design_Component_Reuse_Merge_Prompt")); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -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,69 @@ |
|||||||
|
package com.fr.design.mainframe.reuse; |
||||||
|
|
||||||
|
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; |
||||||
|
|
||||||
|
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; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void readXML(XMLableReader reader) { |
||||||
|
this.setLastNotifyTime(reader.getAttrAsLong("lastNotifyTime", 0L)); |
||||||
|
this.setNotifiedNumber(reader.getAttrAsInt("notifiedNumber", 0)); |
||||||
|
this.setClickedWidgetLib(reader.getAttrAsBoolean("clickedWidgetLib", false)); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void writeXML(XMLPrintWriter writer) { |
||||||
|
writer.startTAG("ComponentReuseNotificationInfo"); |
||||||
|
writer.attr("lastNotifyTime", this.lastNotifyTime) |
||||||
|
.attr("notifiedNumber", this.notifiedNumber) |
||||||
|
.attr("clickedWidgetLib", this.clickedWidgetLib); |
||||||
|
writer.end(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Object clone() throws CloneNotSupportedException { |
||||||
|
return super.clone(); |
||||||
|
} |
||||||
|
} |
@ -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(); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
After Width: | Height: | Size: 166 B |
After Width: | Height: | Size: 377 B |
After Width: | Height: | Size: 608 B |
After Width: | Height: | Size: 622 B |
@ -0,0 +1,46 @@ |
|||||||
|
package com.fr.design.mainframe.reuse; |
||||||
|
|
||||||
|
import com.fr.stable.xml.XMLPrintWriter; |
||||||
|
import com.fr.stable.xml.XMLableReader; |
||||||
|
import com.fr.third.javax.xml.stream.XMLStreamException; |
||||||
|
import org.junit.Assert; |
||||||
|
import org.junit.Test; |
||||||
|
|
||||||
|
import java.io.PrintWriter; |
||||||
|
import java.io.StringReader; |
||||||
|
import java.io.StringWriter; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by kerry on 5/10/21 |
||||||
|
*/ |
||||||
|
public class ComponentReuseNotificationInfoTest { |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testReadXML() { |
||||||
|
try { |
||||||
|
XMLableReader xmlReader = XMLableReader.createXMLableReader(new StringReader("<ComponentReuseNotificationInfo lastNotifyTime=\"1620612153215\" notifiedNumber=\"2\" clickedWidgetLib=\"true\"/>\n")); |
||||||
|
ComponentReuseNotificationInfo notificationInfo = ComponentReuseNotificationInfo.getInstance(); |
||||||
|
notificationInfo.readXML(xmlReader); |
||||||
|
xmlReader.close(); |
||||||
|
Assert.assertEquals(2, notificationInfo.getNotifiedNumber()); |
||||||
|
Assert.assertEquals(true, notificationInfo.isClickedWidgetLib()); |
||||||
|
Assert.assertEquals(1620612153215L, notificationInfo.getLastNotifyTime()); |
||||||
|
} catch (XMLStreamException e) { |
||||||
|
Assert.fail(e.getMessage()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testWriteXML() { |
||||||
|
StringWriter sw = new StringWriter(); |
||||||
|
XMLPrintWriter writer = XMLPrintWriter.create(new PrintWriter(sw)); |
||||||
|
ComponentReuseNotificationInfo notificationInfo = ComponentReuseNotificationInfo.getInstance(); |
||||||
|
notificationInfo.setNotifiedNumber(1); |
||||||
|
notificationInfo.writeXML(writer); |
||||||
|
writer.flush(); |
||||||
|
writer.close(); |
||||||
|
Assert.assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + |
||||||
|
"<ComponentReuseNotificationInfo xmlVersion=\"20170720\" releaseVersion=\"\" lastNotifyTime=\"0\" notifiedNumber=\"1\" clickedWidgetLib=\"false\"/>\n", sw.toString()); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,214 @@ |
|||||||
|
|
||||||
|
|
||||||
|
package com.fr.design.mainframe; |
||||||
|
|
||||||
|
import com.fr.base.iofile.attr.ExtendSharableAttrMark; |
||||||
|
import com.fr.design.DesignerEnvManager; |
||||||
|
import com.fr.design.file.HistoryTemplateListCache; |
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
import com.fr.design.i18n.Toolkit; |
||||||
|
import com.fr.design.layout.FRGUIPaneFactory; |
||||||
|
import com.fr.design.mainframe.adaptve.config.TriggerPointProvider; |
||||||
|
|
||||||
|
import com.fr.design.mainframe.adaptve.config.impl.CellStyleTriggerPoint; |
||||||
|
import com.fr.design.mainframe.adaptve.config.impl.CellValueImageChangeTriggerPoint; |
||||||
|
import com.fr.design.mainframe.adaptve.config.ReuseNotifyInfo; |
||||||
|
import com.fr.design.mainframe.reuse.ComponentReuseNotificationInfo; |
||||||
|
import com.fr.design.mainframe.toast.DesignerToastMsgUtil; |
||||||
|
import com.fr.event.Event; |
||||||
|
import com.fr.event.EventDispatcher; |
||||||
|
import com.fr.event.Listener; |
||||||
|
import com.fr.event.Null; |
||||||
|
import com.fr.form.main.Form; |
||||||
|
import com.fr.form.main.WidgetGather; |
||||||
|
import com.fr.form.ui.AbstractBorderStyleWidget; |
||||||
|
import com.fr.form.ui.Widget; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
|
||||||
|
import javax.swing.BorderFactory; |
||||||
|
import javax.swing.JPanel; |
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.awt.Color; |
||||||
|
import java.awt.Cursor; |
||||||
|
import java.awt.event.MouseEvent; |
||||||
|
import java.awt.event.MouseListener; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Iterator; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by kerry on 4/28/21 |
||||||
|
*/ |
||||||
|
public class ReuseTriggerPointManager { |
||||||
|
private static final long ONE_WEEK_TIME = 7 * 24 * 3600 * 1000L; |
||||||
|
|
||||||
|
private static class Holder { |
||||||
|
private static final ReuseTriggerPointManager HOLDER = new ReuseTriggerPointManager(); |
||||||
|
} |
||||||
|
|
||||||
|
public static ReuseTriggerPointManager getInstance() { |
||||||
|
return Holder.HOLDER; |
||||||
|
} |
||||||
|
|
||||||
|
private Map<JForm, ReuseNotifyInfo> map = new HashMap<>(); |
||||||
|
|
||||||
|
private List<Listener> listeners = new ArrayList<>(); |
||||||
|
|
||||||
|
private ReuseTriggerPointManager() { |
||||||
|
if (!hasNotifiedTwice()) { |
||||||
|
List<TriggerPointProvider> list = getTriggerPoints(); |
||||||
|
for (TriggerPointProvider triggerPoint : list) { |
||||||
|
Listener listener = new Listener<Null>() { |
||||||
|
@Override |
||||||
|
public void on(Event event, Null o) { |
||||||
|
triggerPoint.triggerAction(); |
||||||
|
} |
||||||
|
}; |
||||||
|
EventDispatcher.listen(triggerPoint.triggerEvent(), listener); |
||||||
|
listeners.add(listener); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private List<TriggerPointProvider> getTriggerPoints() { |
||||||
|
List<TriggerPointProvider> list = new ArrayList<>(); |
||||||
|
list.add(new CellStyleTriggerPoint()); |
||||||
|
list.add(new CellValueImageChangeTriggerPoint()); |
||||||
|
return list; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private boolean hasNotifiedTwice() { |
||||||
|
return ComponentReuseNotificationInfo.getInstance().getNotifiedNumber() >= 2; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private void reCount() { |
||||||
|
//重新计次数
|
||||||
|
Iterator<Map.Entry<JForm, ReuseNotifyInfo>> iterator = map.entrySet().iterator(); |
||||||
|
while (iterator.hasNext()) { |
||||||
|
iterator.next().getValue().reset(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void writeTriggerInfo2xml() { |
||||||
|
int number = ComponentReuseNotificationInfo.getInstance().getNotifiedNumber() + 1; |
||||||
|
ComponentReuseNotificationInfo.getInstance().setNotifiedNumber(number); |
||||||
|
ComponentReuseNotificationInfo.getInstance().setLastNotifyTime(System.currentTimeMillis()); |
||||||
|
DesignerEnvManager.getEnvManager().saveXMLFile(); |
||||||
|
//如果已经提示过两次了
|
||||||
|
if (hasNotifiedTwice()) { |
||||||
|
for (Listener listener : listeners) { |
||||||
|
EventDispatcher.stopListen(listener); |
||||||
|
} |
||||||
|
this.map.clear(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public boolean needTrigger() { |
||||||
|
boolean result = true; |
||||||
|
if (ComponentReuseNotificationInfo.getInstance().getLastNotifyTime() > 0L) { |
||||||
|
result = System.currentTimeMillis() - ComponentReuseNotificationInfo.getInstance().getLastNotifyTime() > ONE_WEEK_TIME; |
||||||
|
} |
||||||
|
return !hasNotifiedTwice() && result; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public void registerJForm(JForm jForm) { |
||||||
|
if (!hasNotifiedTwice()) { |
||||||
|
this.map.put(jForm, new ReuseNotifyInfo()); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
public void removeJForm(JForm jForm) { |
||||||
|
if (!hasNotifiedTwice()) { |
||||||
|
this.map.remove(jForm); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public ReuseNotifyInfo getReuseNotifyInfo() { |
||||||
|
JTemplate currentJTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); |
||||||
|
if (!(currentJTemplate instanceof JForm && hasUseReuseComponent((JForm) currentJTemplate)) |
||||||
|
&& !ReuseTriggerPointManager.getInstance().needTrigger()) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
return map.get(currentJTemplate); |
||||||
|
} |
||||||
|
|
||||||
|
public void reuseNotify(ReuseNotifyInfo notifyInfo) { |
||||||
|
if (notifyInfo.matchCondition()) { |
||||||
|
ReuseTriggerPointManager.getInstance().reCount(); |
||||||
|
//弹出提示框
|
||||||
|
JTemplate currentJTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); |
||||||
|
DesignerToastMsgUtil.toastPrompt(createReusePrompt((JForm) currentJTemplate)); |
||||||
|
ReuseTriggerPointManager.getInstance().writeTriggerInfo2xml(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private boolean hasUseReuseComponent(JForm jForm) { |
||||||
|
Form form = jForm.getTarget(); |
||||||
|
List<Widget> extendSharableWidgetList = new ArrayList<>(); |
||||||
|
Form.traversalWidget(form.getContainer(), new WidgetGather() { |
||||||
|
@Override |
||||||
|
public void dealWith(Widget widget) { |
||||||
|
ExtendSharableAttrMark attrMark = ((AbstractBorderStyleWidget) widget).getWidgetAttrMark(ExtendSharableAttrMark.XML_TAG); |
||||||
|
if (attrMark != null && StringUtils.isNotEmpty(attrMark.getShareId())) { |
||||||
|
extendSharableWidgetList.add(widget); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean dealWithAllCards() { |
||||||
|
return true; |
||||||
|
} |
||||||
|
}, AbstractBorderStyleWidget.class); |
||||||
|
return extendSharableWidgetList.size() > 0; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private JPanel createReusePrompt(JForm jForm) { |
||||||
|
JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||||
|
jPanel.add(new UILabel(Toolkit.i18nText("Fine-Design_Component_Reuse_Try_Prompt")), BorderLayout.WEST); |
||||||
|
UILabel reuseLabel = new UILabel(Toolkit.i18nText("Fine-Design_Component_Reuse")); |
||||||
|
reuseLabel.addMouseListener(new MouseListener() { |
||||||
|
@Override |
||||||
|
public void mouseClicked(MouseEvent e) { |
||||||
|
jForm.tabChanged(0); |
||||||
|
ComponentReuseNotifyUtil.enterWidgetLib(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void mousePressed(MouseEvent e) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void mouseReleased(MouseEvent e) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void mouseEntered(MouseEvent e) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void mouseExited(MouseEvent e) { |
||||||
|
|
||||||
|
} |
||||||
|
}); |
||||||
|
reuseLabel.setBorder(BorderFactory.createEmptyBorder(0, 3, 0, 0)); |
||||||
|
reuseLabel.setForeground(Color.BLUE); |
||||||
|
reuseLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); |
||||||
|
jPanel.add(reuseLabel, BorderLayout.CENTER); |
||||||
|
return jPanel; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
@ -0,0 +1,30 @@ |
|||||||
|
package com.fr.design.mainframe.adaptve.config; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by kerry on 5/7/21 |
||||||
|
*/ |
||||||
|
public class ReuseNotifyInfo { |
||||||
|
private static final int CELL_STYLE_MODIFY_MAX_NUMBER = 3; |
||||||
|
private static final int CELL_IMAGE_VALUE_MODIFY_MAX_NUMBER = 1; |
||||||
|
private int cellStyleModifiedNumber = 0; |
||||||
|
private int cellImageValueNumber = 0; |
||||||
|
|
||||||
|
public void addCellStyleModify() { |
||||||
|
cellStyleModifiedNumber++; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public void addCellImageValueModify() { |
||||||
|
cellImageValueNumber++; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean matchCondition() { |
||||||
|
return cellStyleModifiedNumber >= CELL_STYLE_MODIFY_MAX_NUMBER |
||||||
|
|| cellImageValueNumber >= CELL_IMAGE_VALUE_MODIFY_MAX_NUMBER; |
||||||
|
} |
||||||
|
|
||||||
|
public void reset() { |
||||||
|
this.cellImageValueNumber = 0; |
||||||
|
this.cellStyleModifiedNumber = 0; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,20 @@ |
|||||||
|
package com.fr.design.mainframe.adaptve.config; |
||||||
|
|
||||||
|
|
||||||
|
import com.fr.event.Event; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by kerry on 4/29/21 |
||||||
|
*/ |
||||||
|
public interface TriggerPointProvider { |
||||||
|
/** |
||||||
|
* 触发后的操作 |
||||||
|
*/ |
||||||
|
void triggerAction(); |
||||||
|
|
||||||
|
/** |
||||||
|
* 触发事件 |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
Event triggerEvent(); |
||||||
|
} |
@ -0,0 +1,28 @@ |
|||||||
|
package com.fr.design.mainframe.adaptve.config.impl; |
||||||
|
|
||||||
|
import com.fr.design.mainframe.DesignOperationEvent; |
||||||
|
import com.fr.design.mainframe.ReuseTriggerPointManager; |
||||||
|
import com.fr.design.mainframe.adaptve.config.ReuseNotifyInfo; |
||||||
|
import com.fr.design.mainframe.adaptve.config.TriggerPointProvider; |
||||||
|
import com.fr.event.Event; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by kerry on 5/7/21 |
||||||
|
*/ |
||||||
|
public class CellStyleTriggerPoint implements TriggerPointProvider { |
||||||
|
@Override |
||||||
|
public void triggerAction() { |
||||||
|
ReuseNotifyInfo notifyInfo = ReuseTriggerPointManager.getInstance().getReuseNotifyInfo(); |
||||||
|
if (notifyInfo == null) { |
||||||
|
return; |
||||||
|
} |
||||||
|
notifyInfo.addCellStyleModify(); |
||||||
|
ReuseTriggerPointManager.getInstance().reuseNotify(notifyInfo); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Event triggerEvent() { |
||||||
|
return DesignOperationEvent.CELL_STYLE_MODIFY; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,27 @@ |
|||||||
|
package com.fr.design.mainframe.adaptve.config.impl; |
||||||
|
|
||||||
|
import com.fr.design.mainframe.DesignOperationEvent; |
||||||
|
import com.fr.design.mainframe.ReuseTriggerPointManager; |
||||||
|
import com.fr.design.mainframe.adaptve.config.ReuseNotifyInfo; |
||||||
|
import com.fr.design.mainframe.adaptve.config.TriggerPointProvider; |
||||||
|
import com.fr.event.Event; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by kerry on 5/7/21 |
||||||
|
*/ |
||||||
|
public class CellValueImageChangeTriggerPoint implements TriggerPointProvider { |
||||||
|
@Override |
||||||
|
public void triggerAction() { |
||||||
|
ReuseNotifyInfo notifyInfo = ReuseTriggerPointManager.getInstance().getReuseNotifyInfo(); |
||||||
|
if (notifyInfo == null) { |
||||||
|
return; |
||||||
|
} |
||||||
|
notifyInfo.addCellImageValueModify(); |
||||||
|
ReuseTriggerPointManager.getInstance().reuseNotify(notifyInfo); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Event triggerEvent() { |
||||||
|
return DesignOperationEvent.CELL_IMAGE_VALUE_MODIFY; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,45 @@ |
|||||||
|
package com.fr.design.mainframe; |
||||||
|
|
||||||
|
import com.fr.design.mainframe.reuse.ComponentReuseNotificationInfo; |
||||||
|
import org.junit.Assert; |
||||||
|
import org.junit.Test; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by kerry on 5/10/21 |
||||||
|
*/ |
||||||
|
public class ReuseTriggerPointManagerTest { |
||||||
|
private static final long ONE_WEEK_TIME = 7 * 24 * 3600 * 1000L; |
||||||
|
|
||||||
|
|
||||||
|
@Test |
||||||
|
public void testNeedTrigger() { |
||||||
|
ComponentReuseNotificationInfo notificationInfo = ComponentReuseNotificationInfo.getInstance(); |
||||||
|
notificationInfo.setNotifiedNumber(0); |
||||||
|
Assert.assertTrue(ReuseTriggerPointManager.getInstance().needTrigger()); |
||||||
|
|
||||||
|
notificationInfo.setNotifiedNumber(1); |
||||||
|
Assert.assertTrue(ReuseTriggerPointManager.getInstance().needTrigger()); |
||||||
|
|
||||||
|
notificationInfo.setNotifiedNumber(2); |
||||||
|
Assert.assertFalse(ReuseTriggerPointManager.getInstance().needTrigger()); |
||||||
|
|
||||||
|
notificationInfo.setNotifiedNumber(0); |
||||||
|
notificationInfo.setLastNotifyTime(System.currentTimeMillis()); |
||||||
|
Assert.assertFalse(ReuseTriggerPointManager.getInstance().needTrigger()); |
||||||
|
|
||||||
|
notificationInfo.setNotifiedNumber(1); |
||||||
|
notificationInfo.setLastNotifyTime(System.currentTimeMillis()); |
||||||
|
Assert.assertFalse(ReuseTriggerPointManager.getInstance().needTrigger()); |
||||||
|
|
||||||
|
|
||||||
|
notificationInfo.setNotifiedNumber(1); |
||||||
|
notificationInfo.setLastNotifyTime(System.currentTimeMillis() - ONE_WEEK_TIME - 1); |
||||||
|
Assert.assertTrue(ReuseTriggerPointManager.getInstance().needTrigger()); |
||||||
|
|
||||||
|
|
||||||
|
notificationInfo.setNotifiedNumber(2); |
||||||
|
notificationInfo.setLastNotifyTime(System.currentTimeMillis()); |
||||||
|
Assert.assertFalse(ReuseTriggerPointManager.getInstance().needTrigger()); |
||||||
|
} |
||||||
|
|
||||||
|
} |
Loading…
Reference in new issue