From 221f1cd6e33756e1f69d40ae05847f119f76b587 Mon Sep 17 00:00:00 2001 From: "Richard.Fang" <richard.fang@fanruan.com> Date: Tue, 14 Jan 2025 09:39:32 +0800 Subject: [PATCH 1/2] =?UTF-8?q?REPORT-146163=20fix:comboBox=E7=9A=84refres?= =?UTF-8?q?h=E6=B5=81=E7=A8=8B=E4=B8=AD=E9=9D=9EUI=E6=93=8D=E4=BD=9C?= =?UTF-8?q?=E5=90=8E=E5=8F=B0=E6=89=A7=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../data/datapane/TableDataComboBox.java | 42 +++++++++++++------ 1 file changed, 29 insertions(+), 13 deletions(-) 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 + * 刷新数据源并更新下拉框的模型和选中项 + * <p> + * - 更新下拉框模型时,会暂时记录当前选中项,并在刷新后恢复选中项 + * - 通过标记 `refreshModel`,避免刷新模型时触发不必要的选中事件 + * <p> + * 关于 `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) { From 6350f426a5fdefd57f8d65c336ff8e05a49d9cb8 Mon Sep 17 00:00:00 2001 From: "Richard.Fang" <richard.fang@fanruan.com> Date: Tue, 14 Jan 2025 10:03:30 +0800 Subject: [PATCH 2/2] =?UTF-8?q?REPORT-146163=20fix:=E8=B0=83=E6=95=B4?= =?UTF-8?q?=E4=B8=8BrefreshComboBoxModel=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../data/datapane/TableDataComboBox.java | 46 ++++++++++--------- 1 file changed, 25 insertions(+), 21 deletions(-) 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 129851d8ed..692f940d69 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 @@ -133,17 +133,8 @@ public class TableDataComboBox extends UIComboBox implements Prepare4DataSourceC /** * 刷新数据源并更新下拉框的模型和选中项 - * <p> - * - 更新下拉框模型时,会暂时记录当前选中项,并在刷新后恢复选中项 - * - 通过标记 `refreshModel`,避免刷新模型时触发不必要的选中事件 - * <p> - * 关于 `refreshModel` 的作用: - * 1. **抑制事件触发**:下拉框模型在调用 `addElement` 方法时会触发 `fireItemStateChanged` 事件, - * 2. **处理异步和顺序问题**:由于取数的异步执行会导致回调后的UI操作与 `populateBean` 方法调用顺序出现交错 - * (例如:先执行 `refresh` 的取数操作,然后调用 `populateBean`,最后刷新模型) - * 确保刷新模型但不触发选中事件,以避免引发不必要的逻辑干扰 * - * @param source 数据源,用于刷新model + * @param source 数据源,用于刷新模型 */ public void refresh(TableDataSource source) { UIUtil.executeAsyncTaskAndUpdateUI( @@ -152,19 +143,32 @@ public class TableDataComboBox extends UIComboBox implements Prepare4DataSourceC setDsMap(); return null; }, - result -> { - refreshModel = true; - // 获取当前选中的数据项 - TableDataWrapper selectedItem = getSelectedItem(); - // 刷新model,本次操作会重置选中的数据项 - refreshComboBoxModel(); - // 刷新model后恢复选中的数据项 - updateSelectedItem(selectedItem); - refreshModel = false; - } + 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) { this.resMap = DesignTableDataManager.getAllEditingDataSet(source); } @@ -173,7 +177,7 @@ public class TableDataComboBox extends UIComboBox implements Prepare4DataSourceC dsMap = DesignTableDataManager.getAllDataSetIncludingProcedure(resMap); } - private void refreshComboBoxModel() { + private void refreshModel() { //创建ComboBox模型并设置 DefaultComboBoxModel model = new DefaultComboBoxModel(); this.setModel(model);