帆软报表设计器源代码。
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.
 
 
 
 

441 lines
14 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.ilist.JNameEdList;
import com.fr.design.gui.ilist.ListModelElement;
import com.fr.design.gui.ilist.UINameEdList;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.os.impl.PopupDialogSaveAction;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.stable.ArrayUtils;
import com.fr.stable.Nameable;
import com.fr.stable.os.support.OSSupportCenter;
import javax.swing.DefaultListModel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.BorderLayout;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.InputEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
/**
* Created by plough on 2017/7/19.
*/
public abstract class UIListControlPane extends UIControlPane implements ListControlPaneProvider {
private static final String LIST_NAME = "UIControl_List";
private static final int EDIT_RANGE = 25; // 编辑按钮的x坐标范围
protected UINameEdList nameableList;
private int editingIndex;
protected String selectedName;
protected boolean isPopulating = false;
private CommonShortCutHandlers commonHandlers;
private ListControlPaneHelper helper;
public UIListControlPane() {
super();
}
private ListControlPaneHelper getHelper() {
if (helper == null) {
helper = ListControlPaneHelper.newInstance(this);
}
return helper;
}
private CommonShortCutHandlers getCommonHandlers() {
if (commonHandlers == null) {
commonHandlers = CommonShortCutHandlers.newInstance(this);
}
return commonHandlers;
}
@Override
protected JPanel createControlUpdatePane() {
return JControlUpdatePane.newInstance(this);
}
/**
* 生成添加按钮的NameableCreator
*
* @return 按钮的NameableCreator
*/
@Override
public abstract NameableCreator[] createNameableCreators();
@Override
protected void initLeftPane(JPanel leftPane) {
nameableList = createJNameList();
nameableList.setName(LIST_NAME);
nameableList.setSelectionBackground(UIConstants.ATTRIBUTE_PRESS);
leftPane.add(new UIScrollPane(nameableList), BorderLayout.CENTER);
nameableList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
nameableList.addMouseListener(getListMouseListener());
nameableList.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent evt) {
// richie:避免多次update和populate大大降低效率
if (!evt.getValueIsAdjusting()) {
// shoc 切换的时候加检验
if (hasInvalid(false)) {
return;
}
((JControlUpdatePane) UIListControlPane.this.controlUpdatePane).update();
((JControlUpdatePane) UIListControlPane.this.controlUpdatePane).populate();
UIListControlPane.this.checkButtonEnabled();
}
}
});
if (isNewStyle()) {
nameableList.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();
}
});
}
}
private UINameEdList createJNameList() {
UINameEdList nameEdList = new UINameEdList(new DefaultListModel()) {
@Override
protected void doAfterLostFocus() {
UIListControlPane.this.updateControlUpdatePane();
}
@Override
protected void doAfterStopEditing() {
saveSettings();
}
};
nameEdList.setCellRenderer(new UINameableListCellRenderer(this));
return nameEdList;
}
private void updateControlUpdatePane() {
((JControlUpdatePane) controlUpdatePane).update();
}
protected void setNameListEditable(boolean editable) {
this.nameableList.setEditable(editable);
}
@Override
public Nameable[] update() {
return getHelper().update();
}
@Override
public void populate(Nameable[] nameableArray) {
isPopulating = true; // 加一个标识位,避免切换单元格时,触发 saveSettings
nameableList.getCellEditor().stopCellEditing();
DefaultListModel listModel = (DefaultListModel) this.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]));
}
if (listModel.size() > 0 || this.nameableList.getSelectedIndex() != 0) {
this.nameableList.setSelectedIndex(0);
}
this.checkButtonEnabled();
isPopulating = false;
}
/**
* 获取选中的名字
*/
public String getSelectedName() {
return getHelper().getSelectedName();
}
/**
* 添加 Nameable
*
* @param nameable 添加的Nameable
* @param index 序号
*/
public void addNameable(Nameable nameable, int index) {
getHelper().addNameable(nameable, index);
popupEditDialog();
}
public DefaultListModel getModel() {
return (DefaultListModel) UIListControlPane.this.nameableList.getModel();
}
private void popupEditDialog() {
popupEditDialog(null);
}
protected void popupEditDialog(Point mousePos) {
if (isNewStyle()) {
Rectangle currentCellBounds = nameableList.getCellBounds(editingIndex, editingIndex);
if (editingIndex < 0 || (mousePos != null && !currentCellBounds.contains(mousePos))) {
return;
}
popupEditDialog.setLocation(getPopupDialogLocation());
if (popupEditDialog instanceof PopupEditDialog) {
((PopupEditDialog)popupEditDialog).setTitle(getSelectedName());
}
popupEditDialog.setVisible(true);
PopupDialogSaveAction osBasedAction = OSSupportCenter.getAction(PopupDialogSaveAction.class);
osBasedAction.register(this, popupEditDialog);
}
}
private Point getPopupDialogLocation() {
Point resultPos = new Point(0, 0);
Point listPos = nameableList.getLocationOnScreen();
resultPos.x = listPos.x - popupEditDialog.getWidth();
resultPos.y = listPos.y + (nameableList.getSelectedIndex() - 1) * EDIT_RANGE;
// 当对象在屏幕上的位置比较靠下时,往下移动弹窗至与属性面板平齐
Window frame = DesignerContext.getDesignerFrame();
// 不能太低
int maxY = frame.getLocationOnScreen().y + frame.getHeight() - popupEditDialog.getHeight();
if (resultPos.y > maxY) {
resultPos.y = maxY;
}
// 也不能太高
int minY = frame.getLocationOnScreen().y + EDIT_RANGE;
if (resultPos.y < minY) {
resultPos.y = minY;
}
// 当在左侧显示不下时,在右侧弹出弹窗
if (resultPos.x < 0) {
resultPos.x = listPos.x + nameableList.getParent().getWidth();
}
// 如果右侧显示不下,可以向左移动
int maxX = frame.getLocationOnScreen().x + frame.getWidth() - popupEditDialog.getWidth() - EDIT_RANGE;
if (resultPos.x > maxX) {
resultPos.x = maxX;
}
return resultPos;
}
/**
* 生成不重复的名字
*
* @param prefix 名字前缀
* @return 名字
*/
@Override
public String createUnrepeatedName(String prefix) {
return getCommonHandlers().createUnrepeatedName(prefix);
}
@Override
public void onAddItem(NameableCreator creator) {
getCommonHandlers().onAddItem(creator);
}
@Override
public void onRemoveItem() {
getCommonHandlers().onRemoveItem();
}
@Override
public void onCopyItem() {
getCommonHandlers().onCopyItem();
}
@Override
public void onMoveUpItem() {
getCommonHandlers().onMoveUpItem();
}
@Override
public void onMoveDownItem() {
getCommonHandlers().onMoveDownItem();
}
@Override
public void onSortItem(boolean isAtoZ) {
getCommonHandlers().onSortItem(isAtoZ);
}
@Override
public boolean isItemSelected() {
return getModel().getSize() > 0 && nameableList.getSelectedIndex() != -1;
}
/*
* UINameEdList的鼠标事件
*/
private MouseListener getListMouseListener() {
return new MouseAdapter() {
@Override
public void mouseReleased(MouseEvent evt) {
nameableList.stopEditing();
if (evt.getClickCount() >= 2
&& SwingUtilities.isLeftMouseButton(evt) && evt.getX() > EDIT_RANGE) {
editingIndex = nameableList.getSelectedIndex();
selectedName = nameableList.getNameAt(editingIndex);
nameableList.editItemAt(nameableList.getSelectedIndex());
} else if (SwingUtilities.isLeftMouseButton(evt) && evt.getX() <= EDIT_RANGE) {
editingIndex = nameableList.getSelectedIndex();
selectedName = nameableList.getNameAt(editingIndex);
popupEditDialog(evt.getPoint());
}
// peter:处理右键的弹出菜单
if (!SwingUtilities.isRightMouseButton(evt)) {
return;
}
// peter: 注意,在checkButtonEnabled()方法里面,设置了所有的Action的Enabled.
checkButtonEnabled();
// p:右键菜单.
JPopupMenu popupMenu = new JPopupMenu();
for (ShortCut4JControlPane sj : getShorts()) {
sj.getShortCut().intoJPopupMenu(popupMenu);
}
// peter: 只有弹出菜单有子菜单的时候,才需要弹出来.
GUICoreUtils.showPopupMenu(popupMenu, nameableList, evt.getX() - 1,
evt.getY() - 1);
}
@Override
public void mouseClicked(MouseEvent e) {
JList list = (JList) e.getSource();
if (list.locationToIndex(e.getPoint()) == -1 && !e.isShiftDown()
&& !isMenuShortcutKeyDown(e)) {
list.clearSelection();
}
}
private boolean isMenuShortcutKeyDown(InputEvent event) {
return (event.getModifiers() & Toolkit.getDefaultToolkit()
.getMenuShortcutKeyMask()) != 0;
}
@Override
public void mouseMoved(MouseEvent e) {
}
};
}
/**
* 检查按钮可用状态 Check button enabled.
*/
@Override
public void checkButtonEnabled() {
getHelper().checkButtonEnabled();
}
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);
}
}
/**
* 检查是否符合规范
*
* @throws Exception
*/
@Override
public void checkValid() throws Exception {
((JControlUpdatePane) this.controlUpdatePane).checkValid();
}
@Override
public boolean hasInvalid(boolean isAdd) {
return getHelper().hasInvalid(isAdd);
}
/**
* 设置选中项
*
* @param index 选中项的序列号
*/
public void setSelectedIndex(int index) {
nameableList.setSelectedIndex(index);
}
@Override
public int getSelectedIndex() {
return nameableList.getSelectedIndex();
}
@Override
public ListModelElement getSelectedValue() {
return (ListModelElement) this.nameableList.getSelectedValue();
}
@Override
public JControlUpdatePane getControlUpdatePane() {
return (JControlUpdatePane) controlUpdatePane;
}
@Override
public JNameEdList getNameableList() {
return nameableList;
}
}