diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/TableDataComboBox.java b/designer-base/src/main/java/com/fr/design/data/datapane/TableDataComboBox.java index 136181bcd8..129851d8ed 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/TableDataComboBox.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/TableDataComboBox.java @@ -117,7 +117,7 @@ public class TableDataComboBox extends UIComboBox implements Prepare4DataSourceC @Override public void ancestorAdded(AncestorEvent event) { registerDSChangeListener(); - UIUtil.invokeLaterIfNeeded(() -> refresh(DesignTableDataManager.getEditingTableDataSource())); + refresh(DesignTableDataManager.getEditingTableDataSource()); } @Override @@ -132,21 +132,37 @@ public class TableDataComboBox extends UIComboBox implements Prepare4DataSourceC } /** - * refresh ComboBox + * 刷新数据源并更新下拉框的模型和选中项 + *

+ * - 更新下拉框模型时,会暂时记录当前选中项,并在刷新后恢复选中项 + * - 通过标记 `refreshModel`,避免刷新模型时触发不必要的选中事件 + *

+ * 关于 `refreshModel` 的作用: + * 1. **抑制事件触发**:下拉框模型在调用 `addElement` 方法时会触发 `fireItemStateChanged` 事件, + * 2. **处理异步和顺序问题**:由于取数的异步执行会导致回调后的UI操作与 `populateBean` 方法调用顺序出现交错 + * (例如:先执行 `refresh` 的取数操作,然后调用 `populateBean`,最后刷新模型) + * 确保刷新模型但不触发选中事件,以避免引发不必要的逻辑干扰 * - * @param source 数据源 + * @param source 数据源,用于刷新model */ public void refresh(TableDataSource source) { - refreshModel = true; - setResMap(source); - setDsMap(); - // 获取当前选中的数据项 - TableDataWrapper dataWrapper = getSelectedItem(); - // 更新下拉模型 - refreshComboBoxModel(); - //处理已选中的数据项 - updateSelectedItem(dataWrapper); - refreshModel = false; + UIUtil.executeAsyncTaskAndUpdateUI( + () -> { + setResMap(source); + setDsMap(); + return null; + }, + result -> { + refreshModel = true; + // 获取当前选中的数据项 + TableDataWrapper selectedItem = getSelectedItem(); + // 刷新model,本次操作会重置选中的数据项 + refreshComboBoxModel(); + // 刷新model后恢复选中的数据项 + updateSelectedItem(selectedItem); + refreshModel = false; + } + ); } protected void setResMap(TableDataSource source) {