Browse Source

Pull request #4278: REPORT-52151 控件事件支持重命名开发

Merge in DESIGN/design from ~KERRY/design_10.0:feature/10.0 to feature/10.0

* commit 'cc4b438cfb65a96a21964a8b0f16fdf887495548':
  REPORT-52151 控件事件支持重命名开发
feature/10.0
kerry 3 years ago
parent
commit
baf200f14e
  1. 38
      designer-base/src/main/java/com/fr/design/gui/controlpane/CommonShortCutHandlers.java
  2. 144
      designer-base/src/main/java/com/fr/design/gui/controlpane/ListControlPaneHelper.java
  3. 12
      designer-base/src/main/java/com/fr/design/gui/controlpane/UIControlPane.java
  4. 130
      designer-base/src/main/java/com/fr/design/gui/controlpane/UIListControlPane.java
  5. 24
      designer-base/src/main/java/com/fr/design/gui/controlpane/UINameableListCellRenderer.java
  6. 6
      designer-base/src/main/java/com/fr/design/os/impl/PopupDialogSaveAction.java
  7. 14
      designer-base/src/main/java/com/fr/design/widget/EventCreator.java
  8. 41
      designer-base/src/test/java/com/fr/design/gui/controlpane/ListControlPaneHelperTest.java
  9. 533
      designer-form/src/main/java/com/fr/design/gui/controlpane/EventPropertyPane.java
  10. 11
      designer-form/src/main/java/com/fr/design/mainframe/WidgetPropertyPane.java

38
designer-base/src/main/java/com/fr/design/gui/controlpane/CommonShortCutHandlers.java

@ -21,11 +21,9 @@ import java.util.Comparator;
*/
public class CommonShortCutHandlers {
ListControlPaneProvider listControlPane;
JNameEdList nameableList;
private CommonShortCutHandlers(ListControlPaneProvider listControlPane) {
this.listControlPane = listControlPane;
this.nameableList = listControlPane.getNameableList();
}
public static CommonShortCutHandlers newInstance(ListControlPaneProvider listControlPane) {
@ -43,19 +41,19 @@ public class CommonShortCutHandlers {
public void onRemoveItem() {
try {
nameableList.getCellEditor()
listControlPane.getNameableList().getCellEditor()
.stopCellEditing();
} catch (Exception ignored) {
}
if (GUICoreUtils.removeJListSelectedNodes(SwingUtilities
.getWindowAncestor((Component) listControlPane), nameableList)) {
.getWindowAncestor((Component) listControlPane), listControlPane.getNameableList())) {
listControlPane.checkButtonEnabled();
}
}
public void onCopyItem() {
// p:选中的值.
ListModelElement selectedValue = (ListModelElement) nameableList.getSelectedValue();
ListModelElement selectedValue = (ListModelElement) listControlPane.getNameableList().getSelectedValue();
if (selectedValue == null) {
return;
}
@ -76,47 +74,51 @@ public class CommonShortCutHandlers {
}
public void onMoveUpItem() {
int selectedIndex = nameableList.getSelectedIndex();
int selectedIndex = listControlPane.getNameableList().getSelectedIndex();
if (selectedIndex == -1) {
return;
}
// 上移
if (selectedIndex > 0) {
DefaultListModel listModel = (DefaultListModel) nameableList.getModel();
DefaultListModel listModel = (DefaultListModel) listControlPane.getNameableList().getModel();
Object selecteObj1 = listModel.get(selectedIndex - 1);
listModel.set(selectedIndex - 1, listModel.get(selectedIndex));
listModel.set(selectedIndex, selecteObj1);
nameableList.setSelectedIndex(selectedIndex - 1);
nameableList.ensureIndexIsVisible(selectedIndex - 1);
listControlPane.getNameableList().setSelectedIndex(selectedIndex - 1);
listControlPane.getNameableList().ensureIndexIsVisible(selectedIndex - 1);
}
}
public void onMoveDownItem() {
int selectedIndex = nameableList.getSelectedIndex();
int selectedIndex = listControlPane.getNameableList().getSelectedIndex();
if (selectedIndex == -1) {
return;
}
if (selectedIndex < nameableList.getModel().getSize() - 1) {
DefaultListModel listModel = (DefaultListModel) nameableList
if (selectedIndex < listControlPane.getNameableList().getModel().getSize() - 1) {
DefaultListModel listModel = (DefaultListModel) listControlPane.getNameableList()
.getModel();
Object selecteObj1 = listModel.get(selectedIndex + 1);
listModel.set(selectedIndex + 1, listModel.get(selectedIndex));
listModel.set(selectedIndex, selecteObj1);
nameableList.setSelectedIndex(selectedIndex + 1);
nameableList.ensureIndexIsVisible(selectedIndex + 1);
listControlPane.getNameableList().setSelectedIndex(selectedIndex + 1);
listControlPane.getNameableList().ensureIndexIsVisible(selectedIndex + 1);
}
}
public void onSortItem(boolean isAtoZ) {
onSortItem(isAtoZ, listControlPane.getNameableList());
}
public void onSortItem(boolean isAtoZ, JNameEdList nameEdList) {
// p:选中的值.
Object selectedValue = nameableList.getSelectedValue();
Object selectedValue = nameEdList.getSelectedValue();
DefaultListModel listModel = (DefaultListModel) nameableList
DefaultListModel listModel = (DefaultListModel) nameEdList
.getModel();
Nameable[] nameableArray = new Nameable[listModel.getSize()];
if (nameableArray.length <= 0) {
@ -156,12 +158,12 @@ public class CommonShortCutHandlers {
// p:需要选中以前的那个值.
if (selectedValue != null) {
nameableList.setSelectedValue(selectedValue, true);
nameEdList.setSelectedValue(selectedValue, true);
}
listControlPane.checkButtonEnabled();
// p:需要repaint.
nameableList.repaint();
nameEdList.repaint();
}
private String createUnrepeatedCopyName(String suffix) {

144
designer-base/src/main/java/com/fr/design/gui/controlpane/ListControlPaneHelper.java

@ -4,18 +4,41 @@ import com.fr.design.beans.BasicBeanPane;
import com.fr.design.dialog.FineJOptionPane;
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.form.event.Listener;
import com.fr.general.NameObject;
import com.fr.stable.Nameable;
import com.fr.stable.StringUtils;
import com.fr.stable.os.support.OSSupportCenter;
import javax.swing.DefaultListModel;
import javax.swing.JOptionPane;
import javax.swing.JList;
import javax.swing.JPopupMenu;
import javax.swing.SwingUtilities;
import java.awt.Component;
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.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 存放一些公用的方法
* Created by plough on 2018/8/13.
*/
class ListControlPaneHelper {
private static final int EDIT_RANGE = 25; // 编辑按钮的x坐标范围
private ListControlPaneProvider listControlPane;
private ListControlPaneHelper(ListControlPaneProvider listControlPane) {
@ -110,4 +133,123 @@ class ListControlPaneHelper {
}
protected void popupEditDialog(Point mousePos, UINameEdList nameableList, UIControlPane controlPane) {
int editingIndex = nameableList.getSelectedIndex();
Rectangle currentCellBounds = nameableList.getCellBounds(editingIndex, editingIndex);
if (editingIndex < 0 || (mousePos != null && !currentCellBounds.contains(mousePos))) {
return;
}
Window popupEditDialog = controlPane.getPopupEditDialog();
popupEditDialog.setLocation(getPopupDialogLocation(nameableList, popupEditDialog));
if (popupEditDialog instanceof UIControlPane.PopupEditDialog) {
((UIControlPane.PopupEditDialog) popupEditDialog).setTitle(getSelectedName());
}
popupEditDialog.setVisible(true);
PopupDialogSaveAction osBasedAction = OSSupportCenter.getAction(PopupDialogSaveAction.class);
osBasedAction.register(controlPane, popupEditDialog);
}
private Point getPopupDialogLocation(UINameEdList nameableList, Window popupEditDialog) {
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;
}
/*
* UINameEdList的鼠标事件
*/
protected MouseListener getListMouseListener(UINameEdList nameableList, UIControlPane controlPane) {
return new MouseAdapter() {
@Override
public void mouseReleased(MouseEvent evt) {
nameableList.stopEditing();
if (evt.getClickCount() >= 2
&& SwingUtilities.isLeftMouseButton(evt) && evt.getX() > EDIT_RANGE) {
nameableList.editItemAt(nameableList.getSelectedIndex());
} else if (SwingUtilities.isLeftMouseButton(evt) && evt.getX() <= EDIT_RANGE) {
popupEditDialog(evt.getPoint(), nameableList, controlPane);
}
// peter:处理右键的弹出菜单
if (!SwingUtilities.isRightMouseButton(evt)) {
return;
}
// peter: 注意,在checkButtonEnabled()方法里面,设置了所有的Action的Enabled.
checkButtonEnabled();
// p:右键菜单.
JPopupMenu popupMenu = new JPopupMenu();
for (ShortCut4JControlPane sj : listControlPane.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) {
}
};
}
public Map<String, List<NameObject>> processCatalog(List<NameObject> nameObjectList) {
Map<String, List<NameObject>> map = new HashMap<>();
for (NameObject nameObject : nameObjectList) {
Listener listener = (Listener) nameObject.getObject();
if (StringUtils.isNotEmpty(listener.getName())) {
nameObject.setName(listener.getName());
}
List<NameObject> list = map.computeIfAbsent(listener.getEventName(), k -> new ArrayList<>());
list.add(nameObject);
}
return map;
}
}

12
designer-base/src/main/java/com/fr/design/gui/controlpane/UIControlPane.java

@ -49,7 +49,7 @@ import java.awt.event.WindowEvent;
/**
* Created by plough on 2017/7/21.
*/
abstract class UIControlPane extends JControlPane {
public abstract class UIControlPane extends JControlPane {
private UIToolbar topToolBar;
protected Window popupEditDialog;
private static final int TOP_TOOLBAR_HEIGHT = 20;
@ -78,7 +78,7 @@ abstract class UIControlPane extends JControlPane {
initCardPane();
if (isNewStyle()) {
getPopupEditDialog(cardPane);
createPopupEditDialog(cardPane);
this.add(getLeftPane(), BorderLayout.CENTER);
this.setBorder(BorderFactory.createEmptyBorder(10, 10, 15, 10));
} else {
@ -100,7 +100,11 @@ abstract class UIControlPane extends JControlPane {
this.checkButtonEnabled();
}
private void getPopupEditDialog(JPanel cardPane) {
protected Window getPopupEditDialog(){
return this.popupEditDialog;
}
private void createPopupEditDialog(JPanel cardPane) {
popupEditDialog = new PopupEditDialog(cardPane);
}
@ -400,4 +404,4 @@ abstract class UIControlPane extends JControlPane {
return new Dimension(super.getPreferredSize().width, 28);
}
}
}
}

130
designer-base/src/main/java/com/fr/design/gui/controlpane/UIListControlPane.java

@ -6,32 +6,18 @@ 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;
@ -41,11 +27,8 @@ import java.lang.reflect.InvocationTargetException;
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;
@ -93,7 +76,7 @@ public abstract class UIListControlPane extends UIControlPane implements ListCon
nameableList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
nameableList.addMouseListener(getListMouseListener());
nameableList.addMouseListener(getHelper().getListMouseListener(nameableList, this));
nameableList.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent evt) {
// richie:避免多次update和populate大大降低效率
@ -139,7 +122,7 @@ public abstract class UIListControlPane extends UIControlPane implements ListCon
saveSettings();
}
};
nameEdList.setCellRenderer(new UINameableListCellRenderer(this));
nameEdList.setCellRenderer(new UINameableListCellRenderer(this.isNewStyle(), this.creators));
return nameEdList;
}
@ -181,13 +164,6 @@ public abstract class UIListControlPane extends UIControlPane implements ListCon
}
/**
* 获取选中的名字
*/
public String getSelectedName() {
return getHelper().getSelectedName();
}
/**
* 添加 Nameable
*
@ -209,51 +185,10 @@ public abstract class UIListControlPane extends UIControlPane implements ListCon
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);
getHelper().popupEditDialog(mousePos, nameableList, this);
}
}
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;
}
/**
* 生成不重复的名字
@ -301,65 +236,6 @@ public abstract class UIListControlPane extends UIControlPane implements ListCon
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.

24
designer-base/src/main/java/com/fr/design/gui/controlpane/UINameableListCellRenderer.java

@ -1,12 +1,8 @@
package com.fr.design.gui.controlpane;
import com.fr.base.BaseUtils;
import com.fr.design.constants.UIConstants;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.ilist.ListModelElement;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.stable.Nameable;
import sun.swing.DefaultLookup;
@ -14,8 +10,6 @@ import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
* Nameable的ListCellRenerer
@ -32,12 +26,14 @@ public class UINameableListCellRenderer extends
private static final int BUTTON_WIDTH = 25;
private UILabel editButton; // "编辑按钮",实际上是一个 UILabel,由列表项(UIListControlPane)统一处理点击事件
private UILabel label;
private UIListControlPane listControlPane;
private boolean isNewStyle;
private NameableCreator[] creators;
private Color initialLabelForeground;
public UINameableListCellRenderer(UIListControlPane listControlPane) {
public UINameableListCellRenderer( boolean isNewStyle, NameableCreator[] creators) {
super();
this.listControlPane = listControlPane;
this.isNewStyle = isNewStyle;
this.creators = creators;
initComponents();
setOpaque(true);
setBorder(getNoFocusBorder());
@ -50,7 +46,7 @@ public class UINameableListCellRenderer extends
return new Dimension(BUTTON_WIDTH, BUTTON_WIDTH);
}
};
editButton.setIcon(listControlPane.isNewStyle() ? UIConstants.LIST_EDIT_ICON : UIConstants.CPT_ICON);
editButton.setIcon(isNewStyle ? UIConstants.LIST_EDIT_ICON : UIConstants.CPT_ICON);
editButton.setBorder(BorderFactory.createMatteBorder(0, 0, 0, 1, UIConstants.LIST_ITEM_SPLIT_LINE));
editButton.setHorizontalAlignment(SwingConstants.CENTER);
label = new UILabel();
@ -92,7 +88,7 @@ public class UINameableListCellRenderer extends
setBackground(bg == null ? list.getSelectionBackground() : bg);
setForeground(fg == null ? list.getSelectionForeground() : fg);
label.setForeground(Color.WHITE);
if (listControlPane.isNewStyle()) {
if (isNewStyle) {
editButton.setIcon(UIConstants.LIST_EDIT_WHITE_ICON);
}
}
@ -100,7 +96,7 @@ public class UINameableListCellRenderer extends
setBackground(list.getBackground());
setForeground(list.getForeground());
label.setForeground(initialLabelForeground);
if (listControlPane.isNewStyle()) {
if (isNewStyle) {
editButton.setIcon(UIConstants.LIST_EDIT_ICON);
}
}
@ -114,7 +110,7 @@ public class UINameableListCellRenderer extends
Nameable wrappee = ((ListModelElement) value).wrapper;
this.setText(((ListModelElement) value).wrapper.getName());
for (NameableCreator creator : listControlPane.creators()) {
for (NameableCreator creator : creators) {
if (creator.menuIcon() != null && creator.acceptObject2Populate(wrappee) != null) {
this.setToolTipText(creator.createTooltip());
break;
@ -124,4 +120,4 @@ public class UINameableListCellRenderer extends
return this;
}
}
}

6
designer-base/src/main/java/com/fr/design/os/impl/PopupDialogSaveAction.java

@ -1,6 +1,6 @@
package com.fr.design.os.impl;
import com.fr.design.gui.controlpane.UIListControlPane;
import com.fr.design.gui.controlpane.UIControlPane;
import com.fr.stable.os.OperatingSystem;
import com.fr.stable.os.support.OSBasedAction;
@ -15,7 +15,7 @@ import java.awt.*;
*/
public class PopupDialogSaveAction implements OSBasedAction {
private UIListControlPane currentControlPane;
private UIControlPane currentControlPane;
private Window popupDialog;
@Override
@ -26,7 +26,7 @@ public class PopupDialogSaveAction implements OSBasedAction {
}
}
public void register(UIListControlPane currentControlPane, Window popupDialog) {
public void register(UIControlPane currentControlPane, Window popupDialog) {
this.currentControlPane = currentControlPane;
this.popupDialog = popupDialog;
}

14
designer-base/src/main/java/com/fr/design/widget/EventCreator.java

@ -18,6 +18,10 @@ public class EventCreator extends NameableSelfCreator {
this.eventName = eventName;
}
public String getEventName() {
return eventName;
}
@Override
public Nameable createNameable(UnrepeatedNameHelper helper) {
return new NameObject(helper.createUnrepeatedName(this.menuName()),new Listener(this.eventName)) ;
@ -47,13 +51,17 @@ public class EventCreator extends NameableSelfCreator {
return eventName;
}
}
@Override
public void saveUpdatedBean(ListModelElement wrapper, Object bean) {
((NameObject)wrapper.wrapper).setObject(bean);
public void saveUpdatedBean(ListModelElement element, Object bean) {
if (bean instanceof Listener){
((Listener)bean).setName(element.wrapper.getName());
}
((NameObject)element.wrapper).setObject(bean);
}
@Override
public String createTooltip() {
return null;
}
}
}

41
designer-base/src/test/java/com/fr/design/gui/controlpane/ListControlPaneHelperTest.java

@ -0,0 +1,41 @@
package com.fr.design.gui.controlpane;
import com.fr.form.event.Listener;
import com.fr.general.NameObject;
import org.easymock.EasyMock;
import org.junit.Assert;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* Created by kerry on 5/17/21
*/
public class ListControlPaneHelperTest {
@Test
public void testProcessCatalog() {
ListControlPaneHelper helper = ListControlPaneHelper.newInstance(EasyMock.mock(ListControlPaneProvider.class));
List<NameObject> nameObjectList = new ArrayList<>();
Listener listener1 = new Listener();
listener1.setEventName("click");
Listener listener2 = new Listener();
listener2.setEventName("afterInit");
Listener listener3 = new Listener();
listener3.setEventName("click");
Listener listener4 = new Listener();
listener4.setEventName("afterInit");
listener4.setName("test");
nameObjectList.add(new NameObject("click", listener1));
nameObjectList.add(new NameObject("afterInit", listener2));
nameObjectList.add(new NameObject("click", listener3));
nameObjectList.add(new NameObject("afterInit", listener4));
Map<String, List<NameObject>> map = helper.processCatalog(nameObjectList);
Assert.assertEquals(2, map.size());
Assert.assertEquals(2, map.get("afterInit").size());
Assert.assertEquals(2, map.get("click").size());
}
}

533
designer-form/src/main/java/com/fr/design/gui/controlpane/EventPropertyPane.java

@ -0,0 +1,533 @@
package com.fr.design.gui.controlpane;
import com.fr.design.beans.BasicBeanPane;
import com.fr.design.constants.UIConstants;
import com.fr.design.designer.creator.XCreator;
import com.fr.design.designer.properties.EventPropertyTable;
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.UINameEdList;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.FormDesigner;
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 javax.swing.BorderFactory;
import javax.swing.DefaultListModel;
import javax.swing.JPanel;
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.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
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/17/21
*/
public class EventPropertyPane extends UIControlPane implements ListControlPaneProvider {
private XCreator creator;
private boolean isPopulating = false;
private UINameEdList selectNameEdList;
private Map<String, EventListWrapperPane> nameEdListMap = new HashMap<>();
private CommonShortCutHandlers commonHandlers;
private ListControlPaneHelper helper;
private JPanel contentPane;
private FormDesigner designer;
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 EventPropertyPane(FormDesigner designer) {
super();
this.designer = designer;
}
@Override
protected void initLeftPane(JPanel leftPane) {
leftPane.add(new UIScrollPane(contentPane = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, FlowLayout.LEADING, 0, 0)), BorderLayout.CENTER);
}
/**
* 刷新
*/
public void refresh() {
int selectionSize = designer.getSelectionModel().getSelection().size();
if (selectionSize == 0 || selectionSize == 1) {
this.creator = selectionSize == 0 ? designer.getRootComponent() : designer.getSelectionModel()
.getSelection().getSelectedCreator();
} else {
this.creator = null;
contentPane.removeAll();
checkButtonEnabled();
return;
}
Widget widget = creator.toData();
refreshContentPane(widget.supportedEvents());
refreshNameableCreator(EventCreator.createEventCreator(widget.supportedEvents(), EventPropertyTable.WidgetEventListenerUpdatePane.class));
populateNameObjects();
}
private void refreshContentPane(String[] supportedEvents) {
for (String event : supportedEvents) {
if (nameEdListMap.containsKey(event)) {
continue;
}
UINameEdList list = createJNameList(event);
EventListWrapperPane wrapperPane = new EventListWrapperPane(switchLang(event), list);
if (this.selectNameEdList == null) {
this.selectNameEdList = wrapperPane.getNameEdList();
}
contentPane.add(wrapperPane);
nameEdListMap.put(event, wrapperPane);
}
}
public void populateNameObjects() {
Widget widget = creator.toData();
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();
}
public 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();
EventListWrapperPane eventListWrapperPane = nameEdListMap.get(entry.getKey());
populateChildNameList(eventListWrapperPane.getNameEdList(), valueList.toArray(new NameObject[valueList.size()]));
}
this.checkButtonEnabled();
refreshEventListWrapperPane();
isPopulating = false;
}
private void refreshEventListWrapperPane() {
Iterator<Map.Entry<String, EventListWrapperPane>> iterator = nameEdListMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, EventListWrapperPane> entry = iterator.next();
EventListWrapperPane 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);
}
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]));
}
}
protected 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(getHelper().getListMouseListener(nameEdList, this));
nameEdList.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
selectNameEdList = nameEdList;
updateUINameListSelect();
}
});
nameEdList.addModNameActionListener(new ModNameActionListener() {
@Override
public void nameModed(int index, String oldName, String newName) {
saveSettings();
}
});
nameEdList.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent evt) {
// richie:避免多次update和populate大大降低效率
if (!evt.getValueIsAdjusting() && !isPopulating) {
// shoc 切换的时候加检验
if (hasInvalid(false)) {
return;
}
((JControlUpdatePane) EventPropertyPane.this.controlUpdatePane).update();
((JControlUpdatePane) EventPropertyPane.this.controlUpdatePane).populate();
EventPropertyPane.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, EventListWrapperPane>> iterator = nameEdListMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, EventListWrapperPane> 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 creator 控件
*/
public void updateWidgetListener(XCreator creator) {
(creator.toData()).clearListeners();
Nameable[] res = this.update();
for (int i = 0; i < res.length; i++) {
NameObject nameObject = (NameObject) res[i];
(creator.toData()).addListener((Listener) nameObject.getObject());
}
designer.fireTargetModified();
checkButtonEnabled();
}
/**
* 生成不重复的名字
*
* @param prefix 名字前缀
* @return 名字
*/
@Override
public String createUnrepeatedName(String prefix) {
return getCommonHandlers().createUnrepeatedName(prefix);
}
private void updateSelectedNameList(NameableCreator creator) {
String eventName = ((EventCreator) creator).getEventName();
EventListWrapperPane 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);
}
@Override
public void onRemoveItem() {
getCommonHandlers().onRemoveItem();
refreshEventListWrapperPane();
}
@Override
public void onCopyItem() {
getCommonHandlers().onCopyItem();
}
@Override
public void onMoveUpItem() {
getCommonHandlers().onMoveUpItem();
}
@Override
public void onMoveDownItem() {
getCommonHandlers().onMoveDownItem();
}
@Override
public void onSortItem(boolean isAtoZ) {
Iterator<Map.Entry<String, EventListWrapperPane>> iterator = nameEdListMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, EventListWrapperPane> 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() {
java.util.List<Nameable> res = new java.util.ArrayList<Nameable>();
getControlUpdatePane().update();
Iterator<Map.Entry<String, EventListWrapperPane>> iterator = nameEdListMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, EventListWrapperPane> 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 NameableCreator[] createNameableCreators() {
return new NameableCreator[]{
new EventCreator(Widget.EVENT_STATECHANGE, EventPropertyTable.WidgetEventListenerUpdatePane.class)
};
}
@Override
public void saveSettings() {
if (isPopulating) {
return;
}
updateWidgetListener(creator);
}
@Override
protected String title4PopupWindow() {
return "Event";
}
@Override
public String getAddItemText() {
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Add_Event");
}
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);
}
private class EventListWrapperPane extends JPanel {
private UINameEdList nameEdList;
public EventListWrapperPane(String labelText, UINameEdList nameEdList) {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
UILabel label = new UILabel(labelText + Toolkit.i18nText("Fine-Design_Report_Event"));
label.setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 0));
label.setBackground(Color.decode("#FFFFFF"));
label.setPreferredSize(new Dimension(226, 26));
this.nameEdList = nameEdList;
this.add(label, BorderLayout.NORTH);
this.add(this.nameEdList, BorderLayout.CENTER);
}
public UINameEdList getNameEdList() {
return this.nameEdList;
}
}
}

11
designer-form/src/main/java/com/fr/design/mainframe/WidgetPropertyPane.java

@ -6,13 +6,12 @@ import com.fr.design.constants.UIConstants;
import com.fr.design.designer.beans.events.DesignerEditListener;
import com.fr.design.designer.beans.events.DesignerEvent;
import com.fr.design.designer.creator.*;
import com.fr.design.designer.creator.cardlayout.XWCardMainBorderLayout;
import com.fr.design.designer.creator.cardlayout.XWCardTagLayout;
import com.fr.design.designer.properties.EventPropertyTable;
import com.fr.design.designer.properties.mobile.MobileBookMarkPropertyUI;
import com.fr.design.designer.properties.mobile.MobileStylePropertyUI;
import com.fr.design.form.util.FormDesignerUtils;
import com.fr.design.fun.WidgetPropertyUIProvider;
import com.fr.design.gui.controlpane.EventPropertyPane;
import com.fr.design.gui.ibutton.UIHeadGroup;
import com.fr.design.gui.icontainer.UIScrollPane;
import com.fr.design.gui.ilable.UILabel;
@ -38,7 +37,7 @@ public class WidgetPropertyPane extends FormDockView implements BaseWidgetProper
private static final int PADDING = 10;
private static final int PADDING_M = 12;
private FormWidgetCardPane formWidgetCardPane; // 控件的属性表
private EventPropertyTable eventTable; // 控件的事件表
private EventPropertyPane eventTable; // 控件的事件表
private List<AbstractPropertyTable> widgetPropertyTables; // 这个变量应该是保存控件拓展的属性tab
private List<MobileWidgetDefinePane> mobileExtraPropertyPanes; // 保存9.0设计器下移动端拓展的属性tab,舍弃JTable
private FormDesigner designer; // 当前designer
@ -141,7 +140,7 @@ public class WidgetPropertyPane extends FormDockView implements BaseWidgetProper
* 创建事件表事件选项卡不是JTable
*/
private void createEventTable() {
eventTable = new EventPropertyTable(designer);
eventTable = new EventPropertyPane(designer);
designer.addDesignerEditListener(new EventPropertyDesignerAdapter(eventTable));
}
@ -337,9 +336,9 @@ public class WidgetPropertyPane extends FormDockView implements BaseWidgetProper
* 事件表监听界面事件编辑选中
*/
private class EventPropertyDesignerAdapter implements DesignerEditListener {
EventPropertyTable propertyTable;
EventPropertyPane propertyTable;
EventPropertyDesignerAdapter(EventPropertyTable eventTable) {
EventPropertyDesignerAdapter(EventPropertyPane eventTable) {
this.propertyTable = eventTable;
}

Loading…
Cancel
Save