Browse Source

REPORT-51244 【10.0.17】复用组件接触点优化

feature/10.0
kerry 3 years ago
parent
commit
7844e017aa
  1. 19
      designer-base/src/main/java/com/fr/design/DesignerEnvManager.java
  2. 39
      designer-base/src/main/java/com/fr/design/mainframe/ComponentReuseNotifyUtil.java
  3. 15
      designer-base/src/main/java/com/fr/design/mainframe/DesignOperationEvent.java
  4. 39
      designer-base/src/main/java/com/fr/design/mainframe/EastRegionContainerPane.java
  5. 69
      designer-base/src/main/java/com/fr/design/mainframe/reuse/ComponentReuseNotificationInfo.java
  6. 106
      designer-base/src/main/java/com/fr/design/mainframe/toast/DesignerToastMsgUtil.java
  7. 154
      designer-base/src/main/java/com/fr/design/mainframe/toast/ToastMsgDialog.java
  8. BIN
      designer-base/src/main/resources/com/fr/design/images/form/designer/widget_apply_icon.png
  9. BIN
      designer-base/src/main/resources/com/fr/design/images/toast/reuse_icon.png
  10. BIN
      designer-base/src/main/resources/com/fr/design/images/toast/toast_prompt.png
  11. BIN
      designer-base/src/main/resources/com/fr/design/images/toast/toast_warning.png
  12. 46
      designer-base/src/test/java/com/fr/design/mainframe/reuse/ComponentReuseNotificationInfoTest.java
  13. 25
      designer-form/src/main/java/com/fr/design/designer/treeview/ComponentTreeCellRenderer.java
  14. 43
      designer-form/src/main/java/com/fr/design/mainframe/FormParaWidgetPane.java
  15. 7
      designer-form/src/main/java/com/fr/design/mainframe/JForm.java
  16. 214
      designer-form/src/main/java/com/fr/design/mainframe/ReuseTriggerPointManager.java
  17. 27
      designer-form/src/main/java/com/fr/design/mainframe/adaptve/config/ReuseNotifyInfo.java
  18. 20
      designer-form/src/main/java/com/fr/design/mainframe/adaptve/config/TriggerPointProvider.java
  19. 28
      designer-form/src/main/java/com/fr/design/mainframe/adaptve/config/impl/CellStyleTriggerPoint.java
  20. 27
      designer-form/src/main/java/com/fr/design/mainframe/adaptve/config/impl/CellValueImageChangeTriggerPoint.java
  21. 45
      designer-form/src/test/java/com/fr/design/mainframe/ReuseTriggerPointManagerTest.java
  22. 13
      designer-realize/src/main/java/com/fr/design/actions/utils/ReportActionUtils.java
  23. 3
      designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/CellStylePane.java
  24. 3
      designer-realize/src/main/java/com/fr/grid/Grid.java

19
designer-base/src/main/java/com/fr/design/DesignerEnvManager.java

@ -18,6 +18,7 @@ import com.fr.design.file.HistoryTemplateListPane;
import com.fr.design.fun.DesignerPortProvider;
import com.fr.design.i18n.Toolkit;
import com.fr.design.locale.impl.ProductImproveMark;
import com.fr.design.mainframe.reuse.ComponentReuseNotificationInfo;
import com.fr.design.mainframe.vcs.VcsConfigManager;
import com.fr.design.notification.SnapChatConfig;
import com.fr.design.port.DesignerPortContext;
@ -196,6 +197,8 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
// 开启内嵌web页面的调试窗口
private boolean openDebug = false;
private ComponentReuseNotificationInfo notificationInfo = ComponentReuseNotificationInfo.getInstance();
/**
* DesignerEnvManager.
*/
@ -1561,13 +1564,15 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
readRecentColor(reader);
} else if ("OpenDebug".equals(name)) {
readOpenDebug(reader);
} else if (name.equals(ComponentReuseNotificationInfo.XML_TAG)) {
readComponentReuseNotificationInfo(reader);
} else if (name.equals(DesignerPushUpdateConfigManager.XML_TAG)) {
readDesignerPushUpdateAttr(reader);
} else if (name.equals(vcsConfigManager.XML_TAG)) {
readVcsAttr(reader);
} else if (DesignerPort.XML_TAG.equals(name)) {
readDesignerPort(reader);
}else if (name.equals(SnapChatConfig.XML_TAG)) {
} else if (name.equals(SnapChatConfig.XML_TAG)) {
readSnapChatConfig(reader);
} else {
readLayout(reader, name);
@ -1575,6 +1580,11 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
}
}
private void readComponentReuseNotificationInfo(XMLableReader reader){
reader.readXMLObject(this.notificationInfo);
}
private void readSnapChatConfig(XMLableReader reader) {
reader.readXMLObject(this.snapChatConfig = SnapChatConfig.getInstance());
}
@ -1795,9 +1805,16 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
writeVcsAttr(writer);
writeDesignerPort(writer);
writeSnapChatConfig(writer);
writeComponentReuseNotificationInfo(writer);
writer.end();
}
private void writeComponentReuseNotificationInfo(XMLPrintWriter writer) {
if (this.notificationInfo != null) {
this.notificationInfo.writeXML(writer);
}
}
private void writeSnapChatConfig(XMLPrintWriter writer) {
if (this.snapChatConfig != null) {

39
designer-base/src/main/java/com/fr/design/mainframe/ComponentReuseNotifyUtil.java

@ -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"));
}
}
}

15
designer-base/src/main/java/com/fr/design/mainframe/DesignOperationEvent.java

@ -0,0 +1,15 @@
package com.fr.design.mainframe;
import com.fr.event.Event;
import com.fr.event.Null;
/**
* Created by kerry on 4/28/21
*/
public enum DesignOperationEvent implements Event<Null> {
CELL_STYLE_MODIFY,
CELL_IMAGE_VALUE_MODIFY
}

39
designer-base/src/main/java/com/fr/design/mainframe/EastRegionContainerPane.java

@ -299,7 +299,12 @@ public class EastRegionContainerPane extends UIEastResizableContainer {
// 组件库
PropertyItem widgetLib = new PropertyItem(KEY_WIDGET_LIB, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Widget_Library"),
"widgetlib", new PropertyMode[]{PropertyMode.FORM},
new PropertyMode[]{PropertyMode.FORM});
new PropertyMode[]{PropertyMode.FORM}, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
ComponentReuseNotifyUtil.enterWidgetLibExtraAction();
}
});
// 权限编辑
PropertyItem authorityEdition = new PropertyItem(KEY_AUTHORITY_EDITION, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Permissions_Edition"),
"authorityedit", new PropertyMode[]{PropertyMode.AUTHORITY_EDITION_DISABLED},
@ -595,6 +600,7 @@ public class EastRegionContainerPane extends UIEastResizableContainer {
if (propertyItem.isVisible() && propertyItem.isEnabled() && !propertyItem.isPoppedOut()) {
propertyCard.show(rightPane, tabName);
propertyItem.setTabButtonSelected();
propertyItem.processSnapChat();
//从单元格菜单过来也要关闭弹出窗
hideCurrentPopupPane();
}
@ -713,19 +719,30 @@ public class EastRegionContainerPane extends UIEastResizableContainer {
private String iconSuffix = ICON_SUFFIX_NORMAL; // normal, diabled, selected, 三者之一
private final Color selectedBtnBackground = new Color(0xF5F5F7);
private Color originBtnBackground;
private ActionListener actionListener;
public PropertyItem(String name, String title, String btnIconName, PropertyMode[] visibleModes, PropertyMode[] enableModes) {
this(name, title, btnIconName, ICON_BASE_DIR, visibleModes, enableModes, null, null);
}
public PropertyItem(String name, String title, String btnIconName, PropertyMode[] visibleModes, PropertyMode[] enableModes, ActionListener actionListener) {
this(name, title, btnIconName, ICON_BASE_DIR, visibleModes, enableModes, null, null, actionListener);
}
public PropertyItem(String name, String title, String btnIconName, String iconBaseDir, PropertyMode[] visibleModes, PropertyMode[] enableModes, SnapChat snapChat, PromptWindow promptWindow) {
this(name, title, btnIconName, iconBaseDir, visibleModes, enableModes, snapChat, promptWindow, null);
}
public PropertyItem(String name, String title, String btnIconName, String iconBaseDir, PropertyMode[] visibleModes, PropertyMode[] enableModes, SnapChat snapChat, PromptWindow promptWindow, ActionListener actionListener) {
this.name = name;
this.title = title;
this.btnIconName = btnIconName;
this.iconBaseDir = iconBaseDir;
this.snapChat = snapChat;
this.promptWindow = promptWindow;
this.actionListener = actionListener;
initButton();
initPropertyPanel();
initModes(visibleModes, enableModes);
@ -956,17 +973,25 @@ public class EastRegionContainerPane extends UIEastResizableContainer {
popupFixedPane();
}
setTabButtonSelected();
if (snapChat != null && !snapChat.hasRead()) {
snapChat.markRead();
if (promptWindow != null) {
promptWindow.showWindow();
}
}
processSnapChat();
}
});
if (actionListener != null) {
button.addActionListener(actionListener);
}
button.setToolTipText(title);
}
public void processSnapChat(){
if (snapChat != null && !snapChat.hasRead()) {
snapChat.markRead();
if (promptWindow != null) {
promptWindow.showWindow();
}
}
}
public UIButton getButton() {
return button;
}

69
designer-base/src/main/java/com/fr/design/mainframe/reuse/ComponentReuseNotificationInfo.java

@ -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();
}
}

106
designer-base/src/main/java/com/fr/design/mainframe/toast/DesignerToastMsgUtil.java

@ -0,0 +1,106 @@
package com.fr.design.mainframe.toast;
import com.fr.base.BaseUtils;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.DesignerContext;
import com.fr.stable.Constants;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JEditorPane;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
/**
* Created by kerry on 5/6/21
*/
public class DesignerToastMsgUtil {
private static final int MIN_WIDTH = 134;
private static final int MAX_WIDTH = 454;
private static final Icon PROMPT_ICON = BaseUtils.readIcon("/com/fr/design/images/toast/toast_prompt.png");
private static final Icon WARNING_ICON = BaseUtils.readIcon("/com/fr/design/images/toast/toast_warning.png");
private DesignerToastMsgUtil() {
}
public static void toastPrompt(JPanel contendPane) {
toastPane(PROMPT_ICON, contendPane);
}
public static void toastWarning(JPanel contendPane) {
toastPane(WARNING_ICON, contendPane);
}
public static void toastPrompt(String promptInfo) {
toastPrompt(toastPane(promptInfo));
}
public static void toastWarning(String warningInfo) {
toastWarning(toastPane(warningInfo));
}
private static JPanel toastPane(String text) {
UILabel promptLabel = new UILabel("<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();
}
}

154
designer-base/src/main/java/com/fr/design/mainframe/toast/ToastMsgDialog.java

@ -0,0 +1,154 @@
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));
System.out.println(ToastMsgDialog.this.getHeight());
}
}, 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();
}
}

BIN
designer-base/src/main/resources/com/fr/design/images/form/designer/widget_apply_icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 B

BIN
designer-base/src/main/resources/com/fr/design/images/toast/reuse_icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 377 B

BIN
designer-base/src/main/resources/com/fr/design/images/toast/toast_prompt.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 608 B

BIN
designer-base/src/main/resources/com/fr/design/images/toast/toast_warning.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 622 B

46
designer-base/src/test/java/com/fr/design/mainframe/reuse/ComponentReuseNotificationInfoTest.java

@ -0,0 +1,46 @@
package com.fr.design.mainframe.reuse;
import com.fr.stable.xml.XMLPrintWriter;
import com.fr.stable.xml.XMLableReader;
import com.fr.third.javax.xml.stream.XMLStreamException;
import org.junit.Assert;
import org.junit.Test;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
/**
* Created by kerry on 5/10/21
*/
public class ComponentReuseNotificationInfoTest {
@Test
public void testReadXML() {
try {
XMLableReader xmlReader = XMLableReader.createXMLableReader(new StringReader("<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());
}
}

25
designer-form/src/main/java/com/fr/design/designer/treeview/ComponentTreeCellRenderer.java

@ -1,17 +1,24 @@
package com.fr.design.designer.treeview;
import com.fr.base.BaseUtils;
import com.fr.base.iofile.attr.ExtendSharableAttrMark;
import com.fr.design.constants.UIConstants;
import com.fr.design.designer.creator.XCreator;
import com.fr.design.designer.creator.XCreatorUtils;
import com.fr.form.ui.AbstractBorderStyleWidget;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.StringUtils;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JTree;
import javax.swing.tree.DefaultTreeCellRenderer;
import java.awt.Component;
import java.awt.Graphics;
public class ComponentTreeCellRenderer extends DefaultTreeCellRenderer {
private boolean needAddShareIcon = false;
private static final Icon SHARE_ICON = BaseUtils.readIcon("/com/fr/design/images/toast/icon_reuse.png");
public ComponentTreeCellRenderer() {
}
@ -31,13 +38,31 @@ public class ComponentTreeCellRenderer extends DefaultTreeCellRenderer {
}
if (icon != null) {
setIcon(icon);
this.needAddShareIcon = isShareWidget((XCreator) value);
}
}
this.setBorder(BorderFactory.createEmptyBorder(1, 0, 1, 0));
this.setBackgroundNonSelectionColor(UIConstants.TREE_BACKGROUND);
return this;
}
private boolean isShareWidget(XCreator xCreator) {
if (!xCreator.toData().acceptType(AbstractBorderStyleWidget.class)) {
return false;
}
ExtendSharableAttrMark attrMark = ((AbstractBorderStyleWidget) xCreator.toData()).getWidgetAttrMark(ExtendSharableAttrMark.XML_TAG);
return attrMark != null && StringUtils.isNotEmpty(attrMark.getShareId());
}
public void paint(Graphics g) {
super.paint(g);
if (needAddShareIcon) {
SHARE_ICON.paintIcon(this, g, 10, 0);
}
}
@Override
public Icon getClosedIcon() {
return getIcon();

43
designer-form/src/main/java/com/fr/design/mainframe/FormParaWidgetPane.java

@ -15,6 +15,7 @@ import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.icontainer.UIScrollPane;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.imenu.UIPopupMenu;
import com.fr.design.i18n.Toolkit;
import com.fr.design.module.DesignModuleFactory;
import com.fr.design.utils.gui.LayoutUtils;
import com.fr.form.ui.UserDefinedWidgetConfig;
@ -35,6 +36,8 @@ import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.SwingConstants;
import java.awt.Cursor;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
@ -233,8 +236,48 @@ public class FormParaWidgetPane extends JPanel {
}
add(createWidgetCombinationPane(widgetPane, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_ToolBar_Widget")));
add(createJSeparator());
add(createComponentReuseToolPane());
add(createJSeparator());
}
private JPanel createComponentReuseToolPane() {
JPanel jPanel = new JPanel(new BorderLayout(17, 10));
UILabel uiLabel = new UILabel(BaseUtils.readIcon("/com/fr/design/images/form/designer/widget_apply_icon.png"));
jPanel.addMouseListener(new MouseListener() {
@Override
public void mouseClicked(MouseEvent e) {
ComponentReuseNotifyUtil.enterWidgetLib();
}
@Override
public void mousePressed(MouseEvent e) {
jPanel.setBackground(Color.decode("#419BF9"));
}
@Override
public void mouseReleased(MouseEvent e) {
jPanel.setBackground(null);
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
});
jPanel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
jPanel.add(uiLabel, BorderLayout.NORTH);
jPanel.add(new UILabel(Toolkit.i18nText("Fine-Design_Component_Reuse_Apply_Widget")), BorderLayout.CENTER);
jPanel.setToolTipText(Toolkit.i18nText("Fine-Design_Component_Reuse_Apply_Widget"));
return jPanel;
}
private void loadPredefinedWidget() {
predifinedwidgeList.clear();
if (designer != null) {

7
designer-form/src/main/java/com/fr/design/mainframe/JForm.java

@ -319,6 +319,13 @@ public class JForm extends JTemplate<Form, FormUndoState> implements BaseJForm<F
}
String key = jt.getEditingFILE().getPath() + "-" + jt.getTarget().getTemplateID();
FormHierarchyTreePane.getInstance().removeTreePath(key);
ReuseTriggerPointManager.getInstance().removeJForm(JForm.this);
}
@Override
public void templateOpened(JTemplate<?, ?> jt) {
ReuseTriggerPointManager.getInstance().registerJForm(JForm.this);
}
});
return tabCenterPane;

214
designer-form/src/main/java/com/fr/design/mainframe/ReuseTriggerPointManager.java

@ -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;
}
}

27
designer-form/src/main/java/com/fr/design/mainframe/adaptve/config/ReuseNotifyInfo.java

@ -0,0 +1,27 @@
package com.fr.design.mainframe.adaptve.config;
/**
* Created by kerry on 5/7/21
*/
public class ReuseNotifyInfo {
private int cellStyleModifiedNumber = 0;
private int cellImageValueNumber = 0;
public void addCellStyleModify() {
cellStyleModifiedNumber++;
}
public void addCellImageValueModify() {
cellImageValueNumber++;
}
public boolean matchCondition() {
return cellStyleModifiedNumber >= 3 || cellImageValueNumber >= 1;
}
public void reset() {
this.cellImageValueNumber = 0;
this.cellStyleModifiedNumber = 0;
}
}

20
designer-form/src/main/java/com/fr/design/mainframe/adaptve/config/TriggerPointProvider.java

@ -0,0 +1,20 @@
package com.fr.design.mainframe.adaptve.config;
import com.fr.event.Event;
/**
* Created by kerry on 4/29/21
*/
public interface TriggerPointProvider {
/**
* 触发后的操作
*/
void triggerAction();
/**
* 触发事件
* @return
*/
Event triggerEvent();
}

28
designer-form/src/main/java/com/fr/design/mainframe/adaptve/config/impl/CellStyleTriggerPoint.java

@ -0,0 +1,28 @@
package com.fr.design.mainframe.adaptve.config.impl;
import com.fr.design.mainframe.DesignOperationEvent;
import com.fr.design.mainframe.ReuseTriggerPointManager;
import com.fr.design.mainframe.adaptve.config.ReuseNotifyInfo;
import com.fr.design.mainframe.adaptve.config.TriggerPointProvider;
import com.fr.event.Event;
/**
* Created by kerry on 5/7/21
*/
public class CellStyleTriggerPoint implements TriggerPointProvider {
@Override
public void triggerAction() {
ReuseNotifyInfo notifyInfo = ReuseTriggerPointManager.getInstance().getReuseNotifyInfo();
if (notifyInfo == null) {
return;
}
notifyInfo.addCellStyleModify();
ReuseTriggerPointManager.getInstance().reuseNotify(notifyInfo);
}
@Override
public Event triggerEvent() {
return DesignOperationEvent.CELL_STYLE_MODIFY;
}
}

27
designer-form/src/main/java/com/fr/design/mainframe/adaptve/config/impl/CellValueImageChangeTriggerPoint.java

@ -0,0 +1,27 @@
package com.fr.design.mainframe.adaptve.config.impl;
import com.fr.design.mainframe.DesignOperationEvent;
import com.fr.design.mainframe.ReuseTriggerPointManager;
import com.fr.design.mainframe.adaptve.config.ReuseNotifyInfo;
import com.fr.design.mainframe.adaptve.config.TriggerPointProvider;
import com.fr.event.Event;
/**
* Created by kerry on 5/7/21
*/
public class CellValueImageChangeTriggerPoint implements TriggerPointProvider {
@Override
public void triggerAction() {
ReuseNotifyInfo notifyInfo = ReuseTriggerPointManager.getInstance().getReuseNotifyInfo();
if (notifyInfo == null) {
return;
}
notifyInfo.addCellImageValueModify();
ReuseTriggerPointManager.getInstance().reuseNotify(notifyInfo);
}
@Override
public Event triggerEvent() {
return DesignOperationEvent.CELL_IMAGE_VALUE_MODIFY;
}
}

45
designer-form/src/test/java/com/fr/design/mainframe/ReuseTriggerPointManagerTest.java

@ -0,0 +1,45 @@
package com.fr.design.mainframe;
import com.fr.design.mainframe.reuse.ComponentReuseNotificationInfo;
import org.junit.Assert;
import org.junit.Test;
/**
* Created by kerry on 5/10/21
*/
public class ReuseTriggerPointManagerTest {
private static final long ONE_WEEK_TIME = 7 * 24 * 3600 * 1000L;
@Test
public void testNeedTrigger() {
ComponentReuseNotificationInfo notificationInfo = ComponentReuseNotificationInfo.getInstance();
notificationInfo.setNotifiedNumber(0);
Assert.assertTrue(ReuseTriggerPointManager.getInstance().needTrigger());
notificationInfo.setNotifiedNumber(1);
Assert.assertTrue(ReuseTriggerPointManager.getInstance().needTrigger());
notificationInfo.setNotifiedNumber(2);
Assert.assertFalse(ReuseTriggerPointManager.getInstance().needTrigger());
notificationInfo.setNotifiedNumber(0);
notificationInfo.setLastNotifyTime(System.currentTimeMillis());
Assert.assertFalse(ReuseTriggerPointManager.getInstance().needTrigger());
notificationInfo.setNotifiedNumber(1);
notificationInfo.setLastNotifyTime(System.currentTimeMillis());
Assert.assertFalse(ReuseTriggerPointManager.getInstance().needTrigger());
notificationInfo.setNotifiedNumber(1);
notificationInfo.setLastNotifyTime(System.currentTimeMillis() - ONE_WEEK_TIME - 1);
Assert.assertTrue(ReuseTriggerPointManager.getInstance().needTrigger());
notificationInfo.setNotifiedNumber(2);
notificationInfo.setLastNotifyTime(System.currentTimeMillis());
Assert.assertFalse(ReuseTriggerPointManager.getInstance().needTrigger());
}
}

13
designer-realize/src/main/java/com/fr/design/actions/utils/ReportActionUtils.java

@ -2,7 +2,9 @@ package com.fr.design.actions.utils;
import com.fr.base.Style;
import com.fr.design.actions.cell.style.StyleActionInterface;
import com.fr.design.mainframe.DesignOperationEvent;
import com.fr.design.mainframe.ElementCasePane;
import com.fr.event.EventDispatcher;
import com.fr.grid.selection.CellSelection;
import com.fr.grid.selection.FloatSelection;
import com.fr.grid.selection.Selection;
@ -50,9 +52,7 @@ public class ReportActionUtils {
@Override
public void dealWith(CellElement editCellElement) {
Style style2Mod = editCellElement.getStyle();
editCellElement.setStyle(
styleActionInterface.executeStyle(style2Mod, selectedStyle));
updateCellStyle(editCellElement, styleActionInterface.executeStyle(style2Mod, selectedStyle));
}
});
}
@ -119,4 +119,9 @@ public class ReportActionUtils {
//peter:直接返回当前编辑元素的Style
return editCellElement.getStyle();
}
}
public static void updateCellStyle(CellElement cellElement, Style style){
cellElement.setStyle(style);
EventDispatcher.fire(DesignOperationEvent.CELL_STYLE_MODIFY);
}
}

3
designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/CellStylePane.java

@ -1,6 +1,7 @@
package com.fr.design.mainframe.cell.settingpane;
import com.fr.base.Style;
import com.fr.design.actions.utils.ReportActionUtils;
import com.fr.design.constants.UIConstants;
import com.fr.design.mainframe.cell.settingpane.style.StylePane;
import com.fr.design.style.BorderUtils;
@ -63,7 +64,7 @@ public class CellStylePane extends AbstractCellAttrPane {
@Override
public void updateBean(TemplateCellElement cellElement) {
cellElement.setStyle(stylePane.updateBean());
ReportActionUtils.updateCellStyle(cellElement, stylePane.updateBean());
}
@Override

3
designer-realize/src/main/java/com/fr/grid/Grid.java

@ -15,9 +15,11 @@ import com.fr.design.constants.UIConstants;
import com.fr.design.file.HistoryTemplateListPane;
import com.fr.design.fun.GridUIProcessor;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.mainframe.DesignOperationEvent;
import com.fr.design.mainframe.ElementCasePane;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.event.EventDispatcher;
import com.fr.general.ComparatorUtils;
import com.fr.grid.event.CellEditorEvent;
import com.fr.grid.event.CellEditorListener;
@ -1083,6 +1085,7 @@ public class Grid extends BaseGridComponent {
imageChange = true;
}
if (styleChange || imageChange) {
EventDispatcher.fire(DesignOperationEvent.CELL_IMAGE_VALUE_MODIFY);
return true;
}
} else {

Loading…
Cancel
Save