Browse Source

Merge pull request #16937 in DESIGN/design from feature/x to bugfix/11.0

* commit 'e346ab97cc686d4df5b30e841e3f3bd9f928c903':
  REPORT-148266 feat:comboBox事件叠加导致部分操作卡顿问题优化
  feat: JSContentPane支持自定义提示功能 #REPORT-144004
  feat: 移除移动端弹窗配置调整的接口方法 #REPORT-145535
  feat: 部分逻辑抽到插件中实现 #REPORT-145535
  feat: fvs表格-超链-移动端弹窗支持get post设置 #REPORT-145535
bugfix/11.0
superman 1 month ago
parent
commit
74e1e422cd
  1. 39
      designer-base/src/main/java/com/fr/design/data/DesignTableDataManager.java
  2. 171
      designer-base/src/main/java/com/fr/design/data/datapane/TableDataComboBox.java
  3. 3
      designer-base/src/main/java/com/fr/design/data/datapane/TreeTableDataDictPane.java
  4. 2
      designer-base/src/main/java/com/fr/design/editor/editor/ColumnSelectedEditor.java
  5. 26
      designer-base/src/main/java/com/fr/design/fun/DefaultValueAdjustProvider.java
  6. 49
      designer-base/src/main/java/com/fr/design/hyperlink/popup/ContentSettingPane.java
  7. 112
      designer-base/src/main/java/com/fr/design/javascript/JSContentPane.java
  8. 32
      designer-base/src/main/java/com/fr/design/javascript/JSContentWithDescriptionPane.java
  9. 23
      designer-base/src/main/java/com/fr/design/javascript/JavaScriptImplPane.java
  10. 23
      designer-base/src/main/java/com/fr/design/javascript/NewJavaScriptImplPane.java
  11. 2
      designer-base/src/main/java/com/fr/design/present/dict/TableDataDictPane.java
  12. 54
      designer-base/src/main/java/com/fr/design/ui/util/UIUtil.java
  13. 2
      designer-chart/src/main/java/com/fr/design/chart/AutoChartTypePane.java
  14. 2
      designer-chart/src/main/java/com/fr/design/chartx/component/MapAreaMatchPane.java
  15. 5
      designer-chart/src/main/java/com/fr/design/mainframe/ChartPropertyPane.java
  16. 2
      designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/data/DatabaseTableDataPane.java
  17. 2
      designer-realize/src/main/java/com/fr/design/dscolumn/SelectedDataColumnPane.java

39
designer-base/src/main/java/com/fr/design/data/DesignTableDataManager.java

@ -115,6 +115,9 @@ public abstract class DesignTableDataManager {
//增强for循环用的iterator实现的, 如果中间哪个listener修改或删除了(如ChartEditPane.dsChangeListener),
// 由于dsListeners是arraylist, 此时会ConcurrentModifyException
ChangeEvent e = null;
if (dsListeners.get(i) == null) {
continue;
}
dsListeners.get(i).stateChanged(e);
}
}
@ -185,23 +188,33 @@ public abstract class DesignTableDataManager {
globalDsListeners.add(l);
}
/**
* 添加模板数据集改变 监听事件.
*
* @param l ChangeListener监听器
*/
public static void addDsChangeListener(ChangeListener l) {
getDsListenersForCurrentTemplate().add(l);
}
/**
* 移除模板数据集改变 监听事件.
*
* @param l ChangeListener监听器
*/
public static void removeDsChangeListener(ChangeListener l) {
getDsListenersForCurrentTemplate().remove(l);
}
/**
* 添加模板数据集改变 监听事件.
* 获取当前模板的监听器列表.
*
* @param l ChangeListener监听器
* @return 模板对应的监听器列表如果列表不存在则新建.
*/
public static void addDsChangeListener(ChangeListener l) {
private static List<ChangeListener> getDsListenersForCurrentTemplate() {
JTemplate<?, ?> template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
String key = StringUtils.EMPTY;
if (JTemplate.isValid(template)) {
key = template.getPath();
}
List<ChangeListener> dsListeners = dsListenersMap.get(key);
if (dsListeners == null) {
dsListeners = new ArrayList<ChangeListener>();
dsListenersMap.put(key, dsListeners);
}
dsListeners.add(l);
String key = JTemplate.isValid(template) ? template.getPath() : StringUtils.EMPTY;
return dsListenersMap.computeIfAbsent(key, k -> new ArrayList<>());
}
/**

171
designer-base/src/main/java/com/fr/design/data/datapane/TableDataComboBox.java

@ -1,13 +1,14 @@
package com.fr.design.data.datapane;
import com.fr.design.ui.util.UIUtil;
import java.awt.Component;
import java.awt.event.ItemEvent;
import java.util.Iterator;
import java.util.Map.Entry;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.event.AncestorEvent;
import javax.swing.event.AncestorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
@ -32,16 +33,53 @@ public class TableDataComboBox extends UIComboBox implements Prepare4DataSourceC
protected java.util.Map<String, TableDataWrapper> resMap;
private java.util.Map<String, TableDataWrapper> dsMap;
private static final long serialVersionUID = 1L;
private boolean refresModel = false;
private String treeName; //树数据集本身的名字
private boolean refreshModel = false;
private String treeName = StringUtils.EMPTY; //树数据集本身的名字
private ChangeListener changeListener;
/**
* 兼容插件调用
*
* @param source 传入的数据源
*/
public TableDataComboBox(TableDataSource source){
this(source,StringUtils.EMPTY);
this();
}
/**
* 兼容插件调用
*
* @param source 传入的数据源
* @param treeName 树数据集名称
*/
public TableDataComboBox(TableDataSource source, String treeName) {
this(treeName);
}
/**
* 根据树名称创建TableDataComboBox
*
* @param treeName 树数据集名称
*/
public TableDataComboBox(String treeName) {
this();
// 传入树数据集名称
this.treeName = treeName;
}
/**
* 初始化TableDataComboBox
*/
public TableDataComboBox() {
super();
this.treeName = treeName;
setListCellRenderer();
addComboBoxListener();
}
/**
* 设置渲染器
*/
private void setListCellRenderer() {
this.setRenderer(new UIComboBoxRenderer() {
private static final long serialVersionUID = 1L;
@ -60,37 +98,66 @@ public class TableDataComboBox extends UIComboBox implements Prepare4DataSourceC
return renderer;
}
});
refresh(source);
registerDSChangeListener();
}
/**
* refresh ComboBox
* @param source
*/
/**
* 在comboBox可见时添加数据集响应事件与refresh操作
*/
private void addComboBoxListener() {
this.addAncestorListener(new AncestorListener() {
@Override
public void ancestorAdded(AncestorEvent event) {
registerDSChangeListener();
refresh(DesignTableDataManager.getEditingTableDataSource());
}
@Override
public void ancestorRemoved(AncestorEvent event) {
DesignTableDataManager.removeDsChangeListener(changeListener);
}
@Override
public void ancestorMoved(AncestorEvent event) {
}
});
}
/**
* 刷新数据源并更新下拉框的模型和选中项
*
* @param source 数据源用于刷新模型
*/
public void refresh(TableDataSource source) {
TableDataWrapper dataWrapper = getSelectedItem();
refresModel = true;
setResMap(source);
setDsMap();
DefaultComboBoxModel model = new DefaultComboBoxModel();
this.setModel(model);
model.addElement(UIConstants.PENDING);
Iterator<Entry<String, TableDataWrapper>> entryIt = dsMap.entrySet().iterator();
while (entryIt.hasNext()) {
TableDataWrapper tableDataWrapper = entryIt.next().getValue();
if (!ComparatorUtils.equals(tableDataWrapper.getTableDataName(), treeName)) {
model.addElement(tableDataWrapper);
}
}
if (dataWrapper != null) {
if (DesignTableDataManager.isDsNameChanged(dataWrapper.getTableDataName())) {
this.setSelectedTableDataByName(DesignTableDataManager.getChangedDsNameByOldDsName(dataWrapper.getTableDataName()));
} else {
this.getModel().setSelectedItem(dataWrapper);
}
}
refresModel = false;
UIUtil.executeAsyncTaskAndUpdateUI(
() -> {
setResMap(source);
setDsMap();
return null;
},
result -> refreshComboBoxModel()
);
}
/**
* 刷新下拉框模型同时保留当前选中的数据项
* <p>
* 1. 获取下拉框中当前选中的数据项
* 2. 刷新下拉框的模型清空并重新填充数据此操作会重置选中的数据项
* 3. 在刷新模型后恢复之前选中的数据项
* <p>
* 关于 `refreshModel` 的作用
* 1. **抑制事件触发**下拉框模型在调用 `addElement` 方法时会触发 `fireItemStateChanged` 事件
* 通过标记 `refreshModel`可以在刷新过程中抑制此事件
* 2. **处理异步和顺序问题**由于取数操作是异步的可能会导致回调后的 UI 操作与其他逻辑 `populateBean`的调用顺序交错
* 标记 `refreshModel` 可确保在刷新模型时不触发选中事件从而避免逻辑干扰
* 3. **逻辑清晰性**刷新模型本质上是更新数据源的操作不应触发与用户交互相关的选中事件避免对上层逻辑造成额外负担
*/
private void refreshComboBoxModel() {
refreshModel = true;
TableDataWrapper selectedItem = getSelectedItem();
refreshModel();
updateSelectedItem(selectedItem);
refreshModel = false;
}
protected void setResMap(TableDataSource source) {
@ -101,6 +168,26 @@ public class TableDataComboBox extends UIComboBox implements Prepare4DataSourceC
dsMap = DesignTableDataManager.getAllDataSetIncludingProcedure(resMap);
}
private void refreshModel() {
//创建ComboBox模型并设置
DefaultComboBoxModel model = new DefaultComboBoxModel();
this.setModel(model);
model.addElement(UIConstants.PENDING);
// 遍历添加所有数据项到模型,树数据集comboBox下拉模型中排除掉本身
dsMap.values().stream()
.filter(tableDataWrapper -> tableDataWrapper != null && !ComparatorUtils.equals(tableDataWrapper.getTableDataName(), treeName))
.forEach(model::addElement);
}
private void updateSelectedItem(TableDataWrapper dataWrapper) {
if (dataWrapper != null) {
if (DesignTableDataManager.isDsNameChanged(dataWrapper.getTableDataName())) {
this.setSelectedTableData(DesignTableDataManager.getChangedDsNameByOldDsName(dataWrapper.getTableDataName()));
} else {
this.getModel().setSelectedItem(dataWrapper);
}
}
}
/**
@ -117,8 +204,18 @@ public class TableDataComboBox extends UIComboBox implements Prepare4DataSourceC
}
public void setSelectedTableDataByName(String name) {
TableDataWrapper tableDataWrappe = dsMap.get(name) == null? dsMap.get(name + "_P_CURSOR") : dsMap.get(name);
this.getModel().setSelectedItem(tableDataWrappe);
setResMap(DesignTableDataManager.getEditingTableDataSource());
setDsMap();
// 数据集名称修改后控件传入的还是旧名称
if (DesignTableDataManager.isDsNameChanged(name)) {
name = DesignTableDataManager.getChangedDsNameByOldDsName(name);
}
setSelectedTableData(name);
}
private void setSelectedTableData(String name) {
TableDataWrapper tableDataWrapper = dsMap.get(name) == null ? dsMap.get(name + "_P_CURSOR") : dsMap.get(name);
this.getModel().setSelectedItem(tableDataWrapper);
}
@Override
@ -132,7 +229,7 @@ public class TableDataComboBox extends UIComboBox implements Prepare4DataSourceC
//august:addElement方法竟然会fireItemStateChanged,蛋疼
@Override
protected void fireItemStateChanged(ItemEvent e) {
if (!refresModel) {
if (!refreshModel) {
super.fireItemStateChanged(e);
}
}

3
designer-base/src/main/java/com/fr/design/data/datapane/TreeTableDataDictPane.java

@ -167,8 +167,7 @@ public class TreeTableDataDictPane extends BasicPane implements Previewable {
}
protected void setTableDataNameComboBox(String treeName) {
tableDataNameComboBox = new TableDataComboBox(DesignTableDataManager.getEditingTableDataSource(), treeName);
tableDataNameComboBox = new TableDataComboBox(treeName);
}
private void tdChange(boolean isChangeDS) {

2
designer-base/src/main/java/com/fr/design/editor/editor/ColumnSelectedEditor.java

@ -31,7 +31,7 @@ public class ColumnSelectedEditor extends Editor<SimpleDSColumn> implements Prep
public ColumnSelectedEditor() {
this.setName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_DS_Column"));
this.setLayout(FRGUIPaneFactory.createLeftZeroLayout());
tableDataComboBox = new TableDataComboBox(DesignTableDataManager.getEditingTableDataSource());
tableDataComboBox = new TableDataComboBox();
columnNames = new String[0];
tableDataComboBox.addItemListener(new ItemListener() {

26
designer-base/src/main/java/com/fr/design/fun/DefaultValueAdjustProvider.java

@ -6,6 +6,7 @@ import com.fr.chartx.attr.ChartProvider;
import com.fr.design.style.color.FRColorSelectorStyle;
import com.fr.general.FRFont;
import com.fr.report.cell.CellElement;
import com.fr.stable.StringUtils;
import com.fr.stable.collections.combination.Pair;
import com.fr.stable.fun.mark.Selectable;
@ -83,4 +84,29 @@ public interface DefaultValueAdjustProvider extends Selectable {
default List getColorSelector(){
return FRColorSelectorStyle.COLOR_CONFIG;
}
/**
* 移动端弹窗界面是否支持配置POST传参方式
*
* @return 是否支持
*/
default boolean isNeedPostCombo4MobilePopupPane() {
return false;
}
/**
* JsContentPane是否支持内容提示
* @return 是否支持
*/
default boolean isNeedContentWarning4JsContentPane() {
return false;
}
/**
* 自定义匹配js内容并返回对应的提示文本
* @return <是否匹配提示文本>
*/
default Pair<Boolean, String> checkJsContent(String content) {
return new Pair<>(false, StringUtils.EMPTY);
}
}

49
designer-base/src/main/java/com/fr/design/hyperlink/popup/ContentSettingPane.java

@ -6,10 +6,12 @@ import com.fr.base.Parameter;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.formula.TinyFormulaPane;
import com.fr.design.fun.DefaultValueAdjustProvider;
import com.fr.design.gui.frpane.ReportletParameterViewPane;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ibutton.UIRadioButton;
import com.fr.design.gui.icheckbox.UICheckBox;
import com.fr.design.gui.icombobox.UIComboBox;
import com.fr.design.gui.itableeditorpane.UITableEditAction;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.gui.itree.filetree.ReportletPane;
@ -18,6 +20,7 @@ import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.module.DesignModuleFactory;
import com.fr.design.parameter.ParameterReader;
import com.fr.design.utils.DesignUtils;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.js.MobilePopupHyperlink;
import com.fr.stable.CommonUtils;
@ -25,8 +28,14 @@ import com.fr.stable.FormulaProvider;
import com.fr.stable.ParameterProvider;
import com.fr.stable.StringUtils;
import javax.swing.*;
import java.awt.*;
import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
@ -44,6 +53,7 @@ public class ContentSettingPane extends AbstractHyperLinkPane<MobilePopupHyperli
private JPanel textSettingPanel;
private TinyFormulaPane textContentPane;
private CustomFontPane fontPane;
private UIComboBox postComboBox;
public ContentSettingPane() {
super();
@ -112,7 +122,15 @@ public class ContentSettingPane extends AbstractHyperLinkPane<MobilePopupHyperli
JPanel templateContentPane = new JPanel();
templateContentPane.setLayout(new BorderLayout(0,8));
templateContentPane.add(this.createTemplateSelectPanel(), BorderLayout.NORTH);
if (isNeedShowPostCombo()) {
JPanel jPanel = new JPanel(new BorderLayout(0, 5));
jPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
jPanel.add(this.createTemplateSelectPanel(), BorderLayout.NORTH);
jPanel.add(this.createPostComboPanel(), BorderLayout.SOUTH);
templateContentPane.add(jPanel, BorderLayout.NORTH);
} else {
templateContentPane.add(this.createTemplateSelectPanel(), BorderLayout.NORTH);
}
parameterViewPane = this.createReportletParameterViewPane();
templateContentPane.add(parameterViewPane, BorderLayout.CENTER);
@ -123,6 +141,14 @@ public class ContentSettingPane extends AbstractHyperLinkPane<MobilePopupHyperli
return templateContentPane;
}
private boolean isNeedShowPostCombo() {
DefaultValueAdjustProvider valueAdjust = DesignUtils.getValueAdjust();
if (valueAdjust != null) {
return valueAdjust.isNeedPostCombo4MobilePopupPane();
}
return false;
}
private JPanel createTemplateSelectPanel() {
JPanel templatePanel = FRGUIPaneFactory.createBorderLayout_S_Pane();
// 路径输入框
@ -152,6 +178,15 @@ public class ContentSettingPane extends AbstractHyperLinkPane<MobilePopupHyperli
return MobilePopupUIUtils.createLeftTileRightContentPanel(Toolkit.i18nText("FR-Plugin-Designer_Mobile_Popup_Template"), templatePanel);
}
private JPanel createPostComboPanel() {
JPanel postComboPanel = FRGUIPaneFactory.createBorderLayout_S_Pane();
postComboBox = new UIComboBox(new String[]{"GET", "POST"});
postComboBox.setPreferredSize(new Dimension(60, 20));
postComboBox.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
postComboPanel.add(postComboBox, BorderLayout.WEST);
return MobilePopupUIUtils.createLeftTileRightContentPanel(Toolkit.i18nText("Fine-Design_Basic_Reportlet_Parameter_Type"), postComboPanel);
}
private ReportletParameterViewPane createReportletParameterViewPane() {
ReportletParameterViewPane templateParameterViewPane = new ReportletParameterViewPane(
new UITableEditAction[]{
@ -285,6 +320,10 @@ public class ContentSettingPane extends AbstractHyperLinkPane<MobilePopupHyperli
ParameterProvider[] parameters =link.getParameters();
parameterViewPane.populate(parameters);
if (isNeedShowPostCombo()) {
this.postComboBox.setSelectedIndex(link.isByPost() ? 1 : 0);
}
// 继承参数
extendParametersCheckBox.setSelected(link.isExtendParameters());
}
@ -292,6 +331,10 @@ public class ContentSettingPane extends AbstractHyperLinkPane<MobilePopupHyperli
private void updateTemplateContentBean(MobilePopupHyperlink link) {
link.setReportletPath(templatePathTextField.getText());
if (isNeedShowPostCombo()) {
link.setByPost(postComboBox.getSelectedIndex() == 1);
}
List<ParameterProvider> parameterList = this.parameterViewPane.update();
if (!parameterList.isEmpty()) {
Parameter[] parameters = new Parameter[parameterList.size()];

112
designer-base/src/main/java/com/fr/design/javascript/JSContentPane.java

@ -25,12 +25,19 @@ import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.DesignerContext;
import com.fr.general.IOUtils;
import com.fr.js.JavaScriptImpl;
import com.fr.stable.StringUtils;
import com.fr.stable.collections.combination.Pair;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.SwingConstants;
import javax.swing.SwingWorker;
import javax.swing.border.EmptyBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.FontMetrics;
@ -54,6 +61,13 @@ public class JSContentPane extends BasicPane {
private JSImplPopulateAction jsImplPopulateAction;
private boolean modal;
BasicDialog advancedEditorDialog ;
private JLabel warningLabel;
//用来标记当前显示状态
private boolean showWarning = false;
private static final Color WARING_LABEL_BACKGROUND = Color.decode("#FFFBE6");
private static final Color WARING_LABEL_FOREGROUND = new Color(0, 0, 0, 216);
private JPanel endBracketsPanel;
public JSContentPane(){}
public JSContentPane(String[] args) {
@ -73,14 +87,91 @@ public class JSContentPane extends BasicPane {
UILabel funNameLabel2 = new UILabel();
funNameLabel2.setText("}");
this.add(funNameLabel2, BorderLayout.SOUTH);
if (isNeedContentWarning()) {
endBracketsPanel = FRGUIPaneFactory.createBorderLayout_S_Pane();
endBracketsPanel.add(funNameLabel2, BorderLayout.NORTH);
warningLabel = initWarningLabel();
this.add(endBracketsPanel, BorderLayout.SOUTH);
} else {
this.add(funNameLabel2, BorderLayout.SOUTH);
}
}
protected JLabel initWarningLabel() {
JLabel warningLabel = new JLabel(StringUtils.EMPTY);
warningLabel.setOpaque(true);
warningLabel.setAlignmentX(LEFT_ALIGNMENT);
// 设置左右 5px 的间距
warningLabel.setBorder(new EmptyBorder(0, 5, 0, 5));
warningLabel.setPreferredSize(new Dimension(200, 20));
warningLabel.setBackground(WARING_LABEL_BACKGROUND);
warningLabel.setForeground(WARING_LABEL_FOREGROUND);
addContentListener4Warning();
return warningLabel;
}
private void addContentListener4Warning() {
contentTextArea.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void insertUpdate(DocumentEvent e) {
checkContent(contentTextArea);
}
@Override
public void removeUpdate(DocumentEvent e) {
checkContent(contentTextArea);
}
@Override
public void changedUpdate(DocumentEvent e) {
checkContent(contentTextArea);
}
});
}
private void checkContent(RSyntaxTextArea contentTextArea) {
String content = contentTextArea.getText().trim();
Pair<Boolean, String> pair = checkContent(content);
boolean matches = Boolean.TRUE.equals(pair.getFirst());
String tip = pair.getSecond() != null ? pair.getSecond() : StringUtils.EMPTY;
// 更新提示
updateWarningTip(tip);
if (matches == showWarning) {
return;
}
if (matches) {
addWarningLabel();
showWarning = true;
} else {
removeWarningLabel();
showWarning = false;
}
}
protected void updateWarningTip(String tip) {
if (!StringUtils.equals(warningLabel.getText(), tip)) {
warningLabel.setText(tip);
}
}
protected void removeWarningLabel() {
endBracketsPanel.remove(warningLabel);
endBracketsPanel.revalidate();
}
protected void addWarningLabel() {
endBracketsPanel.add(warningLabel, BorderLayout.SOUTH);
endBracketsPanel.revalidate();
}
public JSContentPane(String[] args,boolean modal) {
this(args);
this.modal = modal;
}
public void setJsImplUpdateAction(JSImplUpdateAction jsImplUpdateAction){
this.jsImplUpdateAction = jsImplUpdateAction;
}
@ -93,7 +184,6 @@ public class JSContentPane extends BasicPane {
this.javaScript = javaScript;
}
private void addNewPaneLabel(){
UILabel advancedEditorLabel = new UILabel(Toolkit.i18nText("Fine-Design_Advanced_Editor"), IconUtils.readIcon("com/fr/design/images/edit/advancedEditor.svg"), SwingConstants.LEFT);
advancedEditorLabel.setCursor(new Cursor(Cursor.HAND_CURSOR));
@ -328,4 +418,20 @@ public class JSContentPane extends BasicPane {
protected boolean needAdvancedEditor() {
return true;
}
/**
* 是否支持内容提示
* @return 是否支持
*/
protected boolean isNeedContentWarning() {
return false;
}
/**
* 自定义匹配js内容并返回对应的提示文本
* @return <是否匹配提示文本>
*/
protected Pair<Boolean, String> checkContent(String content) {
return new Pair<>(false, StringUtils.EMPTY);
}
}

32
designer-base/src/main/java/com/fr/design/javascript/JSContentWithDescriptionPane.java

@ -32,6 +32,7 @@ import javax.swing.BorderFactory;
import javax.swing.DefaultListCellRenderer;
import javax.swing.DefaultListModel;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
@ -71,7 +72,6 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.ExecutionException;
public class JSContentWithDescriptionPane extends JSContentPane implements KeyListener {
@ -95,6 +95,9 @@ public class JSContentWithDescriptionPane extends JSContentPane implements KeyLi
private JPopupMenu popupMenu;
private JPanel endBracketsPanel;
private JLabel warningLabel;
private InterfaceAndDescriptionPanel interfaceAndDescriptionPanel;
private JList helpDOCList;
@ -159,8 +162,13 @@ public class JSContentWithDescriptionPane extends JSContentPane implements KeyLi
endBracketsLabel.setText("}");
//结尾括号和复用函数按钮面板
JPanel endBracketsPanel = FRGUIPaneFactory.createBorderLayout_S_Pane();
endBracketsPanel.add(endBracketsLabel, BorderLayout.WEST);
endBracketsPanel = FRGUIPaneFactory.createBorderLayout_S_Pane();
if (isNeedContentWarning()) {
warningLabel = initWarningLabel();
endBracketsPanel.add(endBracketsLabel, BorderLayout.NORTH);
} else {
endBracketsPanel.add(endBracketsLabel, BorderLayout.WEST);
}
JPanel northPanel = FRGUIPaneFactory.createBorderLayout_S_Pane();
northPanel.add(jsParaAndSearchPane, BorderLayout.NORTH);
@ -178,6 +186,24 @@ public class JSContentWithDescriptionPane extends JSContentPane implements KeyLi
this.add(functionNameAndDescriptionPanel, BorderLayout.SOUTH);
}
protected void updateWarningTip(String tip) {
if (!StringUtils.equals(warningLabel.getText(), tip)) {
warningLabel.setText(tip);
}
}
@Override
protected void removeWarningLabel() {
endBracketsPanel.remove(warningLabel);
endBracketsPanel.revalidate();
}
@Override
protected void addWarningLabel() {
endBracketsPanel.add(warningLabel, BorderLayout.SOUTH);
endBracketsPanel.revalidate();
}
public void populate(String js) {
contentTextArea.setText(js);
ifHasBeenWriten = 1;

23
designer-base/src/main/java/com/fr/design/javascript/JavaScriptImplPane.java

@ -3,6 +3,7 @@ package com.fr.design.javascript;
import com.fr.base.Parameter;
import com.fr.design.data.tabledata.tabledatapane.OneListTableModel;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.fun.DefaultValueAdjustProvider;
import com.fr.design.gui.frpane.ReportletParameterViewPane;
import com.fr.design.gui.itableeditorpane.ParameterTableModel;
import com.fr.design.gui.itableeditorpane.UITableEditAction;
@ -13,10 +14,12 @@ import com.fr.design.javascript.jsapi.JSImplPopulateAction;
import com.fr.design.javascript.jsapi.JSImplUpdateAction;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.scrollruler.ModLineBorder;
import com.fr.design.utils.DesignUtils;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.js.JavaScriptImpl;
import com.fr.stable.ParameterProvider;
import com.fr.stable.StringUtils;
import com.fr.stable.collections.combination.Pair;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
@ -84,7 +87,25 @@ public class JavaScriptImplPane extends AbstractHyperLinkPane<JavaScriptImpl> {
}
protected JSContentPane createJSContentPane(String[] defaultArgs){
JSContentPane jsContentPane= new JSContentPane(defaultArgs,modal);
JSContentPane jsContentPane= new JSContentPane(defaultArgs,modal) {
@Override
protected boolean isNeedContentWarning() {
DefaultValueAdjustProvider valueAdjust = DesignUtils.getValueAdjust();
if (valueAdjust != null) {
return valueAdjust.isNeedContentWarning4JsContentPane();
}
return super.isNeedContentWarning();
}
@Override
protected Pair<Boolean, String> checkContent(String content) {
DefaultValueAdjustProvider valueAdjust = DesignUtils.getValueAdjust();
if (valueAdjust != null) {
return valueAdjust.checkJsContent(content);
}
return super.checkContent(content);
}
};
jsContentPane.setJsImplUpdateAction(new JSImplUpdateAction() {
@Override
public void update(JavaScriptImpl javaScript) {

23
designer-base/src/main/java/com/fr/design/javascript/NewJavaScriptImplPane.java

@ -1,7 +1,10 @@
package com.fr.design.javascript;
import com.fr.design.fun.DefaultValueAdjustProvider;
import com.fr.design.utils.DesignUtils;
import com.fr.js.JavaScriptImpl;
import com.fr.stable.collections.combination.Pair;
public class NewJavaScriptImplPane extends JavaScriptImplPane {
@ -10,7 +13,25 @@ public class NewJavaScriptImplPane extends JavaScriptImplPane {
}
protected JSContentPane createJSContentPane(String[] defaultArgs){
return new JSContentWithDescriptionPane(defaultArgs);
return new JSContentWithDescriptionPane(defaultArgs) {
@Override
protected boolean isNeedContentWarning() {
DefaultValueAdjustProvider valueAdjust = DesignUtils.getValueAdjust();
if (valueAdjust != null) {
return valueAdjust.isNeedContentWarning4JsContentPane();
}
return super.isNeedContentWarning();
}
@Override
protected Pair<Boolean, String> checkContent(String content) {
DefaultValueAdjustProvider valueAdjust = DesignUtils.getValueAdjust();
if (valueAdjust != null) {
return valueAdjust.checkJsContent(content);
}
return super.checkContent(content);
}
};
}
public void populate(JavaScriptImpl javaScript) {

2
designer-base/src/main/java/com/fr/design/present/dict/TableDataDictPane.java

@ -83,7 +83,7 @@ public class TableDataDictPane extends FurtherBasicBeanPane<TableDataDictionary>
}
private void initBasicComponets() {
tableDataNameComboBox = new TableDataComboBox(DesignTableDataManager.getEditingTableDataSource());
tableDataNameComboBox = new TableDataComboBox();
tableDataNameComboBox.addItemListener(e -> {
if (e.getStateChange() == ItemEvent.SELECTED) {
tdChange(e);

54
designer-base/src/main/java/com/fr/design/ui/util/UIUtil.java

@ -3,9 +3,12 @@ package com.fr.design.ui.util;
import com.fr.log.FineLoggerFactory;
import com.fr.third.guava.base.Stopwatch;
import com.fr.third.guava.base.Supplier;
import java.util.concurrent.ExecutionException;
import java.util.function.Consumer;
import javax.swing.SwingWorker;
import javax.swing.SwingUtilities;
import org.jetbrains.annotations.NotNull;
import javax.swing.SwingUtilities;
import java.util.concurrent.TimeUnit;
/**
@ -81,4 +84,53 @@ public class UIUtil {
}
return result;
}
/**
* 执行异步任务并在任务完成后更新UI
* <p>
* 该方法将执行一个耗时的后台任务并在任务完成后将结果传递给一个回调函数来更新UI
* 使用 SwingWorker 来处理后台任务确保在任务完成后回到 EDT事件分发线程 更新 UI
* 提供了一个可选的 `finallyBlock` 参数用于执行清理操作例如释放资源或重置状态
*
* @param <T> 任务结果的类型
* @param task 需要在后台执行的任务该任务的执行过程由 Supplier 提供返回任务的结果
* @param uiUpdater 在任务完成后执行的回调函数用来处理结果并更新UI
* @param finallyBlock 可选的清理操作在任务结束后无论是否发生异常都会执行可以传入 null 表示不需要清理操作常见场景包括状态标志的重置或资源释放
*
*/
public static <T> void executeAsyncTaskAndUpdateUI(Supplier<T> task, Consumer<T> uiUpdater, Runnable finallyBlock) {
new SwingWorker<T, Void>() {
@Override
protected T doInBackground() throws Exception {
return task.get();
}
@Override
protected void done() {
try {
T result = get();
uiUpdater.accept(result);
} catch (InterruptedException | ExecutionException e) {
FineLoggerFactory.getLogger().debug(e.getMessage(), e);
} finally {
if (finallyBlock != null) {
finallyBlock.run();
}
}
}
}.execute();
}
/**
* 执行异步任务并在任务完成后更新UI
* <p>
* 该方法将执行一个耗时的后台任务并在任务完成后将结果传递给一个回调函数来更新UI
* 使用 SwingWorker 来处理后台任务确保在任务完成后回到 EDT事件分发线程 更新 UI
*
* @param <T> 任务结果的类型
* @param task 需要在后台执行的任务该任务的执行过程由 Supplier 提供返回任务的结果
* @param uiUpdater 在任务完成后执行的回调函数用来处理结果并更新UI
*/
public static <T> void executeAsyncTaskAndUpdateUI(Supplier<T> task, Consumer<T> uiUpdater) {
executeAsyncTaskAndUpdateUI(task, uiUpdater, null);
}
}

2
designer-chart/src/main/java/com/fr/design/chart/AutoChartTypePane.java

@ -141,7 +141,7 @@ public class AutoChartTypePane extends ChartWizardPane implements CallbackEvent
}
private void initDataFiledBox() {
tableNameComboBox = new TableDataComboBox(DesignTableDataManager.getEditingTableDataSource());
tableNameComboBox = new TableDataComboBox();
tableNameComboBox.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {

2
designer-chart/src/main/java/com/fr/design/chartx/component/MapAreaMatchPane.java

@ -128,7 +128,7 @@ public class MapAreaMatchPane extends BasicBeanPane<MapMatchResult> {
}
private void initButtonGroup() {
tableNameCombox = new TableDataComboBox(DesignTableDataManager.getEditingTableDataSource());
tableNameCombox = new TableDataComboBox();
tableNameCombox.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {

5
designer-chart/src/main/java/com/fr/design/mainframe/ChartPropertyPane.java

@ -9,18 +9,17 @@ import com.fr.base.chart.BaseChartCollection;
import com.fr.chart.chartattr.ChartCollection;
import com.fr.chart.charttypes.ChartTypeManager;
import com.fr.chartx.attr.ChartProvider;
import com.fr.decision.webservice.v10.map.geojson.helper.GEOJSONHelper;
import com.fr.design.ChartTypeInterfaceManager;
import com.fr.design.designer.TargetComponent;
import com.fr.design.gui.chart.BaseChartPropertyPane;
import com.fr.design.gui.chart.ChartEditPaneProvider;
import com.fr.design.gui.frpane.UITitlePanel;
import com.fr.design.mainframe.chart.ChartEditPane;
import com.fr.design.ui.util.UIUtil;
import com.fr.design.utils.gui.GUICoreUtils;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.SwingWorker;
import java.awt.BorderLayout;
import java.awt.Component;
@ -116,7 +115,7 @@ public class ChartPropertyPane extends BaseChartPropertyPane {
*/
public void populateChartPropertyPane(BaseChartCollection collection, TargetComponent<?> ePane) {
if (collection instanceof ChartCollection) {
populateChartPropertyPane((ChartCollection) collection, ePane);
UIUtil.invokeAndWaitIfNeeded(() -> populateChartPropertyPane((ChartCollection) collection, ePane));
}
}

2
designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/data/DatabaseTableDataPane.java

@ -82,7 +82,7 @@ public class DatabaseTableDataPane extends BasicPane{
}
private void initTableCombox() {
tableNameCombox = new TableDataComboBox(DesignTableDataManager.getEditingTableDataSource()){
tableNameCombox = new TableDataComboBox(){
//图表的数据集选择下拉框,不需要注册监听,chartEditPane已经注册了。
public void registerDSChangeListener() {

2
designer-realize/src/main/java/com/fr/design/dscolumn/SelectedDataColumnPane.java

@ -330,7 +330,7 @@ public class SelectedDataColumnPane extends BasicPane {
protected void initTableNameComboBox() {
tableNameComboBox = new TableDataComboBox(DesignTableDataManager.getEditingTableDataSource());
tableNameComboBox = new TableDataComboBox();
tableNameComboBox.setPreferredSize(new Dimension(100, 20));
}

Loading…
Cancel
Save