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