diff --git a/designer-base/src/main/java/com/fr/design/gui/controlpane/CommonShortCutHandlers.java b/designer-base/src/main/java/com/fr/design/gui/controlpane/CommonShortCutHandlers.java index c5d2a51dd..094ef1c22 100644 --- a/designer-base/src/main/java/com/fr/design/gui/controlpane/CommonShortCutHandlers.java +++ b/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) { diff --git a/designer-base/src/main/java/com/fr/design/gui/controlpane/ListControlPaneHelper.java b/designer-base/src/main/java/com/fr/design/gui/controlpane/ListControlPaneHelper.java index 76255d96b..7fe1a27ef 100644 --- a/designer-base/src/main/java/com/fr/design/gui/controlpane/ListControlPaneHelper.java +++ b/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> processCatalog(List nameObjectList) { + Map> map = new HashMap<>(); + for (NameObject nameObject : nameObjectList) { + Listener listener = (Listener) nameObject.getObject(); + if (StringUtils.isNotEmpty(listener.getName())) { + nameObject.setName(listener.getName()); + } + List list = map.computeIfAbsent(listener.getEventName(), k -> new ArrayList<>()); + list.add(nameObject); + } + return map; + } + + + } diff --git a/designer-base/src/main/java/com/fr/design/gui/controlpane/UIControlPane.java b/designer-base/src/main/java/com/fr/design/gui/controlpane/UIControlPane.java index 04427b337..b15b9eab9 100644 --- a/designer-base/src/main/java/com/fr/design/gui/controlpane/UIControlPane.java +++ b/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); } } -} \ No newline at end of file +} diff --git a/designer-base/src/main/java/com/fr/design/gui/controlpane/UIListControlPane.java b/designer-base/src/main/java/com/fr/design/gui/controlpane/UIListControlPane.java index ec76f5bf7..b7b8674be 100644 --- a/designer-base/src/main/java/com/fr/design/gui/controlpane/UIListControlPane.java +++ b/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. diff --git a/designer-base/src/main/java/com/fr/design/gui/controlpane/UINameableListCellRenderer.java b/designer-base/src/main/java/com/fr/design/gui/controlpane/UINameableListCellRenderer.java index b66ee1ef2..40d8d98fa 100644 --- a/designer-base/src/main/java/com/fr/design/gui/controlpane/UINameableListCellRenderer.java +++ b/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; } -} \ No newline at end of file +} diff --git a/designer-base/src/main/java/com/fr/design/os/impl/PopupDialogSaveAction.java b/designer-base/src/main/java/com/fr/design/os/impl/PopupDialogSaveAction.java index 019ee3d97..c0b060005 100644 --- a/designer-base/src/main/java/com/fr/design/os/impl/PopupDialogSaveAction.java +++ b/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; } diff --git a/designer-base/src/main/java/com/fr/design/widget/EventCreator.java b/designer-base/src/main/java/com/fr/design/widget/EventCreator.java index 4fdfd7ed8..63d40515c 100644 --- a/designer-base/src/main/java/com/fr/design/widget/EventCreator.java +++ b/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; } -} \ No newline at end of file +} diff --git a/designer-base/src/test/java/com/fr/design/gui/controlpane/ListControlPaneHelperTest.java b/designer-base/src/test/java/com/fr/design/gui/controlpane/ListControlPaneHelperTest.java new file mode 100644 index 000000000..8f113089e --- /dev/null +++ b/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 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> map = helper.processCatalog(nameObjectList); + Assert.assertEquals(2, map.size()); + Assert.assertEquals(2, map.get("afterInit").size()); + Assert.assertEquals(2, map.get("click").size()); + + } +} diff --git a/designer-form/src/main/java/com/fr/design/gui/controlpane/EventPropertyPane.java b/designer-form/src/main/java/com/fr/design/gui/controlpane/EventPropertyPane.java new file mode 100644 index 000000000..cc3f34669 --- /dev/null +++ b/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 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 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> map) { + isPopulating = true; // 加一个标识位,避免切换单元格时,触发 saveSettings + Iterator>> iterator = map.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry> entry = iterator.next(); + List 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> iterator = nameEdListMap.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry 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> iterator = nameEdListMap.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry 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> iterator = nameEdListMap.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry 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 res = new java.util.ArrayList(); + getControlUpdatePane().update(); + Iterator> iterator = nameEdListMap.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry 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; + } + + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/WidgetPropertyPane.java b/designer-form/src/main/java/com/fr/design/mainframe/WidgetPropertyPane.java index c37b4ba9a..fd64d3aab 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/WidgetPropertyPane.java +++ b/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 widgetPropertyTables; // 这个变量应该是保存控件拓展的属性tab private List 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; }