|
|
|
package com.fr.design.data.datapane;
|
|
|
|
|
|
|
|
import com.fr.design.ui.util.UIUtil;
|
|
|
|
import java.awt.Component;
|
|
|
|
import java.awt.event.ItemEvent;
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
import com.fr.design.constants.UIConstants;
|
|
|
|
import com.fr.design.data.DesignTableDataManager;
|
|
|
|
import com.fr.data.TableDataSource;
|
|
|
|
import com.fr.design.data.tabledata.Prepare4DataSourceChange;
|
|
|
|
import com.fr.design.data.tabledata.wrapper.TemplateTableDataWrapper;
|
|
|
|
import com.fr.design.data.tabledata.wrapper.TableDataWrapper;
|
|
|
|
import com.fr.design.gui.icombobox.UIComboBox;
|
|
|
|
import com.fr.design.gui.icombobox.UIComboBoxRenderer;
|
|
|
|
import com.fr.general.ComparatorUtils;
|
|
|
|
import com.fr.stable.StringUtils;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 包含所有数据集的下拉框
|
|
|
|
*
|
|
|
|
* @author zhou
|
|
|
|
* @since 2012-4-20上午10:34:30
|
|
|
|
*/
|
|
|
|
public class TableDataComboBox extends UIComboBox implements Prepare4DataSourceChange {
|
|
|
|
protected java.util.Map<String, TableDataWrapper> resMap;
|
|
|
|
private java.util.Map<String, TableDataWrapper> dsMap;
|
|
|
|
private static final long serialVersionUID = 1L;
|
|
|
|
private boolean refreshModel = false;
|
|
|
|
private String treeName = StringUtils.EMPTY; //树数据集本身的名字
|
|
|
|
private ChangeListener changeListener;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 兼容插件调用
|
|
|
|
*
|
|
|
|
* @param source 传入的数据源
|
|
|
|
*/
|
|
|
|
public TableDataComboBox(TableDataSource source){
|
|
|
|
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();
|
|
|
|
setListCellRenderer();
|
|
|
|
addComboBoxListener();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 设置渲染器
|
|
|
|
*/
|
|
|
|
private void setListCellRenderer() {
|
|
|
|
this.setRenderer(new UIComboBoxRenderer() {
|
|
|
|
private static final long serialVersionUID = 1L;
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
|
|
|
|
JLabel renderer = (JLabel)super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
|
|
|
|
if (value instanceof TableDataWrapper) {
|
|
|
|
TableDataWrapper tabledatawrappe = (TableDataWrapper)value;
|
|
|
|
renderer.setIcon(tabledatawrappe.getIcon());
|
|
|
|
renderer.setText(tabledatawrappe.getTableDataName());
|
|
|
|
renderer.setToolTipText(tabledatawrappe.getTableDataName());
|
|
|
|
} else {
|
|
|
|
renderer.setIcon(null);
|
|
|
|
renderer.setText(StringUtils.EMPTY);
|
|
|
|
}
|
|
|
|
return renderer;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 在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) {
|
|
|
|
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) {
|
|
|
|
this.resMap = DesignTableDataManager.getAllEditingDataSet(source);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void setDsMap() {
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 向resMap中添加TableData信息
|
|
|
|
* @param name 数据集名字
|
|
|
|
* @param templateTableDataWrappe 数据集
|
|
|
|
*/
|
|
|
|
public void putTableDataIntoMap(String name, TemplateTableDataWrapper templateTableDataWrappe) {
|
|
|
|
if (dsMap.containsKey(name)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
this.addItem(templateTableDataWrappe);
|
|
|
|
dsMap.put(name, templateTableDataWrappe);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setSelectedTableDataByName(String name) {
|
|
|
|
setResMap(DesignTableDataManager.getEditingTableDataSource());
|
|
|
|
setDsMap();
|
|
|
|
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
|
|
|
|
public TableDataWrapper getSelectedItem() {
|
|
|
|
if (dataModel.getSelectedItem() instanceof TableDataWrapper) {
|
|
|
|
return (TableDataWrapper)dataModel.getSelectedItem();
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
//august:addElement方法竟然会fireItemStateChanged,蛋疼
|
|
|
|
@Override
|
|
|
|
protected void fireItemStateChanged(ItemEvent e) {
|
|
|
|
if (!refreshModel) {
|
|
|
|
super.fireItemStateChanged(e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*注册listener,相应数据集改变
|
|
|
|
*/
|
|
|
|
@Override
|
|
|
|
public void registerDSChangeListener() {
|
|
|
|
changeListener = new ChangeListener() {
|
|
|
|
@Override
|
|
|
|
public void stateChanged(ChangeEvent e) {
|
|
|
|
TableDataComboBox.this.refresh(DesignTableDataManager.getEditingTableDataSource());
|
|
|
|
}
|
|
|
|
};
|
|
|
|
DesignTableDataManager.addDsChangeListener(changeListener);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void registerGlobalDSChangeListener() {
|
|
|
|
DesignTableDataManager.addGlobalDsChangeListener(changeListener);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|