帆软报表设计器源代码。
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

555 lines
18 KiB

package com.fr.design.gui.controlpane;
import com.fr.design.beans.BasicBeanPane;
import com.fr.design.constants.UIConstants;
import com.fr.design.gui.icontainer.UIScrollPane;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.ilist.JNameEdList;
import com.fr.design.gui.ilist.ListModelElement;
import com.fr.design.gui.ilist.ModNameActionListener;
import com.fr.design.gui.ilist.UIList;
import com.fr.design.gui.ilist.UINameEdList;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.widget.EventCreator;
import com.fr.form.event.Listener;
import com.fr.form.ui.Widget;
import com.fr.general.NameObject;
import com.fr.report.web.util.ReportEngineEventMapping;
import com.fr.stable.ArrayUtils;
import com.fr.stable.Nameable;
import com.fr.stable.StringUtils;
import javax.swing.BorderFactory;
import javax.swing.DefaultListModel;
import javax.swing.JPanel;
import javax.swing.ListModel;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* Created by kerry on 5/31/21
*/
public abstract class UIListGroupControlPane extends UIControlPane implements ListControlPaneProvider {
private boolean isPopulating = false;
private UINameEdList selectNameEdList;
private Map<String, ListWrapperPane> nameEdListMap = new HashMap<>();
private CommonShortCutHandlers commonHandlers;
private ListControlPaneHelper helper;
private JPanel contentPane;
public JPanel getContentPane() {
return contentPane;
}
private ListControlPaneHelper getHelper() {
if (helper == null) {
helper = ListControlPaneHelper.newInstance(this);
}
return helper;
}
private CommonShortCutHandlers getCommonHandlers() {
if (commonHandlers == null) {
commonHandlers = CommonShortCutHandlers.newInstance(this);
}
return commonHandlers;
}
public boolean isPopulating() {
return isPopulating;
}
@Override
protected void initLeftPane(JPanel leftPane) {
leftPane.add(new UIScrollPane(contentPane = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, FlowLayout.LEADING, 0, 0)), BorderLayout.CENTER);
}
protected void refreshPane(Widget widget, NameableCreator[] creators) {
refreshContentPane(widget.supportedEvents());
refreshNameableCreator(creators);
populateNameObjects(widget);
}
private void refreshContentPane(String[] supportedEvents) {
for (String event : supportedEvents) {
if (nameEdListMap.containsKey(event)) {
continue;
}
UINameEdList list = createJNameList(event);
ListWrapperPane wrapperPane = new ListWrapperPane(switchLang(event), list);
if (this.selectNameEdList == null) {
this.selectNameEdList = wrapperPane.getNameEdList();
}
contentPane.add(wrapperPane);
nameEdListMap.put(event, wrapperPane);
}
contentPane.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
super.mousePressed(e);
if (selectNameEdList != null) {
selectNameEdList.stopEditing();
}
}
});
}
protected void populateNameObjects(Widget widget) {
ArrayList<NameObject> nameObjectList = new ArrayList<>();
for (int i = 0, size = widget.getListenerSize(); i < size; i++) {
Listener listener = widget.getListener(i);
if (!listener.isDefault()) {
nameObjectList.add(i, new NameObject(switchLang(listener.getEventName()) + (i + 1), listener));
}
}
populate(getHelper().processCatalog(nameObjectList));
checkButtonEnabled();
this.repaint();
}
private void populate(Map<String, List<NameObject>> map) {
isPopulating = true; // 加一个标识位,避免切换单元格时,触发 saveSettings
Iterator<Map.Entry<String, List<NameObject>>> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, List<NameObject>> entry = iterator.next();
List<NameObject> valueList = entry.getValue();
ListWrapperPane eventListWrapperPane = nameEdListMap.get(entry.getKey());
populateChildNameList(eventListWrapperPane.getNameEdList(), valueList.toArray(new NameObject[valueList.size()]));
}
this.checkButtonEnabled();
refreshEventListWrapperPane();
this.checkGroupPaneSize();
isPopulating = false;
}
private void refreshEventListWrapperPane() {
Iterator<Map.Entry<String, ListWrapperPane>> iterator = nameEdListMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, ListWrapperPane> entry = iterator.next();
ListWrapperPane eventListWrapperPane = entry.getValue();
UINameEdList nameEdList = eventListWrapperPane.getNameEdList();
int listSize = nameEdList.getModel().getSize();
if (this.selectNameEdList.getModel().getSize() == 0 && listSize > 0) {
this.selectNameEdList = nameEdList;
}
eventListWrapperPane.setVisible(listSize > 0);
}
if (this.selectNameEdList != null) {
this.selectNameEdList.setSelectedIndex(0);
}
this.repaint();
}
private void populateChildNameList(UINameEdList nameableList, Nameable[] nameableArray) {
nameableList.getCellEditor().stopCellEditing();
DefaultListModel listModel = (DefaultListModel) nameableList.getModel();
listModel.removeAllElements();
if (ArrayUtils.isEmpty(nameableArray)) {
isPopulating = false;
return;
}
listModel.setSize(nameableArray.length);
for (int i = 0; i < nameableArray.length; i++) {
listModel.set(i, new ListModelElement(nameableArray[i]));
}
}
private UINameEdList createJNameList(String text) {
UINameEdList nameEdList = new UINameEdList(new DefaultListModel()) {
@Override
protected void doAfterLostFocus() {
((JControlUpdatePane) controlUpdatePane).update();
}
@Override
protected void doAfterStopEditing() {
saveSettings();
}
};
nameEdList.setCellRenderer(new UINameableListCellRenderer(true, this.creators));
nameEdList.setName(text);
nameEdList.setSelectionBackground(UIConstants.ATTRIBUTE_PRESS);
nameEdList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
nameEdList.addMouseListener(new MouseAdapter() {
@Override
public void mouseReleased(MouseEvent e) {
selectNameEdList = nameEdList;
updateUINameListSelect();
}
});
nameEdList.addMouseListener(getHelper().getListMouseListener(nameEdList, this));
nameEdList.addModNameActionListener(new ModNameActionListener() {
@Override
public void nameModed(int index, String oldName, String newName) {
checkGroupPaneSize();
saveSettings();
}
});
nameEdList.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent evt) {
// richie:避免多次update和populate大大降低效率
if (!evt.getValueIsAdjusting()) {
// shoc 切换的时候加检验
if (hasInvalid(false)) {
return;
}
((JControlUpdatePane) UIListGroupControlPane.this.controlUpdatePane).update();
((JControlUpdatePane) UIListGroupControlPane.this.controlUpdatePane).populate();
UIListGroupControlPane.this.checkButtonEnabled();
}
}
});
nameEdList.getModel().addListDataListener(new ListDataListener() {
@Override
public void intervalAdded(ListDataEvent e) {
saveSettings();
}
@Override
public void intervalRemoved(ListDataEvent e) {
saveSettings();
}
@Override
public void contentsChanged(ListDataEvent e) {
saveSettings();
}
});
return nameEdList;
}
private void updateUINameListSelect() {
Iterator<Map.Entry<String, ListWrapperPane>> iterator = nameEdListMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, ListWrapperPane> entry = iterator.next();
UINameEdList nameEdList = entry.getValue().getNameEdList();
if (nameEdList != selectNameEdList) {
nameEdList.clearSelection();
}
}
}
@Override
public void checkButtonEnabled() {
getHelper().checkButtonEnabled();
}
private String switchLang(String eventName) {
// 在 properties 文件中找到相应的 key 值
String localeKey = ReportEngineEventMapping.getLocaleName(eventName);
return com.fr.design.i18n.Toolkit.i18nText(localeKey);
}
/**
* 生成不重复的名字
*
* @param prefix 名字前缀
* @return 名字
*/
@Override
public String createUnrepeatedName(String prefix) {
return getCommonHandlers().createUnrepeatedName(prefix);
}
private void updateSelectedNameList(NameableCreator creator) {
String eventName = ((EventCreator) creator).getEventName();
ListWrapperPane wrapperPane = nameEdListMap.get(eventName);
wrapperPane.setVisible(true);
setSelectNameEdList(wrapperPane.getNameEdList());
}
private void setSelectNameEdList(UINameEdList nameEdList) {
if (this.selectNameEdList != null) {
this.selectNameEdList.clearSelection();
}
this.selectNameEdList = nameEdList;
}
@Override
public void onAddItem(NameableCreator creator) {
updateSelectedNameList(creator);
getCommonHandlers().onAddItem(creator);
checkGroupPaneSize();
}
@Override
public void onRemoveItem() {
getCommonHandlers().onRemoveItem();
refreshEventListWrapperPane();
checkGroupPaneSize();
}
@Override
public void onCopyItem() {
getCommonHandlers().onCopyItem();
checkGroupPaneSize();
}
private void checkGroupPaneSize() {
int width = 180;
Iterator<Map.Entry<String, ListWrapperPane>> iterator = nameEdListMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, ListWrapperPane> entry = iterator.next();
ListWrapperPane wrapperPane = entry.getValue();
UIList uiList = wrapperPane.getNameEdList();
width = Math.max(width, calculateUIListMaxCellWidth(uiList.getModel(), uiList.getFontMetrics(uiList.getFont())));
}
iterator = nameEdListMap.entrySet().iterator();
width += 40;
while (iterator.hasNext()) {
Map.Entry<String, ListWrapperPane> entry = iterator.next();
ListWrapperPane wrapperPane = entry.getValue();
UIList uiList = wrapperPane.getNameEdList();
uiList.setFixedCellWidth(width);
}
}
private int calculateUIListMaxCellWidth(ListModel model, FontMetrics fontMetrics) {
int width = 0;
for (int i = 0; i < model.getSize(); i++) {
Object element = model.getElementAt(i);
if (element != null) {
String text;
if (element instanceof ListModelElement) {
text = ((ListModelElement) element).wrapper.getName();
} else {
text = element.toString();
}
width = Math.max(width, fontMetrics.stringWidth(text));
}
}
return width;
}
@Override
public void onMoveUpItem() {
getCommonHandlers().onMoveUpItem();
}
@Override
public void onMoveDownItem() {
getCommonHandlers().onMoveDownItem();
}
@Override
public void onSortItem(boolean isAtoZ) {
Iterator<Map.Entry<String, ListWrapperPane>> iterator = nameEdListMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, ListWrapperPane> entry = iterator.next();
UINameEdList nameEdList = entry.getValue().getNameEdList();
getCommonHandlers().onSortItem(isAtoZ, nameEdList);
}
}
@Override
public boolean isItemSelected() {
return getModel().getSize() > 0 && getSelectedIndex() != -1;
}
@Override
protected JPanel createControlUpdatePane() {
return JControlUpdatePane.newInstance(this);
}
@Override
public Nameable[] update() {
List<Nameable> res = new ArrayList<Nameable>();
getControlUpdatePane().update();
Iterator<Map.Entry<String, ListWrapperPane>> iterator = nameEdListMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, ListWrapperPane> entry = iterator.next();
UINameEdList nameEdList = entry.getValue().getNameEdList();
DefaultListModel listModel = (DefaultListModel) nameEdList.getModel();
for (int i = 0, len = listModel.getSize(); i < len; i++) {
res.add(((ListModelElement) listModel.getElementAt(i)).wrapper);
}
}
return res.toArray(new Nameable[0]);
}
@Override
public abstract NameableCreator[] createNameableCreators();
@Override
public abstract void saveSettings();
public BasicBeanPane createPaneByCreators(NameableCreator creator) {
try {
return creator.getUpdatePane().newInstance();
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
public BasicBeanPane createPaneByCreators(NameableCreator creator, String string) {
Constructor constructor = null;
try {
constructor = creator.getUpdatePane().getDeclaredConstructor(new Class[]{String.class});
constructor.setAccessible(true);
return (BasicBeanPane) constructor.newInstance(string);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}
@Override
public DefaultListModel getModel() {
if (this.selectNameEdList == null) {
return new DefaultListModel();
}
return (DefaultListModel) this.selectNameEdList.getModel();
}
/**
* 检查是否符合规范
*
* @throws Exception
*/
@Override
public void checkValid() throws Exception {
((JControlUpdatePane) this.controlUpdatePane).checkValid();
}
@Override
public boolean hasInvalid(boolean isAdd) {
return getHelper().hasInvalid(isAdd);
}
public void addNameable(Nameable nameable, int index) {
getHelper().addNameable(nameable, index);
popupEditDialog();
}
/**
* 设置选中项
*
* @param index 选中项的序列号
*/
public void setSelectedIndex(int index) {
if (this.selectNameEdList != null) {
this.selectNameEdList.setSelectedIndex(index);
}
}
@Override
public int getSelectedIndex() {
if (this.selectNameEdList == null) {
return -1;
}
return this.selectNameEdList.getSelectedIndex();
}
@Override
public ListModelElement getSelectedValue() {
if (this.selectNameEdList == null) {
return null;
}
return (ListModelElement) this.selectNameEdList.getSelectedValue();
}
@Override
public JControlUpdatePane getControlUpdatePane() {
return (JControlUpdatePane) controlUpdatePane;
}
@Override
public JNameEdList getNameableList() {
return this.selectNameEdList;
}
private void popupEditDialog() {
getHelper().popupEditDialog(null, this.selectNameEdList, this);
}
protected String getWrapperLabelText() {
return StringUtils.EMPTY;
}
@Override
public void wrapperListener(Listener listener){
}
private class ListWrapperPane extends JPanel {
private UINameEdList nameEdList;
public ListWrapperPane(String labelText, UINameEdList nameEdList) {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
UILabel label = new UILabel(labelText + getWrapperLabelText()) {
@Override
public void paint(Graphics g) {
((Graphics2D) g).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.8f));
super.paint(g);
}
};
label.setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 0));
label.setOpaque(true);
label.setBackground(Color.WHITE);
label.setForeground(Color.decode("#333334"));
label.setFont(label.getFont().deriveFont(11F));
label.setPreferredSize(new Dimension(224, 26));
this.nameEdList = nameEdList;
this.add(label, BorderLayout.NORTH);
this.add(this.nameEdList, BorderLayout.CENTER);
}
public UINameEdList getNameEdList() {
return this.nameEdList;
}
}
}