Browse Source

Merge branch 'feature/10.0' of ssh://code.fineres.com:7999/~tommy/design into feature/10.0

feature/10.0
kuangshuai 3 years ago
parent
commit
7f041d1b0d
  1. 485
      designer-base/src/main/java/com/fr/design/gui/controlpane/UIListGroupControlPane.java
  2. 29
      designer-base/src/main/java/com/fr/design/mod/ContentChange.java
  3. 66
      designer-base/src/main/java/com/fr/design/mod/ContentObjectManager.java
  4. 20
      designer-base/src/main/java/com/fr/design/mod/ContentReplaceUtil.java
  5. 13
      designer-base/src/main/java/com/fr/design/mod/ContentReplacer.java
  6. 108
      designer-base/src/main/java/com/fr/design/mod/ContentReplacerCenter.java
  7. 33
      designer-base/src/main/java/com/fr/design/mod/ModClassFilter.java
  8. 14
      designer-base/src/main/java/com/fr/design/mod/bean/ChangeItem.java
  9. 33
      designer-base/src/main/java/com/fr/design/mod/bean/ContentChangeItem.java
  10. 13
      designer-base/src/main/java/com/fr/design/mod/event/ModifyEvent.java
  11. 12
      designer-base/src/main/java/com/fr/design/mod/event/TableDataModifyEvent.java
  12. 12
      designer-base/src/main/java/com/fr/design/mod/event/WidgetNameModifyEvent.java
  13. 16
      designer-base/src/main/java/com/fr/design/mod/impl/change/ChartHyperRelateCellLinkContentChange.java
  14. 16
      designer-base/src/main/java/com/fr/design/mod/impl/change/ChartHyperRelateFloatLinkContentChange.java
  15. 30
      designer-base/src/main/java/com/fr/design/mod/impl/change/ChartHyperRelateLinkContentChange.java
  16. 37
      designer-base/src/main/java/com/fr/design/mod/impl/change/FormulaContentChange.java
  17. 36
      designer-base/src/main/java/com/fr/design/mod/impl/change/JavaScriptContentChange.java
  18. 35
      designer-base/src/main/java/com/fr/design/mod/impl/change/VanChartHtmlLabelContentChange.java
  19. 21
      designer-base/src/main/java/com/fr/design/mod/impl/repalce/ChartHyperRelateLink4WidgetNameContentReplacer.java
  20. 22
      designer-base/src/main/java/com/fr/design/mod/impl/repalce/Formula4TableDataNameContentReplacer.java
  21. 21
      designer-base/src/main/java/com/fr/design/mod/impl/repalce/Formula4WidgetNameContentReplacer.java
  22. 22
      designer-base/src/main/java/com/fr/design/mod/impl/repalce/JavaScriptContentReplacer.java
  23. 22
      designer-base/src/main/java/com/fr/design/mod/impl/repalce/VanChartHtmlLabelContentReplacer.java
  24. 12
      designer-form/src/main/java/com/fr/design/designer/beans/models/ModelUtil.java
  25. 449
      designer-form/src/main/java/com/fr/design/gui/controlpane/EventPropertyPane.java
  26. 9
      designer-form/src/main/java/com/fr/design/mainframe/FormCreatorDropTarget.java
  27. 132
      designer-realize/src/main/java/com/fr/design/mainframe/app/DesignerAppUtils.java
  28. 19
      designer-realize/src/main/java/com/fr/design/mainframe/app/FormApp.java
  29. 85
      designer-realize/src/main/java/com/fr/design/widget/WidgetEventPane.java
  30. 2
      designer-realize/src/main/java/com/fr/start/module/DesignerActivator.java
  31. 106
      designer-realize/src/test/java/com/fr/design/mainframe/app/DesignerAppUtilsTest.java

485
designer-base/src/main/java/com/fr/design/gui/controlpane/UIListGroupControlPane.java

@ -0,0 +1,485 @@
package com.fr.design.gui.controlpane;
import com.fr.design.beans.BasicBeanPane;
import com.fr.design.constants.UIConstants;
import com.fr.design.gui.icontainer.UIScrollPane;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.ilist.JNameEdList;
import com.fr.design.gui.ilist.ListModelElement;
import com.fr.design.gui.ilist.ModNameActionListener;
import com.fr.design.gui.ilist.UINameEdList;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.widget.EventCreator;
import com.fr.form.event.Listener;
import com.fr.form.ui.Widget;
import com.fr.general.NameObject;
import com.fr.report.web.util.ReportEngineEventMapping;
import com.fr.stable.ArrayUtils;
import com.fr.stable.Nameable;
import com.fr.stable.StringUtils;
import javax.swing.BorderFactory;
import javax.swing.DefaultListModel;
import javax.swing.JPanel;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* Created by kerry on 5/31/21
*/
public abstract class UIListGroupControlPane extends UIControlPane implements ListControlPaneProvider {
private boolean isPopulating = false;
private UINameEdList selectNameEdList;
private Map<String, ListWrapperPane> nameEdListMap = new HashMap<>();
private CommonShortCutHandlers commonHandlers;
private ListControlPaneHelper helper;
private JPanel contentPane;
public JPanel getContentPane() {
return contentPane;
}
private ListControlPaneHelper getHelper() {
if (helper == null) {
helper = ListControlPaneHelper.newInstance(this);
}
return helper;
}
private CommonShortCutHandlers getCommonHandlers() {
if (commonHandlers == null) {
commonHandlers = CommonShortCutHandlers.newInstance(this);
}
return commonHandlers;
}
public boolean isPopulating() {
return isPopulating;
}
@Override
protected void initLeftPane(JPanel leftPane) {
leftPane.add(new UIScrollPane(contentPane = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, FlowLayout.LEADING, 0, 0)), BorderLayout.CENTER);
}
protected void refreshPane(Widget widget, NameableCreator[] creators) {
refreshContentPane(widget.supportedEvents());
refreshNameableCreator(creators);
populateNameObjects(widget);
}
private void refreshContentPane(String[] supportedEvents) {
for (String event : supportedEvents) {
if (nameEdListMap.containsKey(event)) {
continue;
}
UINameEdList list = createJNameList(event);
ListWrapperPane wrapperPane = new ListWrapperPane(switchLang(event), list);
if (this.selectNameEdList == null) {
this.selectNameEdList = wrapperPane.getNameEdList();
}
contentPane.add(wrapperPane);
nameEdListMap.put(event, wrapperPane);
}
}
protected void populateNameObjects(Widget widget) {
ArrayList<NameObject> nameObjectList = new ArrayList<>();
for (int i = 0, size = widget.getListenerSize(); i < size; i++) {
Listener listener = widget.getListener(i);
if (!listener.isDefault()) {
nameObjectList.add(i, new NameObject(switchLang(listener.getEventName()) + (i + 1), listener));
}
}
populate(getHelper().processCatalog(nameObjectList));
checkButtonEnabled();
this.repaint();
}
private void populate(Map<String, List<NameObject>> map) {
isPopulating = true; // 加一个标识位,避免切换单元格时,触发 saveSettings
Iterator<Map.Entry<String, List<NameObject>>> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, List<NameObject>> entry = iterator.next();
List<NameObject> valueList = entry.getValue();
ListWrapperPane eventListWrapperPane = nameEdListMap.get(entry.getKey());
populateChildNameList(eventListWrapperPane.getNameEdList(), valueList.toArray(new NameObject[valueList.size()]));
}
this.checkButtonEnabled();
refreshEventListWrapperPane();
isPopulating = false;
}
private void refreshEventListWrapperPane() {
Iterator<Map.Entry<String, ListWrapperPane>> iterator = nameEdListMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, ListWrapperPane> entry = iterator.next();
ListWrapperPane eventListWrapperPane = entry.getValue();
UINameEdList nameEdList = eventListWrapperPane.getNameEdList();
int listSize = nameEdList.getModel().getSize();
if (this.selectNameEdList.getModel().getSize() == 0 && listSize > 0) {
this.selectNameEdList = nameEdList;
}
eventListWrapperPane.setVisible(listSize > 0);
}
if (this.selectNameEdList != null) {
this.selectNameEdList.setSelectedIndex(0);
}
this.repaint();
}
private void populateChildNameList(UINameEdList nameableList, Nameable[] nameableArray) {
nameableList.getCellEditor().stopCellEditing();
DefaultListModel listModel = (DefaultListModel) nameableList.getModel();
listModel.removeAllElements();
if (ArrayUtils.isEmpty(nameableArray)) {
isPopulating = false;
return;
}
listModel.setSize(nameableArray.length);
for (int i = 0; i < nameableArray.length; i++) {
listModel.set(i, new ListModelElement(nameableArray[i]));
}
}
private UINameEdList createJNameList(String text) {
UINameEdList nameEdList = new UINameEdList(new DefaultListModel()) {
@Override
protected void doAfterLostFocus() {
((JControlUpdatePane) controlUpdatePane).update();
}
@Override
protected void doAfterStopEditing() {
saveSettings();
}
};
nameEdList.setCellRenderer(new UINameableListCellRenderer(true, this.creators));
nameEdList.setName(text);
nameEdList.setSelectionBackground(UIConstants.ATTRIBUTE_PRESS);
nameEdList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
nameEdList.addMouseListener(new MouseAdapter() {
@Override
public void mouseReleased(MouseEvent e) {
selectNameEdList = nameEdList;
updateUINameListSelect();
}
});
nameEdList.addMouseListener(getHelper().getListMouseListener(nameEdList, this));
nameEdList.addModNameActionListener(new ModNameActionListener() {
@Override
public void nameModed(int index, String oldName, String newName) {
saveSettings();
}
});
nameEdList.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent evt) {
// richie:避免多次update和populate大大降低效率
if (!evt.getValueIsAdjusting()) {
// shoc 切换的时候加检验
if (hasInvalid(false)) {
return;
}
((JControlUpdatePane) UIListGroupControlPane.this.controlUpdatePane).update();
((JControlUpdatePane) UIListGroupControlPane.this.controlUpdatePane).populate();
UIListGroupControlPane.this.checkButtonEnabled();
}
}
});
nameEdList.getModel().addListDataListener(new ListDataListener() {
@Override
public void intervalAdded(ListDataEvent e) {
saveSettings();
}
@Override
public void intervalRemoved(ListDataEvent e) {
saveSettings();
}
@Override
public void contentsChanged(ListDataEvent e) {
saveSettings();
}
});
return nameEdList;
}
private void updateUINameListSelect() {
Iterator<Map.Entry<String, ListWrapperPane>> iterator = nameEdListMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, ListWrapperPane> entry = iterator.next();
UINameEdList nameEdList = entry.getValue().getNameEdList();
if (nameEdList != selectNameEdList) {
nameEdList.clearSelection();
}
}
}
@Override
public void checkButtonEnabled() {
getHelper().checkButtonEnabled();
}
private String switchLang(String eventName) {
// 在 properties 文件中找到相应的 key 值
String localeKey = ReportEngineEventMapping.getLocaleName(eventName);
return com.fr.design.i18n.Toolkit.i18nText(localeKey);
}
/**
* 生成不重复的名字
*
* @param prefix 名字前缀
* @return 名字
*/
@Override
public String createUnrepeatedName(String prefix) {
return getCommonHandlers().createUnrepeatedName(prefix);
}
private void updateSelectedNameList(NameableCreator creator) {
String eventName = ((EventCreator) creator).getEventName();
ListWrapperPane wrapperPane = nameEdListMap.get(eventName);
wrapperPane.setVisible(true);
setSelectNameEdList(wrapperPane.getNameEdList());
}
private void setSelectNameEdList(UINameEdList nameEdList) {
if (this.selectNameEdList != null) {
this.selectNameEdList.clearSelection();
}
this.selectNameEdList = nameEdList;
}
@Override
public void onAddItem(NameableCreator creator) {
updateSelectedNameList(creator);
getCommonHandlers().onAddItem(creator);
}
@Override
public void onRemoveItem() {
getCommonHandlers().onRemoveItem();
refreshEventListWrapperPane();
}
@Override
public void onCopyItem() {
getCommonHandlers().onCopyItem();
}
@Override
public void onMoveUpItem() {
getCommonHandlers().onMoveUpItem();
}
@Override
public void onMoveDownItem() {
getCommonHandlers().onMoveDownItem();
}
@Override
public void onSortItem(boolean isAtoZ) {
Iterator<Map.Entry<String, ListWrapperPane>> iterator = nameEdListMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, ListWrapperPane> entry = iterator.next();
UINameEdList nameEdList = entry.getValue().getNameEdList();
getCommonHandlers().onSortItem(isAtoZ, nameEdList);
}
}
@Override
public boolean isItemSelected() {
return getModel().getSize() > 0 && getSelectedIndex() != -1;
}
@Override
protected JPanel createControlUpdatePane() {
return JControlUpdatePane.newInstance(this);
}
@Override
public Nameable[] update() {
java.util.List<Nameable> res = new java.util.ArrayList<Nameable>();
getControlUpdatePane().update();
Iterator<Map.Entry<String, ListWrapperPane>> iterator = nameEdListMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, ListWrapperPane> entry = iterator.next();
UINameEdList nameEdList = entry.getValue().getNameEdList();
DefaultListModel listModel = (DefaultListModel) nameEdList.getModel();
for (int i = 0, len = listModel.getSize(); i < len; i++) {
res.add(((ListModelElement) listModel.getElementAt(i)).wrapper);
}
}
return res.toArray(new Nameable[0]);
}
@Override
public abstract NameableCreator[] createNameableCreators();
@Override
public abstract void saveSettings();
public BasicBeanPane createPaneByCreators(NameableCreator creator) {
try {
return creator.getUpdatePane().newInstance();
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
public BasicBeanPane createPaneByCreators(NameableCreator creator, String string) {
Constructor constructor = null;
try {
constructor = creator.getUpdatePane().getDeclaredConstructor(new Class[]{String.class});
constructor.setAccessible(true);
return (BasicBeanPane) constructor.newInstance(string);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}
@Override
public DefaultListModel getModel() {
if (this.selectNameEdList == null) {
return new DefaultListModel();
}
return (DefaultListModel) this.selectNameEdList.getModel();
}
/**
* 检查是否符合规范
*
* @throws Exception
*/
@Override
public void checkValid() throws Exception {
((JControlUpdatePane) this.controlUpdatePane).checkValid();
}
@Override
public boolean hasInvalid(boolean isAdd) {
return getHelper().hasInvalid(isAdd);
}
public void addNameable(Nameable nameable, int index) {
getHelper().addNameable(nameable, index);
popupEditDialog();
}
/**
* 设置选中项
*
* @param index 选中项的序列号
*/
public void setSelectedIndex(int index) {
if (this.selectNameEdList != null) {
this.selectNameEdList.setSelectedIndex(index);
}
}
@Override
public int getSelectedIndex() {
if (this.selectNameEdList == null) {
return -1;
}
return this.selectNameEdList.getSelectedIndex();
}
@Override
public ListModelElement getSelectedValue() {
if (this.selectNameEdList == null) {
return null;
}
return (ListModelElement) this.selectNameEdList.getSelectedValue();
}
@Override
public JControlUpdatePane getControlUpdatePane() {
return (JControlUpdatePane) controlUpdatePane;
}
@Override
public JNameEdList getNameableList() {
return this.selectNameEdList;
}
private void popupEditDialog() {
getHelper().popupEditDialog(null, this.selectNameEdList, this);
}
protected String getWrapperLabelText(){
return StringUtils.EMPTY;
}
private class ListWrapperPane extends JPanel {
private UINameEdList nameEdList;
public ListWrapperPane(String labelText, UINameEdList nameEdList) {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
UILabel label = new UILabel(labelText + getWrapperLabelText());
label.setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 0));
label.setBackground(Color.decode("#FFFFFF"));
label.setPreferredSize(new Dimension(224, 26));
this.nameEdList = nameEdList;
this.add(label, BorderLayout.NORTH);
this.add(this.nameEdList, BorderLayout.CENTER);
}
public UINameEdList getNameEdList() {
return this.nameEdList;
}
}
}

29
designer-base/src/main/java/com/fr/design/mod/ContentChange.java

@ -0,0 +1,29 @@
package com.fr.design.mod;
import com.fr.design.mod.bean.ChangeItem;
import java.util.Map;
/**
*
* @author hades
* @version 10.0
* Created by hades on 2021/4/27
*/
public interface ContentChange<T> {
/**
* 标识内容替换类型
*
* @return
*/
String type();
/**
* 替换详情信息
*
* @return
*/
Map<ChangeItem, ContentReplacer<T>> changeInfo();
}

66
designer-base/src/main/java/com/fr/design/mod/ContentObjectManager.java

@ -0,0 +1,66 @@
package com.fr.design.mod;
import com.fr.base.Formula;
import com.fr.chart.web.ChartHyperRelateCellLink;
import com.fr.chart.web.ChartHyperRelateFloatLink;
import com.fr.design.file.filter.ClassFilter;
import com.fr.invoke.ClassHelper;
import com.fr.js.JavaScriptImpl;
import com.fr.plugin.chart.base.VanChartHtmlLabel;
import com.fr.stable.Filter;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.jetbrains.annotations.Nullable;
/**
* 管理所有需要替换内容的对象
*
* @author hades
* @version 10.0
* Created by hades on 2021/4/28
*/
public class ContentObjectManager {
private static ContentObjectManager INSTANCE = new ContentObjectManager();
public static ContentObjectManager getInstance() {
return INSTANCE;
}
/**
* 放置所有需要替换内容的对象
*/
private Map<String, Set<Object>> objectMap;
private final Set<String> set = new HashSet<>();
private ContentObjectManager() {
set.add(Formula.class.getName());
set.add(JavaScriptImpl.class.getName());
set.add(ChartHyperRelateCellLink.class.getName());
set.add(ChartHyperRelateFloatLink.class.getName());
set.add(VanChartHtmlLabel.class.getName());
}
public void searchObject(Object ob) {
objectMap = ClassHelper.searchObject(ob, set, ModClassFilter.getInstance());
}
public void searchObject(Object ob, Filter<String> filter) {
objectMap = ClassHelper.searchObject(ob, set, filter);
}
public void searchObject(Object ob, Set<String> set, Filter<String> filter) {
objectMap = ClassHelper.searchObject(ob, set, filter);
}
public void clearObject() {
objectMap = null;
}
@Nullable
public Map<String, Set<Object>> getObjectMap() {
return objectMap;
}
}

20
designer-base/src/main/java/com/fr/design/mod/ContentReplaceUtil.java

@ -0,0 +1,20 @@
package com.fr.design.mod;
/**
* @author hades
* @version 10.0
* Created by hades on 2021/5/31
*/
public class ContentReplaceUtil {
public static final String EQ_STRING = "=";
public static String replaceContent(String content, String oldName, String newName) {
return content.replaceAll(generateStr(oldName), generateStr(newName));
}
private static String generateStr(String str) {
return "\"" + str + "\"";
}
}

13
designer-base/src/main/java/com/fr/design/mod/ContentReplacer.java

@ -0,0 +1,13 @@
package com.fr.design.mod;
/**
*
* @author hades
* @version 10.0
* Created by hades on 2021/5/27
*/
public interface ContentReplacer<T> {
void replace(T t, String oldName, String newName);
}

108
designer-base/src/main/java/com/fr/design/mod/ContentReplacerCenter.java

@ -0,0 +1,108 @@
package com.fr.design.mod;
import com.fr.design.mod.bean.ChangeItem;
import com.fr.design.mod.bean.ContentChangeItem;
import com.fr.design.mod.event.TableDataModifyEvent;
import com.fr.design.mod.event.WidgetNameModifyEvent;
import com.fr.design.mod.impl.change.ChartHyperRelateCellLinkContentChange;
import com.fr.design.mod.impl.change.ChartHyperRelateFloatLinkContentChange;
import com.fr.design.mod.impl.change.FormulaContentChange;
import com.fr.design.mod.impl.change.JavaScriptContentChange;
import com.fr.design.mod.impl.change.VanChartHtmlLabelContentChange;
import com.fr.event.Event;
import com.fr.event.EventDispatcher;
import com.fr.event.Listener;
import com.fr.log.FineLoggerFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 默认联动内容替换器实现
*
* 当前替换顺序组件名-> 数据集名
*
* @author hades
* @version 10.0
* Created by hades on 2021/5/27
*/
public class ContentReplacerCenter {
private static final ContentReplacerCenter INSTANCE = new ContentReplacerCenter();
public static ContentReplacerCenter getInstance() {
return INSTANCE;
}
private List<ContentChange> contentChangeList = new ArrayList<>();
private List<ContentChangeItem> items = new ArrayList<>();
private ContentReplacerCenter() {
EventDispatcher.listen(WidgetNameModifyEvent.INSTANCE, new Listener<ContentChangeItem>() {
@Override
public void on(Event event, ContentChangeItem param) {
if (param.getChangeMap().isEmpty()) {
return;
}
items.add(param);
}
});
EventDispatcher.listen(TableDataModifyEvent.INSTANCE, new Listener<ContentChangeItem>() {
@Override
public void on(Event event, ContentChangeItem param) {
items.add(param);
long start = System.currentTimeMillis();
ContentObjectManager.getInstance().searchObject(param.getObject());
FineLoggerFactory.getLogger().debug("search object spend {} ms", (System.currentTimeMillis() - start));
FineLoggerFactory.getLogger().debug("search result: {}", ContentObjectManager.getInstance().getObjectMap() == null
? null : ContentObjectManager.getInstance().getObjectMap().keySet());
List<ContentChangeItem> itemsCopy = new ArrayList<>(items);
items.clear();
onRename(itemsCopy, contentChangeList);
}
});
}
public void register() {
contentChangeList.add(new ChartHyperRelateCellLinkContentChange());
contentChangeList.add(new ChartHyperRelateFloatLinkContentChange());
contentChangeList.add(new FormulaContentChange());
contentChangeList.add(new JavaScriptContentChange());
contentChangeList.add(new VanChartHtmlLabelContentChange());
}
private void onRename(List<ContentChangeItem> contentChangeItemList, List<ContentChange> contentChangeList) {
Map<String, Set<Object>> objectMap = ContentObjectManager.getInstance().getObjectMap();
if (objectMap != null) {
long start = System.currentTimeMillis();
for (ContentChange contentChange : contentChangeList) {
Set<Object> set = objectMap.get(contentChange.type());
// 所有需要处理的js等对象
if (set != null) {
for (Object ob : set) {
fireChange(ob, contentChange, contentChangeItemList);
}
}
}
objectMap.clear();
FineLoggerFactory.getLogger().debug("replace all content spend {} ms", (System.currentTimeMillis() - start));
}
}
private void fireChange(Object o, ContentChange contentChange, List<ContentChangeItem> itemList) {
// 当前两项存在两项: 数据集名称和组件名称
for (ContentChangeItem contentChangeItem : itemList) {
Map<ChangeItem, ContentReplacer> map = contentChange.changeInfo();
if (map.containsKey(contentChangeItem.getChangeItem())) {
// 具体重命名取决于复用组件存在多少个组件或数据集
for (Map.Entry<String, String> entry : contentChangeItem.getChangeMap().entrySet()) {
map.get(contentChangeItem.getChangeItem()).replace(o, entry.getKey(), entry.getValue());
}
}
}
}
}

33
designer-base/src/main/java/com/fr/design/mod/ModClassFilter.java

@ -0,0 +1,33 @@
package com.fr.design.mod;
import com.fr.stable.Filter;
import java.util.HashSet;
import java.util.Set;
/**
* @author hades
* @version 10.0
* Created by hades on 2021/5/31
*/
public class ModClassFilter implements Filter<String> {
private static final Set<String> FILTER_SET = new HashSet<>();
private static final Filter<String> INSTANCE = new ModClassFilter();
public static Filter<String> getInstance() {
return INSTANCE;
}
static {
FILTER_SET.add("java.awt.image.BufferedImage");
FILTER_SET.add("sun.awt.AppContext");
FILTER_SET.add("com.fr.poly.creator.ECBlockCreator");
FILTER_SET.add("io.netty.channel.nio.SelectedSelectionKeySet");
}
@Override
public boolean accept(String s) {
return FILTER_SET.contains(s);
}
}

14
designer-base/src/main/java/com/fr/design/mod/bean/ChangeItem.java

@ -0,0 +1,14 @@
package com.fr.design.mod.bean;
/**
* @author hades
* @version 10.0
* Created by hades on 2021/5/28
*/
public enum ChangeItem {
TABLE_DATA_NAME,
WIDGET_NAME
}

33
designer-base/src/main/java/com/fr/design/mod/bean/ContentChangeItem.java

@ -0,0 +1,33 @@
package com.fr.design.mod.bean;
import java.util.Map;
/**
* @author hades
* @version 10.0
* Created by hades on 2021/5/28
*/
public class ContentChangeItem {
private final Map<String, String> changeMap;
private final ChangeItem changeItem;
private final Object object;
public ContentChangeItem(Map<String, String> changeMap,Object object, ChangeItem changeItem) {
this.changeMap = changeMap;
this.changeItem = changeItem;
this.object = object;
}
public Map<String, String> getChangeMap() {
return changeMap;
}
public ChangeItem getChangeItem() {
return changeItem;
}
public Object getObject() {
return object;
}
}

13
designer-base/src/main/java/com/fr/design/mod/event/ModifyEvent.java

@ -0,0 +1,13 @@
package com.fr.design.mod.event;
import com.fr.design.mod.bean.ContentChangeItem;
import com.fr.event.Event;
/**
* @author hades
* @version 10.0
* Created by hades on 2021/5/28
*/
public class ModifyEvent implements Event<ContentChangeItem> {
}

12
designer-base/src/main/java/com/fr/design/mod/event/TableDataModifyEvent.java

@ -0,0 +1,12 @@
package com.fr.design.mod.event;
/**
* @author hades
* @version 10.0
* Created by hades on 2021/5/28
*/
public class TableDataModifyEvent extends ModifyEvent {
public static final TableDataModifyEvent INSTANCE = new TableDataModifyEvent();
}

12
designer-base/src/main/java/com/fr/design/mod/event/WidgetNameModifyEvent.java

@ -0,0 +1,12 @@
package com.fr.design.mod.event;
/**
* @author hades
* @version 10.0
* Created by hades on 2021/5/28
*/
public class WidgetNameModifyEvent extends ModifyEvent {
public static final WidgetNameModifyEvent INSTANCE = new WidgetNameModifyEvent();
}

16
designer-base/src/main/java/com/fr/design/mod/impl/change/ChartHyperRelateCellLinkContentChange.java

@ -0,0 +1,16 @@
package com.fr.design.mod.impl.change;
import com.fr.chart.web.ChartHyperRelateCellLink;
/**
* @author hades
* @version 10.0
* Created by hades on 2021/5/28
*/
public class ChartHyperRelateCellLinkContentChange extends ChartHyperRelateLinkContentChange {
@Override
public String type() {
return ChartHyperRelateCellLink.class.getName();
}
}

16
designer-base/src/main/java/com/fr/design/mod/impl/change/ChartHyperRelateFloatLinkContentChange.java

@ -0,0 +1,16 @@
package com.fr.design.mod.impl.change;
import com.fr.chart.web.ChartHyperRelateFloatLink;
/**
* @author hades
* @version 10.0
* Created by hades on 2021/5/28
*/
public class ChartHyperRelateFloatLinkContentChange extends ChartHyperRelateLinkContentChange{
@Override
public String type() {
return ChartHyperRelateFloatLink.class.getName();
}
}

30
designer-base/src/main/java/com/fr/design/mod/impl/change/ChartHyperRelateLinkContentChange.java

@ -0,0 +1,30 @@
package com.fr.design.mod.impl.change;
import com.fr.chart.web.ChartHyperRelateLink;
import com.fr.design.mod.ContentChange;
import com.fr.design.mod.ContentReplacer;
import com.fr.design.mod.bean.ChangeItem;
import com.fr.design.mod.impl.repalce.ChartHyperRelateLink4WidgetNameContentReplacer;
import java.util.HashMap;
import java.util.Map;
/**
* @author hades
* @version 10.0
* Created by hades on 2021/5/27
*/
public abstract class ChartHyperRelateLinkContentChange implements ContentChange<ChartHyperRelateLink> {
private final Map<ChangeItem, ContentReplacer<ChartHyperRelateLink>> map;
public ChartHyperRelateLinkContentChange() {
this.map = new HashMap<>();
map.put(ChangeItem.WIDGET_NAME, new ChartHyperRelateLink4WidgetNameContentReplacer());
}
@Override
public Map<ChangeItem, ContentReplacer<ChartHyperRelateLink>> changeInfo() {
return map;
}
}

37
designer-base/src/main/java/com/fr/design/mod/impl/change/FormulaContentChange.java

@ -0,0 +1,37 @@
package com.fr.design.mod.impl.change;
import com.fr.base.Formula;
import com.fr.design.mod.ContentChange;
import com.fr.design.mod.ContentReplacer;
import com.fr.design.mod.bean.ChangeItem;
import com.fr.design.mod.impl.repalce.Formula4TableDataNameContentReplacer;
import com.fr.design.mod.impl.repalce.Formula4WidgetNameContentReplacer;
import java.util.HashMap;
import java.util.Map;
/**
* @author hades
* @version 10.0
* Created by hades on 2021/5/27
*/
public class FormulaContentChange implements ContentChange<Formula> {
private final Map<ChangeItem, ContentReplacer<Formula>> map;
public FormulaContentChange() {
map = new HashMap<>();
map.put(ChangeItem.WIDGET_NAME, new Formula4WidgetNameContentReplacer());
map.put(ChangeItem.TABLE_DATA_NAME, new Formula4TableDataNameContentReplacer());
}
@Override
public String type() {
return Formula.class.getName();
}
@Override
public Map<ChangeItem, ContentReplacer<Formula>> changeInfo() {
return map;
}
}

36
designer-base/src/main/java/com/fr/design/mod/impl/change/JavaScriptContentChange.java

@ -0,0 +1,36 @@
package com.fr.design.mod.impl.change;
import com.fr.design.mod.ContentChange;
import com.fr.design.mod.ContentReplacer;
import com.fr.design.mod.bean.ChangeItem;
import com.fr.design.mod.impl.repalce.JavaScriptContentReplacer;
import com.fr.js.JavaScriptImpl;
import java.util.HashMap;
import java.util.Map;
/**
* @author hades
* @version 10.0
* Created by hades on 2021/5/27
*/
public class JavaScriptContentChange implements ContentChange<JavaScriptImpl> {
private final Map<ChangeItem, ContentReplacer<JavaScriptImpl>> map;
public JavaScriptContentChange() {
map = new HashMap<>();
map.put(ChangeItem.WIDGET_NAME, new JavaScriptContentReplacer());
map.put(ChangeItem.TABLE_DATA_NAME, new JavaScriptContentReplacer());
}
@Override
public String type() {
return JavaScriptImpl.class.getName();
}
@Override
public Map<ChangeItem, ContentReplacer<JavaScriptImpl>> changeInfo() {
return map;
}
}

35
designer-base/src/main/java/com/fr/design/mod/impl/change/VanChartHtmlLabelContentChange.java

@ -0,0 +1,35 @@
package com.fr.design.mod.impl.change;
import com.fr.design.mod.ContentChange;
import com.fr.design.mod.ContentReplacer;
import com.fr.design.mod.bean.ChangeItem;
import com.fr.design.mod.impl.repalce.VanChartHtmlLabelContentReplacer;
import com.fr.plugin.chart.base.VanChartHtmlLabel;
import java.util.HashMap;
import java.util.Map;
/**
* @author hades
* @version 10.0
* Created by hades on 2021/5/31
*/
public class VanChartHtmlLabelContentChange implements ContentChange<VanChartHtmlLabel> {
private final Map<ChangeItem, ContentReplacer<VanChartHtmlLabel>> map;
public VanChartHtmlLabelContentChange() {
map = new HashMap<>();
map.put(ChangeItem.WIDGET_NAME, new VanChartHtmlLabelContentReplacer());
map.put(ChangeItem.TABLE_DATA_NAME, new VanChartHtmlLabelContentReplacer());
}
@Override
public String type() {
return VanChartHtmlLabel.class.getName();
}
@Override
public Map<ChangeItem, ContentReplacer<VanChartHtmlLabel>> changeInfo() {
return map;
}
}

21
designer-base/src/main/java/com/fr/design/mod/impl/repalce/ChartHyperRelateLink4WidgetNameContentReplacer.java

@ -0,0 +1,21 @@
package com.fr.design.mod.impl.repalce;
import com.fr.chart.web.ChartHyperRelateLink;
import com.fr.design.mod.ContentReplacer;
import com.fr.general.ComparatorUtils;
/**
* @author hades
* @version 10.0
* Created by hades on 2021/5/28
*/
public class ChartHyperRelateLink4WidgetNameContentReplacer implements ContentReplacer<ChartHyperRelateLink> {
@Override
public void replace(ChartHyperRelateLink chartHyperRelateLink, String oldName, String newName) {
if (ComparatorUtils.equals(chartHyperRelateLink.getRelateCCName(), oldName)) {
chartHyperRelateLink.setRelateCCName(newName);
}
}
}

22
designer-base/src/main/java/com/fr/design/mod/impl/repalce/Formula4TableDataNameContentReplacer.java

@ -0,0 +1,22 @@
package com.fr.design.mod.impl.repalce;
import com.fr.base.Formula;
import com.fr.design.mod.ContentReplaceUtil;
import com.fr.design.mod.ContentReplacer;
import com.fr.parser.FRFormulaTransformer;
/**
* @author hades
* @version 10.0
* Created by hades on 2021/5/28
*/
public class Formula4TableDataNameContentReplacer implements ContentReplacer<Formula> {
@Override
public void replace(Formula formula, String oldName, String newName) {
FRFormulaTransformer frFormulaTransformer = new FRFormulaTransformer();
frFormulaTransformer.addRenamedDataset(oldName, newName);
formula.setContent(ContentReplaceUtil.EQ_STRING + frFormulaTransformer.transform(formula.getPureContent()));
}
}

21
designer-base/src/main/java/com/fr/design/mod/impl/repalce/Formula4WidgetNameContentReplacer.java

@ -0,0 +1,21 @@
package com.fr.design.mod.impl.repalce;
import com.fr.base.Formula;
import com.fr.design.mod.ContentReplaceUtil;
import com.fr.design.mod.ContentReplacer;
import com.fr.parser.FRFormulaTransformer;
/**
* @author hades
* @version 10.0
* Created by hades on 2021/5/28
*/
public class Formula4WidgetNameContentReplacer implements ContentReplacer<Formula> {
@Override
public void replace(Formula formula, String oldName, String newName) {
FRFormulaTransformer frFormulaTransformer = new FRFormulaTransformer();
frFormulaTransformer.addRenamedWidget(oldName, newName);
formula.setContent(ContentReplaceUtil.EQ_STRING + frFormulaTransformer.transform(formula.getPureContent()));
}
}

22
designer-base/src/main/java/com/fr/design/mod/impl/repalce/JavaScriptContentReplacer.java

@ -0,0 +1,22 @@
package com.fr.design.mod.impl.repalce;
import com.fr.design.mod.ContentReplacer;
import com.fr.design.mod.ContentReplaceUtil;
import com.fr.js.JavaScriptImpl;
import com.fr.stable.StringUtils;
/**
* @author hades
* @version 10.0
* Created by hades on 2021/5/28
*/
public class JavaScriptContentReplacer implements ContentReplacer<JavaScriptImpl> {
@Override
public void replace(JavaScriptImpl javaScript, String oldName, String newName) {
if (StringUtils.isNotEmpty(javaScript.getContent())) {
javaScript.setContent(ContentReplaceUtil.replaceContent(javaScript.getContent(), oldName, newName));
}
}
}

22
designer-base/src/main/java/com/fr/design/mod/impl/repalce/VanChartHtmlLabelContentReplacer.java

@ -0,0 +1,22 @@
package com.fr.design.mod.impl.repalce;
import com.fr.design.mod.ContentReplacer;
import com.fr.design.mod.ContentReplaceUtil;
import com.fr.plugin.chart.base.VanChartHtmlLabel;
import com.fr.stable.StringUtils;
/**
* @author hades
* @version 10.0
* Created by hades on 2021/5/31
*/
public class VanChartHtmlLabelContentReplacer implements ContentReplacer<VanChartHtmlLabel> {
@Override
public void replace(VanChartHtmlLabel vanChartHtmlLabel, String oldName, String newName) {
if (StringUtils.isNotEmpty(vanChartHtmlLabel.getCustomText())) {
vanChartHtmlLabel.setCustomText(
ContentReplaceUtil.replaceContent(vanChartHtmlLabel.getCustomText(), oldName, newName));
}
}
}

12
designer-form/src/main/java/com/fr/design/designer/beans/models/ModelUtil.java

@ -2,11 +2,17 @@ package com.fr.design.designer.beans.models;
import com.fr.design.designer.creator.XCreator;
import com.fr.design.designer.creator.XWParameterLayout;
import com.fr.design.mod.bean.ChangeItem;
import com.fr.design.mod.bean.ContentChangeItem;
import com.fr.design.mod.event.WidgetNameModifyEvent;
import com.fr.event.EventDispatcher;
import com.fr.form.main.Form;
import com.fr.form.ui.Widget;
import com.fr.stable.StringUtils;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
@ -25,10 +31,16 @@ abstract class ModelUtil {
Set<XCreator> nameRelatedCreators = new HashSet<>();
//直接遍历出来目标值,然后按需处理
xCreator.traversalNameRelatedXCreators(nameRelatedCreators);
Map<String, String> renameMap = new HashMap<>();
for (XCreator target : nameRelatedCreators) {
String uniqueName = uniqueName(form, target, duplicated);
String oldName = target.toData().getWidgetName();
if (StringUtils.isNotEmpty(oldName)) {
renameMap.put(oldName, uniqueName);
}
target.resetCreatorName(uniqueName);
}
EventDispatcher.fire(WidgetNameModifyEvent.INSTANCE, new ContentChangeItem(renameMap, xCreator.toData(), ChangeItem.WIDGET_NAME));
}
private static String uniqueName(Form form, XCreator xCreator, Set<String> duplicated) {

449
designer-form/src/main/java/com/fr/design/gui/controlpane/EventPropertyPane.java

@ -1,93 +1,30 @@
package com.fr.design.gui.controlpane;
import com.fr.design.beans.BasicBeanPane;
import com.fr.design.constants.UIConstants;
import com.fr.design.designer.creator.XCreator;
import com.fr.design.designer.properties.EventPropertyTable;
import com.fr.design.gui.icontainer.UIScrollPane;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.ilist.JNameEdList;
import com.fr.design.gui.ilist.ListModelElement;
import com.fr.design.gui.ilist.ModNameActionListener;
import com.fr.design.gui.ilist.UINameEdList;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.FormDesigner;
import com.fr.design.widget.EventCreator;
import com.fr.form.event.Listener;
import com.fr.form.ui.Widget;
import com.fr.general.NameObject;
import com.fr.report.web.util.ReportEngineEventMapping;
import com.fr.stable.ArrayUtils;
import com.fr.stable.Nameable;
import javax.swing.BorderFactory;
import javax.swing.DefaultListModel;
import javax.swing.JPanel;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* Created by kerry on 5/17/21
*/
public class EventPropertyPane extends UIControlPane implements ListControlPaneProvider {
public class EventPropertyPane extends UIListGroupControlPane {
private XCreator creator;
private boolean isPopulating = false;
private UINameEdList selectNameEdList;
private Map<String, EventListWrapperPane> nameEdListMap = new HashMap<>();
private CommonShortCutHandlers commonHandlers;
private ListControlPaneHelper helper;
private JPanel contentPane;
private FormDesigner designer;
private ListControlPaneHelper getHelper() {
if (helper == null) {
helper = ListControlPaneHelper.newInstance(this);
}
return helper;
}
private CommonShortCutHandlers getCommonHandlers() {
if (commonHandlers == null) {
commonHandlers = CommonShortCutHandlers.newInstance(this);
}
return commonHandlers;
}
public EventPropertyPane(FormDesigner designer) {
super();
this.designer = designer;
}
@Override
protected void initLeftPane(JPanel leftPane) {
leftPane.add(new UIScrollPane(contentPane = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, FlowLayout.LEADING, 0, 0)), BorderLayout.CENTER);
}
/**
* 刷新
*/
@ -98,184 +35,19 @@ public class EventPropertyPane extends UIControlPane implements ListControlPaneP
.getSelection().getSelectedCreator();
} else {
this.creator = null;
contentPane.removeAll();
this.getContentPane().removeAll();
checkButtonEnabled();
return;
}
Widget widget = creator.toData();
refreshContentPane(widget.supportedEvents());
refreshNameableCreator(EventCreator.createEventCreator(widget.supportedEvents(), EventPropertyTable.WidgetEventListenerUpdatePane.class));
populateNameObjects();
refreshPane(widget, EventCreator.createEventCreator(widget.supportedEvents(), EventPropertyTable.WidgetEventListenerUpdatePane.class));
}
private void refreshContentPane(String[] supportedEvents) {
for (String event : supportedEvents) {
if (nameEdListMap.containsKey(event)) {
continue;
}
UINameEdList list = createJNameList(event);
EventListWrapperPane wrapperPane = new EventListWrapperPane(switchLang(event), list);
if (this.selectNameEdList == null) {
this.selectNameEdList = wrapperPane.getNameEdList();
}
contentPane.add(wrapperPane);
nameEdListMap.put(event, wrapperPane);
}
}
public void populateNameObjects() {
Widget widget = creator.toData();
ArrayList<NameObject> nameObjectList = new ArrayList<>();
for (int i = 0, size = widget.getListenerSize(); i < size; i++) {
Listener listener = widget.getListener(i);
if (!listener.isDefault()) {
nameObjectList.add(i, new NameObject(switchLang(listener.getEventName()) + (i + 1), listener));
}
}
populate(getHelper().processCatalog(nameObjectList));
checkButtonEnabled();
this.repaint();
}
public void populate(Map<String, List<NameObject>> map) {
isPopulating = true; // 加一个标识位,避免切换单元格时,触发 saveSettings
Iterator<Map.Entry<String, List<NameObject>>> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, List<NameObject>> entry = iterator.next();
List<NameObject> valueList = entry.getValue();
EventListWrapperPane eventListWrapperPane = nameEdListMap.get(entry.getKey());
populateChildNameList(eventListWrapperPane.getNameEdList(), valueList.toArray(new NameObject[valueList.size()]));
}
this.checkButtonEnabled();
refreshEventListWrapperPane();
isPopulating = false;
}
private void refreshEventListWrapperPane() {
Iterator<Map.Entry<String, EventListWrapperPane>> iterator = nameEdListMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, EventListWrapperPane> entry = iterator.next();
EventListWrapperPane eventListWrapperPane = entry.getValue();
UINameEdList nameEdList = eventListWrapperPane.getNameEdList();
int listSize = nameEdList.getModel().getSize();
if (this.selectNameEdList.getModel().getSize() == 0 && listSize > 0) {
this.selectNameEdList = nameEdList;
}
eventListWrapperPane.setVisible(listSize > 0);
}
if (this.selectNameEdList != null) {
this.selectNameEdList.setSelectedIndex(0);
}
this.repaint();
}
private void populateChildNameList(UINameEdList nameableList, Nameable[] nameableArray) {
nameableList.getCellEditor().stopCellEditing();
DefaultListModel listModel = (DefaultListModel) nameableList.getModel();
listModel.removeAllElements();
if (ArrayUtils.isEmpty(nameableArray)) {
isPopulating = false;
return;
}
listModel.setSize(nameableArray.length);
for (int i = 0; i < nameableArray.length; i++) {
listModel.set(i, new ListModelElement(nameableArray[i]));
}
}
protected UINameEdList createJNameList(String text) {
UINameEdList nameEdList = new UINameEdList(new DefaultListModel()) {
@Override
protected void doAfterLostFocus() {
((JControlUpdatePane) controlUpdatePane).update();
}
@Override
protected void doAfterStopEditing() {
saveSettings();
}
};
nameEdList.setCellRenderer(new UINameableListCellRenderer(true, this.creators));
nameEdList.setName(text);
nameEdList.setSelectionBackground(UIConstants.ATTRIBUTE_PRESS);
nameEdList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
nameEdList.addMouseListener(new MouseAdapter() {
@Override
public void mouseReleased(MouseEvent e) {
selectNameEdList = nameEdList;
updateUINameListSelect();
}
});
nameEdList.addMouseListener(getHelper().getListMouseListener(nameEdList, this));
nameEdList.addModNameActionListener(new ModNameActionListener() {
@Override
public void nameModed(int index, String oldName, String newName) {
saveSettings();
}
});
nameEdList.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent evt) {
// richie:避免多次update和populate大大降低效率
if (!evt.getValueIsAdjusting()) {
// shoc 切换的时候加检验
if (hasInvalid(false)) {
return;
}
((JControlUpdatePane) EventPropertyPane.this.controlUpdatePane).update();
((JControlUpdatePane) EventPropertyPane.this.controlUpdatePane).populate();
EventPropertyPane.this.checkButtonEnabled();
}
}
});
nameEdList.getModel().addListDataListener(new ListDataListener() {
@Override
public void intervalAdded(ListDataEvent e) {
saveSettings();
}
@Override
public void intervalRemoved(ListDataEvent e) {
saveSettings();
}
@Override
public void contentsChanged(ListDataEvent e) {
saveSettings();
}
});
return nameEdList;
}
private void updateUINameListSelect() {
Iterator<Map.Entry<String, EventListWrapperPane>> iterator = nameEdListMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, EventListWrapperPane> entry = iterator.next();
UINameEdList nameEdList = entry.getValue().getNameEdList();
if (nameEdList != selectNameEdList) {
nameEdList.clearSelection();
}
}
}
@Override
public void checkButtonEnabled() {
getHelper().checkButtonEnabled();
}
private String switchLang(String eventName) {
// 在 properties 文件中找到相应的 key 值
String localeKey = ReportEngineEventMapping.getLocaleName(eventName);
return com.fr.design.i18n.Toolkit.i18nText(localeKey);
populateNameObjects(widget);
}
/**
@ -296,98 +68,6 @@ public class EventPropertyPane extends UIControlPane implements ListControlPaneP
}
/**
* 生成不重复的名字
*
* @param prefix 名字前缀
* @return 名字
*/
@Override
public String createUnrepeatedName(String prefix) {
return getCommonHandlers().createUnrepeatedName(prefix);
}
private void updateSelectedNameList(NameableCreator creator) {
String eventName = ((EventCreator) creator).getEventName();
EventListWrapperPane wrapperPane = nameEdListMap.get(eventName);
wrapperPane.setVisible(true);
setSelectNameEdList(wrapperPane.getNameEdList());
}
private void setSelectNameEdList(UINameEdList nameEdList) {
if (this.selectNameEdList != null) {
this.selectNameEdList.clearSelection();
}
this.selectNameEdList = nameEdList;
}
@Override
public void onAddItem(NameableCreator creator) {
updateSelectedNameList(creator);
getCommonHandlers().onAddItem(creator);
}
@Override
public void onRemoveItem() {
getCommonHandlers().onRemoveItem();
refreshEventListWrapperPane();
}
@Override
public void onCopyItem() {
getCommonHandlers().onCopyItem();
}
@Override
public void onMoveUpItem() {
getCommonHandlers().onMoveUpItem();
}
@Override
public void onMoveDownItem() {
getCommonHandlers().onMoveDownItem();
}
@Override
public void onSortItem(boolean isAtoZ) {
Iterator<Map.Entry<String, EventListWrapperPane>> iterator = nameEdListMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, EventListWrapperPane> entry = iterator.next();
UINameEdList nameEdList = entry.getValue().getNameEdList();
getCommonHandlers().onSortItem(isAtoZ, nameEdList);
}
}
@Override
public boolean isItemSelected() {
return getModel().getSize() > 0 && getSelectedIndex() != -1;
}
@Override
protected JPanel createControlUpdatePane() {
return JControlUpdatePane.newInstance(this);
}
@Override
public Nameable[] update() {
java.util.List<Nameable> res = new java.util.ArrayList<Nameable>();
getControlUpdatePane().update();
Iterator<Map.Entry<String, EventListWrapperPane>> iterator = nameEdListMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, EventListWrapperPane> entry = iterator.next();
UINameEdList nameEdList = entry.getValue().getNameEdList();
DefaultListModel listModel = (DefaultListModel) nameEdList.getModel();
for (int i = 0, len = listModel.getSize(); i < len; i++) {
res.add(((ListModelElement) listModel.getElementAt(i)).wrapper);
}
}
return res.toArray(new Nameable[0]);
}
@Override
public NameableCreator[] createNameableCreators() {
return new NameableCreator[]{
@ -397,7 +77,7 @@ public class EventPropertyPane extends UIControlPane implements ListControlPaneP
@Override
public void saveSettings() {
if (isPopulating) {
if (isPopulating()) {
return;
}
updateWidgetListener(creator);
@ -413,123 +93,8 @@ public class EventPropertyPane extends UIControlPane implements ListControlPaneP
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Add_Event");
}
public BasicBeanPane createPaneByCreators(NameableCreator creator) {
try {
return creator.getUpdatePane().newInstance();
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
public BasicBeanPane createPaneByCreators(NameableCreator creator, String string) {
Constructor constructor = null;
try {
constructor = creator.getUpdatePane().getDeclaredConstructor(new Class[]{String.class});
constructor.setAccessible(true);
return (BasicBeanPane) constructor.newInstance(string);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}
@Override
public DefaultListModel getModel() {
if (this.selectNameEdList == null) {
return new DefaultListModel();
}
return (DefaultListModel) this.selectNameEdList.getModel();
}
/**
* 检查是否符合规范
*
* @throws Exception
*/
@Override
public void checkValid() throws Exception {
((JControlUpdatePane) this.controlUpdatePane).checkValid();
}
@Override
public boolean hasInvalid(boolean isAdd) {
return getHelper().hasInvalid(isAdd);
}
public void addNameable(Nameable nameable, int index) {
getHelper().addNameable(nameable, index);
popupEditDialog();
protected String getWrapperLabelText(){
return Toolkit.i18nText("Fine-Design_Report_Event");
}
/**
* 设置选中项
*
* @param index 选中项的序列号
*/
public void setSelectedIndex(int index) {
if (this.selectNameEdList != null) {
this.selectNameEdList.setSelectedIndex(index);
}
}
@Override
public int getSelectedIndex() {
if (this.selectNameEdList == null) {
return -1;
}
return this.selectNameEdList.getSelectedIndex();
}
@Override
public ListModelElement getSelectedValue() {
if (this.selectNameEdList == null) {
return null;
}
return (ListModelElement) this.selectNameEdList.getSelectedValue();
}
@Override
public JControlUpdatePane getControlUpdatePane() {
return (JControlUpdatePane) controlUpdatePane;
}
@Override
public JNameEdList getNameableList() {
return this.selectNameEdList;
}
private void popupEditDialog() {
getHelper().popupEditDialog(null, this.selectNameEdList, this);
}
private class EventListWrapperPane extends JPanel {
private UINameEdList nameEdList;
public EventListWrapperPane(String labelText, UINameEdList nameEdList) {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
UILabel label = new UILabel(labelText + Toolkit.i18nText("Fine-Design_Report_Event"));
label.setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 0));
label.setBackground(Color.decode("#FFFFFF"));
label.setPreferredSize(new Dimension(226, 26));
this.nameEdList = nameEdList;
this.add(label, BorderLayout.NORTH);
this.add(this.nameEdList, BorderLayout.CENTER);
}
public UINameEdList getNameEdList() {
return this.nameEdList;
}
}
}

9
designer-form/src/main/java/com/fr/design/mainframe/FormCreatorDropTarget.java

@ -21,7 +21,11 @@ import com.fr.design.form.util.XCreatorConstants;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.icon.IconPathConstants;
import com.fr.design.mainframe.chart.info.ChartInfoCollector;
import com.fr.design.mod.bean.ChangeItem;
import com.fr.design.mod.bean.ContentChangeItem;
import com.fr.design.mod.event.TableDataModifyEvent;
import com.fr.design.utils.ComponentUtils;
import com.fr.event.EventDispatcher;
import com.fr.form.share.editor.SharableEditorProvider;
import com.fr.form.share.SharableWidgetProvider;
import com.fr.form.share.ShareLoader;
@ -29,6 +33,7 @@ import com.fr.form.ui.Widget;
import com.fr.stable.Constants;
import com.fr.stable.StringUtils;
import java.util.Collections;
import javax.swing.BorderFactory;
import javax.swing.JWindow;
import java.util.List;
@ -102,14 +107,16 @@ public class FormCreatorDropTarget extends DropTarget {
String shareId = addingXCreator.getShareId();
SharableEditorProvider sharableEditor = ShareLoader.getLoader().getSharedElCaseEditorById(shareId);
SharableWidgetProvider bindInfo = ShareLoader.getLoader().getElCaseBindInfoById(shareId);
Map<String, String> tdNameMap = Collections.emptyMap();
if (sharableEditor != null && bindInfo != null) {
Map<String, String> tdNameMap = TableDataTreePane.getInstance(DesignModelAdapter.getCurrentModelAdapter()).addTableData(bindInfo.getName(), sharableEditor.getTableDataSource(), true);
tdNameMap = TableDataTreePane.getInstance(DesignModelAdapter.getCurrentModelAdapter()).addTableData(bindInfo.getName(), sharableEditor.getTableDataSource(), true);
//合并数据集之后,可能会有数据集名称变化,做一下联动
//共享的组件拿的时候都是克隆的,这边改拖拽中克隆的对象而非新克隆对象,上面这个新克隆的对象只是为了拿数据集
for (Map.Entry<String, String> entry : tdNameMap.entrySet()) {
designer.getTarget().renameTableData(widget, entry.getKey(), entry.getValue());
}
}
EventDispatcher.fire(TableDataModifyEvent.INSTANCE, new ContentChangeItem(tdNameMap, widget, ChangeItem.TABLE_DATA_NAME));
}
designer.getSelectionModel().setSelectedCreators(
FormSelectionUtils.rebuildSelection(xCreator, new Widget[]{widget}));

132
designer-realize/src/main/java/com/fr/design/mainframe/app/DesignerAppUtils.java

@ -7,16 +7,24 @@ import com.fr.design.extra.exe.callback.ModifyStatusCallback;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.ui.util.UIUtil;
import com.fr.io.TemplateIOErrorUtils;
import com.fr.locale.InterProviderFactory;
import com.fr.plugin.context.PluginMarker;
import com.fr.plugin.context.PluginMarkerAdapter;
import com.fr.plugin.engine.remote.PluginRemoteSync;
import com.fr.plugin.manage.PluginManager;
import com.fr.plugin.manage.control.PluginControllerHelper;
import com.fr.plugin.manage.control.PluginTask;
import com.fr.stable.StringUtils;
import com.fr.stable.TemplateIOErrorContextHolder;
import com.fr.third.guava.cache.Cache;
import com.fr.third.guava.cache.CacheBuilder;
import com.fr.third.guava.collect.Multimap;
import com.fr.workspace.WorkContext;
import java.time.Duration;
import java.util.Collection;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 设计器app共用工具类
@ -26,6 +34,118 @@ import java.util.Collection;
* Created by vito on 2021/5/27
*/
public class DesignerAppUtils {
private static final int DEFAULT_MAX_CACHE_SIZE = 50;
private static final int DEFAULT_CONCURRENCY_LEVEL = 8;
private static final long DEFAULT_EXPIRE_HOURS = 1;
private static final Cache<String, Multimap<String, PluginMarkerAdapter>> ERROR_CACHE = CacheBuilder.newBuilder()
.maximumSize(DEFAULT_MAX_CACHE_SIZE)
.expireAfterAccess(Duration.ofHours(DEFAULT_EXPIRE_HOURS))
.concurrencyLevel(DEFAULT_CONCURRENCY_LEVEL)
.build();
/**
* 弹出指定的插件信息
* 并失效缓存
*
* @param key 指定key
* @return 插件安装信息
*/
public static Multimap<String, PluginMarkerAdapter> popPluginInfoMap(String key) {
Multimap<String, PluginMarkerAdapter> ifPresent = ERROR_CACHE.getIfPresent(key);
ERROR_CACHE.invalidate(key);
return ifPresent;
}
/**
* 失效指定的插件信息缓存
*
* @param key 指定key
*/
public static void invalidatePlugins(String key) {
ERROR_CACHE.invalidate(key);
}
/**
* 格式化多行插件错误信息详情并缓存
* 用于界面展示
*
* @param key 缓存key
* @return 格式化后的多行插件错误信息详情
*/
public static String dealWithErrorDetailMultiLineAndCache(String key) {
Multimap<String, PluginMarkerAdapter> pendingPlugins = TemplateIOErrorContextHolder.getPendingPlugin();
if (pendingPlugins.isEmpty()) {
return StringUtils.EMPTY;
}
dealWithRemote(pendingPlugins);
StringBuilder sb = new StringBuilder();
if (WorkContext.getCurrent().isLocal()) {
// 缓存等待后续处理
ERROR_CACHE.put(key, pendingPlugins);
}
Collection<PluginMarkerAdapter> unknownPlugins = pendingPlugins.get(TemplateIOErrorContextHolder.UNKNOWN_PLUGIN);
if (!unknownPlugins.isEmpty()) {
sb.append(InterProviderFactory.getProvider().getLocText("Fine-Core_Plugin_Error_UnknownPlugin")).append(":\n");
for (PluginMarkerAdapter pluginMarker : unknownPlugins) {
sb.append("\"").append(pluginMarker.getPluginID()).append("\"")
.append(InterProviderFactory.getProvider().getLocText("Fine-Dec_Platform_Plugin")).append('\n');
}
}
Collection<PluginMarkerAdapter> notInstalledPlugins = pendingPlugins.get(TemplateIOErrorContextHolder.NOT_INSTALLED_PLUGIN);
if (!notInstalledPlugins.isEmpty()) {
sb.append(InterProviderFactory.getProvider().getLocText("Fine-Core_Plugin_Error_UninstalledPlugins")).append(":\n");
for (PluginMarkerAdapter pluginMarker : notInstalledPlugins) {
sb.append("\"").append(pluginMarker.getPluginName()).append("\"")
.append(InterProviderFactory.getProvider().getLocText("Fine-Dec_Platform_Plugin")).append('\n');
}
}
Collection<PluginMarkerAdapter> disablePlugins = pendingPlugins.get(TemplateIOErrorContextHolder.DISABLE_PLUGIN);
if (!disablePlugins.isEmpty()) {
sb.append(InterProviderFactory.getProvider().getLocText("Fine-Core_Plugin_Error_InactivePlugins")).append(":\n");
for (PluginMarkerAdapter pluginMarker : disablePlugins) {
sb.append("\"").append(pluginMarker.getPluginName()).append("\"")
.append(InterProviderFactory.getProvider().getLocText("Fine-Dec_Platform_Plugin")).append('\n');
}
}
return sb.toString();
}
/**
* 远程环境下需要特殊处理远程服务器尚未安装的插件
*
* @param pendingPlugins 待处理插件
*/
private static void dealWithRemote(Multimap<String, PluginMarkerAdapter> pendingPlugins) {
if (!WorkContext.getCurrent().isLocal()) {
rearrange(pendingPlugins);
}
}
/**
* 远程设计重新整理下列表
*
* @param pendingPlugins 待处理列表
*/
public static void rearrange(Multimap<String, PluginMarkerAdapter> pendingPlugins) {
Map<String, PluginRemoteSync.PluginStatus> pluginRemoteStatusByIdIndex = PluginRemoteSync.getInstance().getPluginRemoteStatusByIdIndex();
Collection<PluginMarkerAdapter> unknownPlugins = pendingPlugins.get(TemplateIOErrorContextHolder.UNKNOWN_PLUGIN);
Collection<PluginMarkerAdapter> notInstall = pendingPlugins.get(TemplateIOErrorContextHolder.NOT_INSTALLED_PLUGIN);
Collection<PluginMarkerAdapter> disable = pendingPlugins.get(TemplateIOErrorContextHolder.DISABLE_PLUGIN);
unknownPlugins.removeIf(adapter -> pluginRemoteStatusByIdIndex.containsKey(adapter.getPluginID()));
// 本地未启用名单不准确添加到一起之后重新分配
notInstall.addAll(disable);
disable.clear();
// 从所有未安装中过滤远程未启用的,添加到未启用列表
disable.addAll(notInstall.stream().filter(plugin ->
pluginRemoteStatusByIdIndex.containsKey(plugin.getPluginID())
&& !pluginRemoteStatusByIdIndex.get(plugin.getPluginID()).isRunning())
.collect(Collectors.toList()));
// 清理未安装中所有远程安装过的插件(包含启用和未启用)
notInstall.removeIf(adapter -> pluginRemoteStatusByIdIndex.containsKey(adapter.getPluginID()));
}
/**
* 处理模板读取时的异常
@ -34,7 +154,7 @@ public class DesignerAppUtils {
*/
public static void dealWithTemplateIOError(String path) {
// 试图获取多行读取错误提示并缓存待处理列表
String detail = TemplateIOErrorUtils.dealWithErrorDetailMultiLineAndCache(path);
String detail = dealWithErrorDetailMultiLineAndCache(path);
if (detail.length() > 0) {
UIUtil.invokeLaterIfNeeded(() -> {
if (WorkContext.getCurrent().isLocal()) {
@ -52,7 +172,7 @@ public class DesignerAppUtils {
@Override
public void doCancel() {
TemplateIOErrorUtils.invalidatePlugins(path);
invalidatePlugins(path);
}
}).build().setVisible(true);
} else {
@ -68,13 +188,13 @@ public class DesignerAppUtils {
}
private static void installAndEnablePlugin(String key) {
Multimap<String, PluginMarkerAdapter> stringPluginMarkerAdapterMultimap = TemplateIOErrorUtils.popPluginInfoMap(key);
Collection<PluginMarkerAdapter> disablePlugins = stringPluginMarkerAdapterMultimap.get(TemplateIOErrorUtils.DISABLE_PLUGIN);
Multimap<String, PluginMarkerAdapter> stringPluginMarkerAdapterMultimap = popPluginInfoMap(key);
Collection<PluginMarkerAdapter> disablePlugins = stringPluginMarkerAdapterMultimap.get(TemplateIOErrorContextHolder.DISABLE_PLUGIN);
for (PluginMarkerAdapter disablePlugin : disablePlugins) {
PluginManager.getController().enable(disablePlugin, new ModifyStatusCallback(false));
}
Collection<PluginMarkerAdapter> uninstallPlugins = stringPluginMarkerAdapterMultimap.get(TemplateIOErrorUtils.NOT_INSTALLED_PLUGIN);
Collection<PluginMarkerAdapter> uninstallPlugins = stringPluginMarkerAdapterMultimap.get(TemplateIOErrorContextHolder.NOT_INSTALLED_PLUGIN);
for (PluginMarker uninstallPlugin : uninstallPlugins) {
PluginTask pluginTask = PluginTask.installTask(uninstallPlugin);
PluginControllerHelper.installOnline(uninstallPlugin, new InstallOnlineCallback(pluginTask));

19
designer-realize/src/main/java/com/fr/design/mainframe/app/FormApp.java

@ -23,6 +23,7 @@ import com.fr.general.ComparatorUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.Constants;
import com.fr.stable.bridge.StableFactory;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.concurrent.Callable;
@ -62,8 +63,7 @@ class FormApp extends AbstractAppProvider {
new Callable<OpenResult<Form, Parameter[]>>() {
@Override
public OpenResult<Form, Parameter[]> call() throws Exception {
Form form = asIOFile(tplFile);
DesignerAppUtils.dealWithTemplateIOError(tplFile.getPath());
Form form = getForm(tplFile);
return new OpenResult<>(form, form.getParameters());
}
}, emptyForm);
@ -72,22 +72,31 @@ class FormApp extends AbstractAppProvider {
public JTemplate<?, ?> call() throws Exception {
OpenResult<Form, Parameter[]> result = worker.getResult();
return (JTemplate<Form, ?>) StableFactory.getMarkedInstanceObjectFromClass(BaseJForm.XML_TAG,
new Object[]{result.getBaseBook(), tplFile, result.getRef()}, classType, BaseJForm.class);
new Object[]{result.getBaseBook(), tplFile, result.getRef()}, classType, BaseJForm.class);
}
});
worker.start(tplFile.getPath());
OpenResult<Form, Parameter[]> result = worker.getResult();
if (result != null) {
return (JTemplate<Form, ?>) StableFactory.getMarkedInstanceObjectFromClass(BaseJForm.XML_TAG,
new Object[]{result.getBaseBook(), tplFile, new Parameter[0]}, classType, BaseJForm.class);
new Object[]{result.getBaseBook(), tplFile, new Parameter[0]}, classType, BaseJForm.class);
}
return emptyForm;
} else {
return (JTemplate<Form, ?>) StableFactory.getMarkedInstanceObjectFromClass(BaseJForm.XML_TAG,
new Object[]{asIOFile(tplFile), tplFile}, classType, BaseJForm.class);
new Object[]{getForm(tplFile), tplFile}, classType, BaseJForm.class);
}
}
@Nullable
private Form getForm(FILE tplFile) {
Form form = asIOFile(tplFile);
if (form != null) {
DesignerAppUtils.dealWithTemplateIOError(tplFile.getPath());
}
return form;
}
@Override
public Form asIOFile(FILE file) {

85
designer-realize/src/main/java/com/fr/design/widget/WidgetEventPane.java

@ -1,10 +1,10 @@
package com.fr.design.widget;
import java.util.ArrayList;
import java.util.List;
import com.fr.design.gui.controlpane.ObjectUIControlPane;
import java.lang.reflect.Constructor;
import com.fr.design.beans.BasicBeanPane;
import com.fr.design.gui.controlpane.UIListGroupControlPane;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.CellWidgetPropertyPane;
import com.fr.design.write.submit.DBManipulationPane;
import com.fr.design.write.submit.SmartInsertDBManipulationInWidgetEventPane;
@ -20,18 +20,20 @@ import com.fr.grid.selection.Selection;
import com.fr.general.NameObject;
import com.fr.grid.selection.CellSelection;
import com.fr.stable.AssistUtils;
import com.fr.stable.Nameable;
import javax.swing.*;
public class WidgetEventPane extends ObjectUIControlPane {
public class WidgetEventPane extends UIListGroupControlPane {
private static final Selection NO_SELECTION = new CellSelection(-1, -1, -1, -1);
private Selection selection = NO_SELECTION;
private ElementCasePane object;
public WidgetEventPane(ElementCasePane pane) {
super(pane);
this.setNameListEditable(false);
this.object = pane;
if(pane != null){
selection = pane.getSelection();
}
@ -62,7 +64,7 @@ public class WidgetEventPane extends ObjectUIControlPane {
protected String title4PopupWindow() {
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Event");
}
public static class WidgetEventListenerUpdatePane extends ListenerUpdatePane {
private ElementCasePane epane;
// 反射会用到
@ -91,8 +93,8 @@ public class WidgetEventPane extends ObjectUIControlPane {
protected DBManipulationPane createDBManipulationPane() {
if(epane == null && DesignerContext.getDesignerFrame().getSelectedJTemplate() != null) {
return autoCreateDBManipulationInWidgetEventPane();
}
}
return new SmartInsertDBManipulationInWidgetEventPane(epane);
}
@ -100,7 +102,7 @@ public class WidgetEventPane extends ObjectUIControlPane {
protected String title4PopupWindow() {
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Set_Callback_Function");
}
@Override
protected boolean isForm() {
return false;
@ -116,26 +118,14 @@ public class WidgetEventPane extends ObjectUIControlPane {
protected boolean supportCellAction() {
return false;
}
}
public void populate(Widget widget) {
if (widget == null) {
return;
}
this.refreshNameableCreator(EventCreator.createEventCreator(widget.supportedEvents(), WidgetEventListenerUpdatePane.class));
List<NameObject> list = new ArrayList<NameObject>();
Listener listener;
for (int i = 0, size = widget.getListenerSize(); i < size; i++) {
listener = widget.getListener(i);
if (!listener.isDefault()) //name+(i+1)需要确保名字不重复
{
list.add(new NameObject(EventCreator.switchLang(listener.getEventName()) + (i + 1), listener));
}
}
this.populate(list.toArray(new NameObject[list.size()]));
refreshPane(widget, EventCreator.createEventCreator(widget.supportedEvents(), WidgetEventListenerUpdatePane.class));
}
/**
@ -150,4 +140,49 @@ public class WidgetEventPane extends ObjectUIControlPane {
}
return res_array;
}
@Override
public BasicBeanPane createPaneByCreators(NameableCreator creator) {
try {
if (object == null) {
return super.createPaneByCreators(creator);
} else if (object.getClass().isArray()) {
return creator.getUpdatePane().getConstructor(object.getClass()).newInstance(object);
} else {
Constructor<? extends BasicBeanPane> constructor = getConstructor(creator.getUpdatePane(), object.getClass());
return constructor == null ? super.createPaneByCreators(creator) : constructor.newInstance(object);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 传进BasicBeanPane的构造函数的参数可能是
*
* @param clazz
* @param cls
* @return
*/
private Constructor<? extends BasicBeanPane> getConstructor(Class<? extends BasicBeanPane> clazz, Class<?> cls) {
Constructor<? extends BasicBeanPane> constructor = null;
try {
constructor = clazz.getConstructor(cls);
} catch (SecurityException e) {
} catch (NoSuchMethodException e) {
}
if (constructor != null) {
return constructor;
} else {
if (AssistUtils.equals(cls.getName(),Object.class.getName())) {
return null;
}
return getConstructor(clazz, cls.getSuperclass());
}
}
protected String getWrapperLabelText(){
return Toolkit.i18nText("Fine-Design_Report_Event");
}
}

2
designer-realize/src/main/java/com/fr/start/module/DesignerActivator.java

@ -55,6 +55,7 @@ import com.fr.design.mainframe.form.FormReportComponentComposite;
import com.fr.design.mainframe.loghandler.DesignerLogAppender;
import com.fr.design.mainframe.share.constants.ShareEntryKey;
import com.fr.design.mainframe.socketio.DesignerSocketIO;
import com.fr.design.mod.ContentReplacerCenter;
import com.fr.design.module.DesignModuleFactory;
import com.fr.design.os.impl.SupportOSImpl;
import com.fr.design.parameter.FormParameterReader;
@ -158,6 +159,7 @@ public class DesignerActivator extends Activator {
storePassport();
AlphaFineHelper.switchConfig4Locale();
RecoverManager.register(new RecoverForDesigner());
ContentReplacerCenter.getInstance().register();
pushUpdateTask.run();
}

106
designer-realize/src/test/java/com/fr/design/mainframe/app/DesignerAppUtilsTest.java

@ -0,0 +1,106 @@
package com.fr.design.mainframe.app;
import com.fr.invoke.Reflect;
import com.fr.plugin.context.PluginMarker;
import com.fr.plugin.context.PluginMarkerAdapter;
import com.fr.plugin.engine.remote.PluginRemoteSync;
import com.fr.stable.TemplateIOErrorContextHolder;
import com.fr.third.guava.collect.Multimap;
import org.easymock.EasyMock;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.easymock.PowerMock;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
/**
* @author vito
* @version 10.0
* Created by vito on 2021/5/31
*/
@RunWith(PowerMockRunner.class)
@PrepareForTest({PluginRemoteSync.class})
public class DesignerAppUtilsTest {
@Test
public void testDealWithErrorDetailMultiLineAndCache() {
TemplateIOErrorContextHolder.registerPluginNameMap(new HashMap<String, String>() {{
put("2", "好用的插件");
}},new HashSet<>());
TemplateIOErrorContextHolder.addNeedEnablePlugin(PluginMarkerAdapter.create("1", "1.0", "1插件"));
TemplateIOErrorContextHolder.addNeedInstallPlugin(PluginMarker.create("2", "1.0"));
TemplateIOErrorContextHolder.addNeedInstallPlugin(PluginMarker.create("3", "1.0"));
String log = DesignerAppUtils.dealWithErrorDetailMultiLineAndCache("template1");
Assert.assertTrue(log.contains("1插件"));
Assert.assertTrue(log.contains("好用的插件"));
Assert.assertTrue(log.contains("3"));
Multimap<String, PluginMarkerAdapter> map = DesignerAppUtils.popPluginInfoMap("template1");
Assert.assertEquals(3, map.size());
Assert.assertNull(DesignerAppUtils.popPluginInfoMap("template1"));
}
@Test
public void testInvalidatePlugins() {
TemplateIOErrorContextHolder.registerPluginNameMap(new HashMap<String, String>() {{
put("2", "好用的插件");
}},new HashSet<>());
TemplateIOErrorContextHolder.addNeedEnablePlugin(PluginMarkerAdapter.create("1", "1.0", "1插件"));
TemplateIOErrorContextHolder.addNeedInstallPlugin(PluginMarker.create("2", "1.0"));
TemplateIOErrorContextHolder.addNeedInstallPlugin(PluginMarker.create("3", "1.0"));
String log = DesignerAppUtils.dealWithErrorDetailMultiLineAndCache("template1");
Assert.assertTrue(log.contains("1插件"));
Assert.assertTrue(log.contains("好用的插件"));
Assert.assertTrue(log.contains("3"));
DesignerAppUtils.invalidatePlugins("template1");
Assert.assertNull(DesignerAppUtils.popPluginInfoMap("template1"));
}
@Test
public void testRearrange(){
// 远程插件模拟注册
PluginRemoteSync pluginRemoteSync = EasyMock.createMock(PluginRemoteSync.class);
EasyMock.expect(pluginRemoteSync.getPluginRemoteStatusByIdIndex()).andReturn(new HashMap<String, PluginRemoteSync.PluginStatus>(){{
put("com.fr.plugin1", Reflect.on(PluginRemoteSync.PluginStatus.class).call("create","com.fr.plugin1","1",true).get());
put("com.fr.plugin2", Reflect.on(PluginRemoteSync.PluginStatus.class).call("create","com.fr.plugin2","1",true).get());
put("com.fr.plugin3", Reflect.on(PluginRemoteSync.PluginStatus.class).call("create","com.fr.plugin3","1",false).get());
put("com.fr.plugin4", Reflect.on(PluginRemoteSync.PluginStatus.class).call("create","com.fr.plugin4","1",false).get());
}}).anyTimes();
EasyMock.replay(pluginRemoteSync);
PowerMock.mockStaticPartial(PluginRemoteSync.class, "getInstance");
EasyMock.expect(PluginRemoteSync.getInstance()).andReturn(pluginRemoteSync).anyTimes();
PowerMock.replay(PluginRemoteSync.class);
// 本地插件模拟检查
TemplateIOErrorContextHolder.registerPluginNameMap(new HashMap<String, String>() {{
put("com.fr.plugin1", "好用的插件1");
put("com.fr.plugin2", "好用的插件2");
put("com.fr.plugin3", "好用的插件3");
put("com.fr.plugin4", "好用的插件4");
put("com.fr.plugin5", "好用的插件5");
}},new HashSet<>());
// unknown
TemplateIOErrorContextHolder.addNeedInstallPlugin(PluginMarker.create("com.fr.plugin7", "1"));
// disable
TemplateIOErrorContextHolder.addNeedEnablePlugin(PluginMarkerAdapter.create("com.fr.plugin5", "1", "plugin5"));
TemplateIOErrorContextHolder.addNeedInstallPlugin(PluginMarker.create("com.fr.plugin3", "1"));
// not install
TemplateIOErrorContextHolder.addNeedInstallPlugin(PluginMarker.create("com.fr.plugin1", "1"));
TemplateIOErrorContextHolder.addNeedInstallPlugin(PluginMarker.create("com.fr.plugin4", "1"));
Multimap<String, PluginMarkerAdapter> pendingPlugins = TemplateIOErrorContextHolder.getPendingPlugin();
Reflect.on(DesignerAppUtils.class).call("rearrange",pendingPlugins).get();
Assert.assertEquals(1,pendingPlugins.get(TemplateIOErrorContextHolder.UNKNOWN_PLUGIN).size());
Collection<PluginMarkerAdapter> pluginMarkerAdapters = pendingPlugins.get(TemplateIOErrorContextHolder.DISABLE_PLUGIN);
Assert.assertEquals(2, pluginMarkerAdapters.size());
pluginMarkerAdapters.contains(PluginMarker.create("com.fr.plugin3", "1"));
pluginMarkerAdapters.contains(PluginMarker.create("com.fr.plugin4", "1"));
Collection<PluginMarkerAdapter> pluginMarkerAdapters1 = pendingPlugins.get(TemplateIOErrorContextHolder.NOT_INSTALLED_PLUGIN);
Assert.assertEquals(1, pluginMarkerAdapters1.size());
pluginMarkerAdapters1.contains(PluginMarker.create("com.fr.plugin5","1"));
}
}
Loading…
Cancel
Save