From 07c5057047bbbaf766d03aa2c3d2914557131eb7 Mon Sep 17 00:00:00 2001 From: plough Date: Fri, 21 Jul 2017 14:06:42 +0800 Subject: [PATCH 1/6] =?UTF-8?q?REPORT-3163=20=E5=90=88=E4=BD=9C=E5=BC=80?= =?UTF-8?q?=E5=8F=919.0=E8=AE=BE=E8=AE=A1=E5=99=A8=3D>=E5=B0=86=E8=B6=85?= =?UTF-8?q?=E7=BA=A7=E9=93=BE=E6=8E=A5=E9=9D=A2=E6=9D=BF=E6=94=B9=E4=B8=BA?= =?UTF-8?q?=E5=8D=95=E4=BE=8B=EF=BC=8C=E6=8F=92=E5=85=A5=E5=8F=B3=E4=BE=A7?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E9=9D=A2=E6=9D=BF=E6=A1=86=E6=9E=B6=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mainframe/ElementCasePaneDelegate.java | 3 + .../com/fr/design/mainframe/JWorkBook.java | 6 ++ .../mainframe/ReportHyperlinkGroupPane.java | 55 +++++++++++++++++++ .../design/gui/frpane/HyperlinkGroupPane.java | 3 +- .../mainframe/EastRegionContainerPane.java | 8 +++ .../com/fr/design/mainframe/JTemplate.java | 4 +- .../gui/xpane/FormHyperlinkGroupPane.java | 16 +++++- .../src/com/fr/design/mainframe/JForm.java | 2 +- 8 files changed, 89 insertions(+), 8 deletions(-) create mode 100644 designer/src/com/fr/design/mainframe/ReportHyperlinkGroupPane.java diff --git a/designer/src/com/fr/design/mainframe/ElementCasePaneDelegate.java b/designer/src/com/fr/design/mainframe/ElementCasePaneDelegate.java index 433628209..f515643be 100644 --- a/designer/src/com/fr/design/mainframe/ElementCasePaneDelegate.java +++ b/designer/src/com/fr/design/mainframe/ElementCasePaneDelegate.java @@ -58,6 +58,8 @@ public class ElementCasePaneDelegate extends ElementCasePane { QuickEditorRegion.getInstance().populate(getCurrentEditor()); JTemplate editingTemplate = HistoryTemplateListPane.getInstance().getCurrentEditingTemplate(); if (editingTemplate != null && !editingTemplate.isUpMode()) { + // 模板初始化完成后,才能初始化超级链接面板 + ReportHyperlinkGroupPane.getInstance().populate(ElementCasePaneDelegate.this); if (((ElementCasePaneDelegate)e.getSource()).getSelection() instanceof FloatSelection) { EastRegionContainerPane.getInstance().switchMode(EastRegionContainerPane.PropertyMode.REPORT_FLOAT); // EastRegionContainerPane.getInstance().replaceCellAttrPane(CellElementPropertyPane.getInstance()); @@ -66,6 +68,7 @@ public class ElementCasePaneDelegate extends ElementCasePane { EastRegionContainerPane.getInstance().switchMode(EastRegionContainerPane.PropertyMode.REPORT); EastRegionContainerPane.getInstance().replaceCellAttrPane(CellElementPropertyPane.getInstance()); EastRegionContainerPane.getInstance().replaceCellElementPane(QuickEditorRegion.getInstance()); + EastRegionContainerPane.getInstance().replaceHyperlinkPane(ReportHyperlinkGroupPane.getInstance()); } EastRegionContainerPane.getInstance().removeParameterPane(); } diff --git a/designer/src/com/fr/design/mainframe/JWorkBook.java b/designer/src/com/fr/design/mainframe/JWorkBook.java index 5978a506f..11ceb595d 100644 --- a/designer/src/com/fr/design/mainframe/JWorkBook.java +++ b/designer/src/com/fr/design/mainframe/JWorkBook.java @@ -23,6 +23,7 @@ import com.fr.design.event.TargetModifiedListener; import com.fr.design.file.HistoryTemplateListPane; import com.fr.design.file.MutilTempalteTabPane; import com.fr.design.fun.PreviewProvider; +import com.fr.design.gui.frpane.HyperlinkGroupPane; import com.fr.design.gui.ibutton.UIButton; import com.fr.design.gui.icontainer.UIModeControlContainer; import com.fr.design.gui.imenu.UIMenuItem; @@ -755,6 +756,11 @@ public class JWorkBook extends JTemplate { return true; } + @Override + public HyperlinkGroupPane getHyperLinkPane() { + return ReportHyperlinkGroupPane.getInstance(); + } + public void setAuthorityMode(boolean isUpMode) { centerPane.setAuthorityMode(isUpMode); } diff --git a/designer/src/com/fr/design/mainframe/ReportHyperlinkGroupPane.java b/designer/src/com/fr/design/mainframe/ReportHyperlinkGroupPane.java new file mode 100644 index 000000000..64c397da1 --- /dev/null +++ b/designer/src/com/fr/design/mainframe/ReportHyperlinkGroupPane.java @@ -0,0 +1,55 @@ +package com.fr.design.mainframe; + +import com.fr.design.gui.frpane.HyperlinkGroupPane; +import com.fr.grid.selection.CellSelection; +import com.fr.grid.selection.FloatSelection; +import com.fr.grid.selection.Selection; +import com.fr.js.NameJavaScriptGroup; +import com.fr.report.cell.CellElement; +import com.fr.report.cell.FloatElement; +import com.fr.report.elementcase.TemplateElementCase; + +/** + * Created by plough on 2017/7/21. + */ +public class ReportHyperlinkGroupPane extends HyperlinkGroupPane { + private static ReportHyperlinkGroupPane singleton; + + private ReportHyperlinkGroupPane() { + super(); + } + + public synchronized static ReportHyperlinkGroupPane getInstance() { + if (singleton == null) { + singleton = new ReportHyperlinkGroupPane(); + } + return singleton; + } + + public void populate(ElementCasePane reportPane) { +// TemplateElementCase elementCase = ePane.getEditingElementCase(); +// if (elementCase == null) { +// return; +// } +// ePane.getSelection().populatePropertyPane(ePane); + final TemplateElementCase report = reportPane.getEditingElementCase(); + NameJavaScriptGroup nameHyperlinks = getNameJSGroup(reportPane, report); + populate(nameHyperlinks); + } + + private NameJavaScriptGroup getNameJSGroup(ElementCasePane reportPane, final TemplateElementCase report) { + NameJavaScriptGroup nameHyperlinks = null; + final Selection sel = reportPane.getSelection(); + if (sel instanceof FloatSelection) { + FloatElement selectedFloatElement = report.getFloatElement(((FloatSelection)sel).getSelectedFloatName()); + nameHyperlinks = selectedFloatElement.getNameHyperlinkGroup(); + } else { + CellElement editCellElement = report.getCellElement(((CellSelection)sel).getColumn(), ((CellSelection)sel).getRow()); + if (editCellElement != null) { + nameHyperlinks = editCellElement.getNameHyperlinkGroup(); + } + } + + return nameHyperlinks; + } +} diff --git a/designer_base/src/com/fr/design/gui/frpane/HyperlinkGroupPane.java b/designer_base/src/com/fr/design/gui/frpane/HyperlinkGroupPane.java index 3408bf371..d0a824074 100644 --- a/designer_base/src/com/fr/design/gui/frpane/HyperlinkGroupPane.java +++ b/designer_base/src/com/fr/design/gui/frpane/HyperlinkGroupPane.java @@ -23,8 +23,7 @@ import java.util.Set; * @author kunsnat E-mail:kunsnat@gmail.com * @version 创建时间:2013-6-25 上午11:17:57 */ -public class HyperlinkGroupPane extends JListControlPane { - +public abstract class HyperlinkGroupPane extends JListControlPane { /** * 生成添加按钮的NameableCreator * diff --git a/designer_base/src/com/fr/design/mainframe/EastRegionContainerPane.java b/designer_base/src/com/fr/design/mainframe/EastRegionContainerPane.java index bdd03b3c5..5970c60ea 100644 --- a/designer_base/src/com/fr/design/mainframe/EastRegionContainerPane.java +++ b/designer_base/src/com/fr/design/mainframe/EastRegionContainerPane.java @@ -267,6 +267,14 @@ public class EastRegionContainerPane extends UIEastResizableContainer { return propertyItemMap.get(KEY_WIDGET_SETTINGS).getContentPane(); } + public void replaceHyperlinkPane(JComponent pane) { + propertyItemMap.get(KEY_HYPERLINK).replaceContentPane(pane); + } + + public JComponent getHyperlinkPane() { + return propertyItemMap.get(KEY_HYPERLINK).getContentPane(); + } + public void replaceWidgetLibPane(JComponent pane) { propertyItemMap.get(KEY_WIDGET_LIB).replaceContentPane(pane); } diff --git a/designer_base/src/com/fr/design/mainframe/JTemplate.java b/designer_base/src/com/fr/design/mainframe/JTemplate.java index a5023be82..72778113b 100644 --- a/designer_base/src/com/fr/design/mainframe/JTemplate.java +++ b/designer_base/src/com/fr/design/mainframe/JTemplate.java @@ -867,9 +867,7 @@ public abstract class JTemplate> ex * 返回当前支持的超链界面pane * @return 超链连接界面 */ - public HyperlinkGroupPane getHyperLinkPane() { - return new HyperlinkGroupPane(); - } + public abstract HyperlinkGroupPane getHyperLinkPane(); /** * 是否是图表 diff --git a/designer_form/src/com/fr/design/gui/xpane/FormHyperlinkGroupPane.java b/designer_form/src/com/fr/design/gui/xpane/FormHyperlinkGroupPane.java index 773446f5a..61b0c7aa9 100644 --- a/designer_form/src/com/fr/design/gui/xpane/FormHyperlinkGroupPane.java +++ b/designer_form/src/com/fr/design/gui/xpane/FormHyperlinkGroupPane.java @@ -8,8 +8,20 @@ import com.fr.general.ComparatorUtils; import com.fr.general.Inter; import com.fr.js.EmailJavaScript; -public class FormHyperlinkGroupPane extends HyperlinkGroupPane{ - +public class FormHyperlinkGroupPane extends HyperlinkGroupPane{ + private static FormHyperlinkGroupPane singleton; + + private FormHyperlinkGroupPane() { + super(); + } + + public synchronized static FormHyperlinkGroupPane getInstance() { + if (singleton == null) { + singleton = new FormHyperlinkGroupPane(); + } + return singleton; + } + /** * 生成添加按钮的NameableCreator * 由于表单报表块的单元格超链和单元格条件属性超链中的emailPane都要用表单的emailPane,这里调整下 diff --git a/designer_form/src/com/fr/design/mainframe/JForm.java b/designer_form/src/com/fr/design/mainframe/JForm.java index 234dad22f..7de4557cf 100644 --- a/designer_form/src/com/fr/design/mainframe/JForm.java +++ b/designer_form/src/com/fr/design/mainframe/JForm.java @@ -124,7 +124,7 @@ public class JForm extends JTemplate implements BaseJForm { * @return 超链连接界面 */ public HyperlinkGroupPane getHyperLinkPane() { - return new FormHyperlinkGroupPane(); + return FormHyperlinkGroupPane.getInstance(); } //表单返回 FORM_TAB or ELEMENTCASE_TAB From 92206ac3d8cf324de854aeff507c97b972e98a62 Mon Sep 17 00:00:00 2001 From: plough Date: Fri, 21 Jul 2017 14:13:44 +0800 Subject: [PATCH 2/6] =?UTF-8?q?REPORT-3163=20=E5=90=88=E4=BD=9C=E5=BC=80?= =?UTF-8?q?=E5=8F=919.0=E8=AE=BE=E8=AE=A1=E5=99=A8=3D>=E6=82=AC=E6=B5=AE?= =?UTF-8?q?=E5=85=83=E7=B4=A0=E8=B6=85=E7=BA=A7=E9=93=BE=E6=8E=A5tab?= =?UTF-8?q?=E6=94=B9=E4=B8=BA=E5=8F=AF=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/com/fr/design/mainframe/ElementCasePaneDelegate.java | 2 +- .../src/com/fr/design/mainframe/EastRegionContainerPane.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/designer/src/com/fr/design/mainframe/ElementCasePaneDelegate.java b/designer/src/com/fr/design/mainframe/ElementCasePaneDelegate.java index f515643be..5253999ac 100644 --- a/designer/src/com/fr/design/mainframe/ElementCasePaneDelegate.java +++ b/designer/src/com/fr/design/mainframe/ElementCasePaneDelegate.java @@ -68,8 +68,8 @@ public class ElementCasePaneDelegate extends ElementCasePane { EastRegionContainerPane.getInstance().switchMode(EastRegionContainerPane.PropertyMode.REPORT); EastRegionContainerPane.getInstance().replaceCellAttrPane(CellElementPropertyPane.getInstance()); EastRegionContainerPane.getInstance().replaceCellElementPane(QuickEditorRegion.getInstance()); - EastRegionContainerPane.getInstance().replaceHyperlinkPane(ReportHyperlinkGroupPane.getInstance()); } + EastRegionContainerPane.getInstance().replaceHyperlinkPane(ReportHyperlinkGroupPane.getInstance()); EastRegionContainerPane.getInstance().removeParameterPane(); } } diff --git a/designer_base/src/com/fr/design/mainframe/EastRegionContainerPane.java b/designer_base/src/com/fr/design/mainframe/EastRegionContainerPane.java index 5970c60ea..a0a3b8828 100644 --- a/designer_base/src/com/fr/design/mainframe/EastRegionContainerPane.java +++ b/designer_base/src/com/fr/design/mainframe/EastRegionContainerPane.java @@ -106,7 +106,7 @@ public class EastRegionContainerPane extends UIEastResizableContainer { // 超级链接 PropertyItem hyperlink = new PropertyItem(KEY_HYPERLINK, Inter.getLocText("FR-Designer_Hyperlink"), "/com/fr/design/images/buttonicon/add.png", new PropertyMode[]{PropertyMode.REPORT, PropertyMode.REPORT_PARA, PropertyMode.REPORT_FLOAT, PropertyMode.POLY, PropertyMode.POLY_CHART}, - new PropertyMode[]{PropertyMode.REPORT, PropertyMode.FORM_REPORT, PropertyMode.POLY_REPORT}); + new PropertyMode[]{PropertyMode.REPORT, PropertyMode.REPORT_FLOAT, PropertyMode.FORM_REPORT, PropertyMode.POLY_REPORT}); // 组件库 PropertyItem widgetLib = new PropertyItem(KEY_WIDGET_LIB, Inter.getLocText("FR-Designer_Widget_Library"), "/com/fr/design/images/buttonicon/add.png", new PropertyMode[]{PropertyMode.FORM}, From 4929f8efad92520801d79bc2583ef1dc1e1e9df2 Mon Sep 17 00:00:00 2001 From: plough Date: Fri, 21 Jul 2017 16:50:17 +0800 Subject: [PATCH 3/6] =?UTF-8?q?REPORT-3163=20=E5=90=88=E4=BD=9C=E5=BC=80?= =?UTF-8?q?=E5=8F=919.0=E8=AE=BE=E8=AE=A1=E5=99=A8=3D>=E6=96=B0=E5=88=97?= =?UTF-8?q?=E8=A1=A8=E9=9D=A2=E6=9D=BF=E9=9B=8F=E5=BD=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../design/gui/controlpane/UIControlPane.java | 232 +++++ .../gui/controlpane/UIListControlPane.java | 945 ++++++++++++++++++ .../UINameableListCellRenderer.java | 146 +++ .../design/gui/frpane/HyperlinkGroupPane.java | 3 +- 4 files changed, 1325 insertions(+), 1 deletion(-) create mode 100644 designer_base/src/com/fr/design/gui/controlpane/UIControlPane.java create mode 100644 designer_base/src/com/fr/design/gui/controlpane/UIListControlPane.java create mode 100644 designer_base/src/com/fr/design/gui/controlpane/UINameableListCellRenderer.java diff --git a/designer_base/src/com/fr/design/gui/controlpane/UIControlPane.java b/designer_base/src/com/fr/design/gui/controlpane/UIControlPane.java new file mode 100644 index 000000000..f67512d92 --- /dev/null +++ b/designer_base/src/com/fr/design/gui/controlpane/UIControlPane.java @@ -0,0 +1,232 @@ +package com.fr.design.gui.controlpane; + +import com.fr.design.dialog.BasicPane; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.gui.itoolbar.UIToolbar; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.layout.TableLayout; +import com.fr.design.layout.TableLayoutHelper; +import com.fr.design.menu.ShortCut; +import com.fr.design.menu.ToolBarDef; +import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.general.Inter; +import com.fr.stable.ArrayUtils; +import com.fr.stable.Nameable; + +import javax.swing.*; +import java.awt.*; + +/** + * Created by plough on 2017/7/21. + */ +public abstract class UIControlPane extends BasicPane implements UnrepeatedNameHelper { + protected static final int SHORT_WIDTH = 30; //每加一个short Divider位置加30 + protected JPanel controlUpdatePane; + + private ShortCut4JControlPane[] shorts; + private NameableCreator[] creators; + private ToolBarDef toolbarDef; + + private UIToolbar toolBar; + // peter:这是整体的一个cardLayout Pane + protected CardLayout cardLayout; + + protected JPanel cardPane; + + public UIControlPane() { + this.initComponentPane(); + } + + /** + * 生成添加按钮的NameableCreator + * + * @return 按钮的NameableCreator + */ + public abstract NameableCreator[] createNameableCreators(); + + public ShortCut4JControlPane[] getShorts() { + return shorts; + } + + public void setShorts(ShortCut4JControlPane[] shorts) { + this.shorts = shorts; + } + + public void setCreators(NameableCreator[] creators) { + this.creators = creators; + } + + public ToolBarDef getToolbarDef() { + return toolbarDef; + } + + public void setToolbarDef(ToolBarDef toolbarDef) { + this.toolbarDef = toolbarDef; + } + + public UIToolbar getToolBar() { + return toolBar; + } + + public void setToolBar(UIToolbar toolBar) { + this.toolBar = toolBar; + } + + public CardLayout getCardLayout() { + return cardLayout; + } + + public void setCardLayout(CardLayout cardLayout) { + this.cardLayout = cardLayout; + } + + public JPanel getCardPane() { + return cardPane; + } + + public void setCardPane(JPanel cardPane) { + this.cardPane = cardPane; + } + + protected void initComponentPane() { + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + this.creators = this.createNameableCreators(); + this.controlUpdatePane = createControlUpdatePane(); + + // p: edit card layout + this.cardLayout = new CardLayout(); + cardPane = FRGUIPaneFactory.createCardLayout_S_Pane(); + cardPane.setLayout(this.cardLayout); + // p:选择的Label + UILabel selectLabel = new UILabel(); + cardPane.add(selectLabel, "SELECT"); + cardPane.add(controlUpdatePane, "EDIT"); + // SplitPane +// JSplitPane mainSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, getLeftPane(), cardPane); +// mainSplitPane.setBorder(BorderFactory.createLineBorder(GUICoreUtils.getTitleLineBorderColor())); +// mainSplitPane.setOneTouchExpandable(true); + + this.add(getLeftPane(), BorderLayout.CENTER); +// mainSplitPane.setDividerLocation(getLeftPreferredSize()); + this.checkButtonEnabled(); + } + + protected abstract JPanel createControlUpdatePane(); + + protected JPanel getLeftPane() { + // LeftPane + JPanel leftPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + + JPanel leftContentPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + initLeftPane(leftContentPane); + leftPane.add(leftContentPane, BorderLayout.CENTER); + + shorts = this.createShortcuts(); + if (ArrayUtils.isEmpty(shorts)) { + return leftPane; + } + + toolbarDef = new ToolBarDef(); + for (ShortCut4JControlPane sj : shorts) { + toolbarDef.addShortCut(sj.getShortCut()); + } + toolBar = ToolBarDef.createJToolBar(); + toolbarDef.updateToolBar(toolBar); + leftContentPane.add(toolBar, BorderLayout.NORTH); + + // 顶部标签及add按钮 + UIToolbar topToolBar = new UIToolbar(); + topToolBar.setLayout(new BorderLayout()); + ShortCut addItem = addItemShortCut().getShortCut(); + addItem.intoJToolBar(topToolBar); + double p = TableLayout.PREFERRED; + double f = TableLayout.FILL; + double[] columnSize = { p, f }; + double[] rowSize = { p}; + Component[][] components = new Component[][]{ + new Component[]{new UILabel("add hyperlink "), topToolBar}, + }; + JPanel leftTopPane = TableLayoutHelper.createTableLayoutPane(components,rowSize,columnSize); + leftPane.add(leftTopPane, BorderLayout.NORTH); + + return leftPane; + } + + /** + * 初始化左边面板 + */ + protected void initLeftPane(JPanel leftPane) { + + } + + protected int getLeftPreferredSize() { + return shorts.length * SHORT_WIDTH; + } + + + protected ShortCut4JControlPane[] createShortcuts() { + return new ShortCut4JControlPane[]{ +// addItemShortCut(), + copyItemShortCut(), + moveUpItemShortCut(), + moveDownItemShortCut(), + sortItemShortCut(), + removeItemShortCut() + }; + } + + protected abstract ShortCut4JControlPane addItemShortCut(); + + protected abstract ShortCut4JControlPane removeItemShortCut(); + + protected abstract ShortCut4JControlPane copyItemShortCut(); + + protected abstract ShortCut4JControlPane moveUpItemShortCut(); + + protected abstract ShortCut4JControlPane moveDownItemShortCut(); + + protected abstract ShortCut4JControlPane sortItemShortCut(); + + public abstract Nameable[] update(); + + + public void populate(Nameable[] nameableArray) { + } + + /** + * 检查按钮可用状态 Check button enabled. + */ + public void checkButtonEnabled() { + } + + protected void doBeforeRemove() { + } + + protected void doAfterRemove() { + } + + public NameableCreator[] creators() { + return creators == null ? new NameableCreator[0] : creators; + } + + protected abstract boolean hasInvalid(boolean isAdd); + + /** + * 刷新 NameableCreator + * + * @param creators 生成器 + */ + public void refreshNameableCreator(NameableCreator[] creators) { + this.creators = creators; + shorts = this.createShortcuts(); + toolbarDef.clearShortCuts(); + for (ShortCut4JControlPane sj : shorts) { + toolbarDef.addShortCut(sj.getShortCut()); + } + + toolbarDef.updateToolBar(toolBar); + toolBar.validate(); + toolBar.repaint(); + this.repaint(); + } +} \ No newline at end of file diff --git a/designer_base/src/com/fr/design/gui/controlpane/UIListControlPane.java b/designer_base/src/com/fr/design/gui/controlpane/UIListControlPane.java new file mode 100644 index 000000000..c36a7902c --- /dev/null +++ b/designer_base/src/com/fr/design/gui/controlpane/UIListControlPane.java @@ -0,0 +1,945 @@ +package com.fr.design.gui.controlpane; + +import com.fr.base.BaseUtils; +import com.fr.base.FRContext; +import com.fr.design.actions.UpdateAction; +import com.fr.design.beans.BasicBeanPane; +import com.fr.design.data.tabledata.tabledatapane.GlobalMultiTDTableDataPane; +import com.fr.design.data.tabledata.tabledatapane.GlobalTreeTableDataPane; +import com.fr.design.data.tabledata.tabledatapane.MultiTDTableDataPane; +import com.fr.design.data.tabledata.tabledatapane.TreeTableDataPane; +import com.fr.design.file.HistoryTemplateListPane; +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.ModNameActionListener; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.JTemplate; +import com.fr.design.menu.LineSeparator; +import com.fr.design.menu.MenuDef; +import com.fr.design.menu.ShortCut; +import com.fr.design.menu.ToolBarDef; +import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.general.ComparatorUtils; +import com.fr.general.Inter; +import com.fr.stable.ArrayUtils; +import com.fr.stable.Nameable; +import com.fr.stable.core.PropertyChangeAdapter; +import sun.swing.DefaultLookup; + +import javax.swing.*; +import javax.swing.border.Border; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import java.awt.*; +import java.awt.event.ActionEvent; +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; +import java.util.Arrays; +import java.util.Comparator; + +/** + * Created by plough on 2017/7/19. + */ + +public abstract class UIListControlPane extends UIControlPane { + public static final String LIST_NAME = "UIControl_List"; + + protected JNameEdList nameableList; + protected int editingIndex; + protected String selectedName; + private boolean isNameRepeated = false; + + public UIListControlPane() { + this.initComponentPane(); + } + + @Override + protected JPanel createControlUpdatePane() { + return new JControlUpdatePane(); + } + + /** + * 生成添加按钮的NameableCreator + * + * @return 按钮的NameableCreator + */ + @Override + public abstract NameableCreator[] createNameableCreators(); + + + @Override + protected void initLeftPane(JPanel leftPane) { + nameableList = createJNameList(); + nameableList.setName(LIST_NAME); + leftPane.add(new UIScrollPane(nameableList), BorderLayout.CENTER); + + + nameableList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); + nameableList.addMouseListener(listMouseListener); + 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(); + } + } + }); + } + + public JNameEdList createJNameList() { + JNameEdList nameEdList = new JNameEdList(new DefaultListModel()) { + @Override + protected void doAfterLostFocus() { + UIListControlPane.this.updateControlUpdatePane(); + } + }; + nameEdList.setCellRenderer(new UINameableListCellRenderer(this)); + return nameEdList; + } + + public void updateControlUpdatePane() { + ((JControlUpdatePane) controlUpdatePane).update(); + } + + protected void doWhenPopulate(BasicBeanPane beanPane) { + + } + + protected void doBeforePopulate(ListModelElement el, Object obj) { + + } + + @Override + protected ShortCut4JControlPane addItemShortCut() { + ShortCut addItemShortCut; + NameableCreator[] creators = creators(); + if (creators.length == 1) { + addItemShortCut = new AddItemUpdateAction(creators); + } else { + addItemShortCut = new AddItemMenuDef(creators); + } + return new AbsoluteEnableShortCut(addItemShortCut); + } + + @Override + protected ShortCut4JControlPane removeItemShortCut() { + return new NormalEnableShortCut(new RemoveItemAction()); + } + + @Override + protected ShortCut4JControlPane copyItemShortCut() { + return new NormalEnableShortCut(new CopyItemAction()); + } + + @Override + protected ShortCut4JControlPane moveUpItemShortCut() { + return new NormalEnableShortCut(new MoveUpItemAction()); + } + + @Override + protected ShortCut4JControlPane moveDownItemShortCut() { + return new NormalEnableShortCut(new MoveDownItemAction()); + } + + @Override + protected ShortCut4JControlPane sortItemShortCut() { + return new NormalEnableShortCut(new SortItemAction()); + } + + public void setNameListEditable(boolean editable) { + this.nameableList.setEditable(editable); + } + + @Override + public Nameable[] update() { + java.util.List res = new java.util.ArrayList(); + ((JControlUpdatePane) this.controlUpdatePane).update(); + DefaultListModel listModel = (DefaultListModel) this.nameableList.getModel(); + for (int i = 0, len = listModel.getSize(); i < len; i++) { + res.add(((ListModelElement) listModel.getElementAt(i)).wrapper); + } + + return res.toArray(new Nameable[res.size()]); + } + + @Override + public void populate(Nameable[] nameableArray) { + DefaultListModel listModel = (DefaultListModel) this.nameableList.getModel(); + listModel.removeAllElements(); + if (ArrayUtils.isEmpty(nameableArray)) { + return; + } + + for (Nameable aNameableArray : nameableArray) { + listModel.addElement(new ListModelElement(aNameableArray)); + } + + if (listModel.size() > 0) { + this.nameableList.setSelectedIndex(0); + } + this.checkButtonEnabled(); + } + + /** + * 添加名字改变时的listener + * + * @param l 名字改变时的监听 + */ + public void addModNameActionListener(ModNameActionListener l) { + this.nameableList.addModNameActionListener(l); + } + + /** + * 添加Editinglistener + * + * @param l 监听 + */ + public void addEditingListner(PropertyChangeAdapter l) { + this.nameableList.addEditingListner(l); + } + + /* + * 刷新当前的选中的UpdatePane + */ + protected void populateSelectedValue() { + ((JControlUpdatePane) UIListControlPane.this.controlUpdatePane).populate(); + } + + /** + * 根据name,选中JNameEdList中的item + */ + public void setSelectedName(String name) { + DefaultListModel listModel = (DefaultListModel) this.nameableList.getModel(); + for (int i = 0, len = listModel.getSize(); i < len; i++) { + Nameable item = ((ListModelElement) listModel.getElementAt(i)).wrapper; + if (ComparatorUtils.equals(name, item.getName())) { + this.nameableList.setSelectedIndex(i); + break; + } + } + } + + public String getEditingName() { + return this.nameableList.getEditingName(); + } + + public Object getEditingType() { + return this.nameableList.getAllTypes()[editingIndex]; + } + + public void setWarnigText(int index) { + this.nameableList.setWarnigText(index); + } + + /** + * 获取选中的名字 + */ + public String getSelectedName() { + ListModelElement el = (ListModelElement) this.nameableList.getSelectedValue(); + + return el == null ? null : el.wrapper.getName(); + } + + protected boolean isNameRepeted(java.util.List[] list, String name) { + for (int i = 0; i < list.length; i++) { + if (list[i].contains(name)) { + isNameRepeated = true; + return true; + } + } + isNameRepeated = false; + return false; + } + + /** + * 名字是否重复 + * + * @return 重复则返回true + */ + public boolean isNameRepeated() { + return isNameRepeated; + } + + /** + * 添加 Nameable + * + * @param nameable 添加的Nameable + * @param index 序号 + */ + public void addNameable(Nameable nameable, int index) { + JNameEdList nameEdList = UIListControlPane.this.nameableList; + DefaultListModel model = (DefaultListModel) nameEdList.getModel(); + + ListModelElement el = new ListModelElement(nameable); + model.add(index, el); + nameableList.setSelectedIndex(index); + nameableList.ensureIndexIsVisible(index); + + nameEdList.repaint(); + } + + /** + * 是否重命名 + * + * @return 是则true + */ + public boolean isContainsRename() { + String rename = Inter.getLocText("FR-Please_Rename") + "!"; + String[] names = this.nameableList.getAllNames(); + for (int i = names.length - 1; i >= 0; i--) { + if (ComparatorUtils.equals(names[i], rename)) { + return true; + } + } + return false; + } + + protected DefaultListModel getModel() { + return (DefaultListModel) UIListControlPane.this.nameableList.getModel(); + } + + private String createUnrepeatedCopyName(String suffix) { + DefaultListModel model = this.getModel(); + String[] names = new String[model.getSize()]; + for (int i = 0; i < model.size(); i++) { + names[i] = ((ListModelElement) model.get(i)).wrapper.getName(); + } + String lastName = "CopyOf" + suffix; + while (ArrayUtils.contains(names, lastName)) { + lastName = "CopyOf" + lastName; + } + return lastName; + } + + + /** + * 生成不重复的名字 + * + * @param prefix 名字前缀 + * @return 名字 + */ + @Override + public String createUnrepeatedName(String prefix) { + DefaultListModel model = this.getModel(); + Nameable[] all = new Nameable[model.getSize()]; + for (int i = 0; i < model.size(); i++) { + all[i] = ((ListModelElement) model.get(i)).wrapper; + } + // richer:生成的名字从1开始. kunsnat: 添加属性从0开始. + int count = all.length + 1; + while (true) { + String name_test = prefix + count; + boolean repeated = false; + for (int i = 0, len = model.size(); i < len; i++) { + Nameable nameable = all[i]; + if (ComparatorUtils.equals(nameable.getName(), name_test)) { + repeated = true; + break; + } + } + + if (!repeated) { + return name_test; + } + + count++; + } + } + + /** + * 增加项的UpdateAction + */ + protected class AddItemUpdateAction extends UpdateAction { + final NameableCreator creator; + + public AddItemUpdateAction(NameableCreator[] creators) { + this.creator = creators[0]; + this.setName(Inter.getLocText("FR-Action_Add")); + this.setMnemonic('A'); + this.setSmallIcon(BaseUtils.readIcon("/com/fr/base/images/cell/control/add.png")); + } + + @Override + public void actionPerformed(ActionEvent e) { + Nameable nameable = creator.createNameable(UIListControlPane.this); + + UIListControlPane.this.addNameable(nameable, getModel().getSize()); + } + } + + /* + * 增加项的MenuDef + */ + protected class AddItemMenuDef extends MenuDef { + public AddItemMenuDef(NameableCreator[] creators) { + this.setName(Inter.getLocText("FR-Action_Add")); + this.setMnemonic('A'); + this.setIconPath("/com/fr/design/images/control/addPopup.png"); + wrapActionListener(creators); + } + + private void wrapActionListener(NameableCreator[] creators) { + for (final NameableCreator creator : creators) { + if (!whetherAdd(creator.menuName())) { + continue; + } + boolean isTrue = ComparatorUtils.equals(creator.menuName(), Inter.getLocText("Datasource-Stored_Procedure")) || + ComparatorUtils.equals(creator.menuName(), Inter.getLocText("DS-Relation_TableData")) || ComparatorUtils.equals(creator.menuName(), Inter.getLocText("DS-Multi_Dimensional_Database")); + if (isTrue) { + this.addShortCut(new LineSeparator()); + } + this.addShortCut(new UpdateAction() { + { + this.setName(creator.menuName()); + Icon icon = creator.menuIcon(); + if (icon != null) { + this.setSmallIcon(icon); + } + } + + @Override + public void actionPerformed(ActionEvent e) { + if (hasInvalid(true)) { + return; + } + + Nameable nameable = creator.createNameable(UIListControlPane.this); + + UIListControlPane.this.addNameable(nameable, getModel().getSize()); + } + }); + } + } + + private boolean whetherAdd(String itemName) { + JTemplate jTemplate = HistoryTemplateListPane.getInstance().getCurrentEditingTemplate(); + if (jTemplate == null) { + return false; + } + //先屏蔽掉这个,之后还有别的 + String[] names = {Inter.getLocText("FR-Hyperlink_Chart_Float")}; + for (String name : names) { + if (!jTemplate.isJWorkBook() && ComparatorUtils.equals(itemName, name)) { + return false; + } + } + String formName = Inter.getLocText("Hyperlink-Form_link"); + return !(jTemplate.isJWorkBook() && ComparatorUtils.equals(itemName, formName)); + } + } + + /* + * 移除item + */ + private class RemoveItemAction extends UpdateAction { + public RemoveItemAction() { + this.setName(Inter.getLocText("FR-Action_Remove")); + this.setMnemonic('R'); + this.setSmallIcon(BaseUtils + .readIcon("/com/fr/base/images/cell/control/remove.png")); + } + + @Override + public void actionPerformed(ActionEvent evt) { + try { + UIListControlPane.this.nameableList.getCellEditor() + .stopCellEditing(); + } catch (Exception ignored) { + } + // bug:在选中一个NameObject并删除,会遗留下Name. + doBeforeRemove(); + if (GUICoreUtils.removeJListSelectedNodes(SwingUtilities + .getWindowAncestor(UIListControlPane.this), nameableList)) { + checkButtonEnabled(); + doAfterRemove(); + } + } + } + + /* + * CopyItem + */ + private class CopyItemAction extends UpdateAction { + public CopyItemAction() { + this.setName(Inter.getLocText("FR-Action_Copy")); + this.setMnemonic('C'); + this.setSmallIcon(BaseUtils + .readIcon("/com/fr/base/images/cell/control/copy.png")); + } + + @Override + public void actionPerformed(ActionEvent evt) { + // p:选中的值. + ListModelElement selectedValue = (ListModelElement) nameableList.getSelectedValue(); + if (selectedValue == null) { + return; + } + + ((JControlUpdatePane) controlUpdatePane).update(); + + Nameable selectedNameable = selectedValue.wrapper; + + // p: 用反射机制实现 + try { + Nameable newNameable = (Nameable) BaseUtils.cloneObject(selectedNameable); + newNameable.setName(createUnrepeatedCopyName(selectedNameable.getName())); + + UIListControlPane.this.addNameable(newNameable, nameableList.getSelectedIndex() + 1); + } catch (Exception e) { + FRContext.getLogger().error(e.getMessage(), e); + } + } + } + + /* + * 上移Item + */ + private class MoveUpItemAction extends UpdateAction { + public MoveUpItemAction() { + this.setName(Inter.getLocText("Utils-Move_Up")); + this.setMnemonic('U'); + this.setSmallIcon(BaseUtils + .readIcon("/com/fr/design/images/control/up.png")); + } + + @Override + public void actionPerformed(ActionEvent evt) { + int selectedIndex = nameableList.getSelectedIndex(); + if (selectedIndex == -1) { + return; + } + + // 上移 + if (selectedIndex > 0) { + DefaultListModel listModel = (DefaultListModel) nameableList + .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); + } + } + } + + /* + * 下移Item + */ + private class MoveDownItemAction extends UpdateAction { + public MoveDownItemAction() { + this.setName(Inter.getLocText("Utils-Move_Down")); + this.setMnemonic('D'); + this.setSmallIcon(BaseUtils + .readIcon("/com/fr/design/images/control/down.png")); + } + + @Override + public void actionPerformed(ActionEvent evt) { + int selectedIndex = nameableList.getSelectedIndex(); + if (selectedIndex == -1) { + return; + } + + if (selectedIndex < nameableList.getModel().getSize() - 1) { + DefaultListModel listModel = (DefaultListModel) nameableList + .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); + } + } + } + + private class SortItemAction extends UpdateAction { + private boolean isAtoZ = false; + + public SortItemAction() { + this.setName(Inter.getLocText("FR-Action_Sort")); + this.setMnemonic('S'); + this.setSmallIcon(BaseUtils + .readIcon("/com/fr/design/images/control/sortAsc.png")); + } + + @Override + public void actionPerformed(ActionEvent evt) { + // p:选中的值. + Object selectedValue = nameableList.getSelectedValue(); + + DefaultListModel listModel = (DefaultListModel) nameableList + .getModel(); + Nameable[] nameableArray = new Nameable[listModel.getSize()]; + if (nameableArray.length <= 0) { + return; + } + + for (int i = 0; i < listModel.getSize(); i++) { + nameableArray[i] = ((ListModelElement) listModel.getElementAt(i)).wrapper; + } + + // p:排序. + if (isAtoZ) { + Comparator nameableComparator = new Comparator() { + @Override + public int compare(Nameable o1, Nameable o2) { + return -ComparatorUtils.compare(o1.getName(), o2 + .getName()); + } + }; + isAtoZ = !isAtoZ; + Arrays.sort(nameableArray, nameableComparator); + } else { + Comparator nameableComparator = new Comparator() { + @Override + public int compare(Nameable o1, Nameable o2) { + return ComparatorUtils.compare(o1.getName(), o2 + .getName()); + } + }; + isAtoZ = !isAtoZ; + Arrays.sort(nameableArray, nameableComparator); + } + + for (int i = 0; i < nameableArray.length; i++) { + listModel.set(i, new ListModelElement(nameableArray[i])); + } + + // p:需要选中以前的那个值. + if (selectedValue != null) { + nameableList.setSelectedValue(selectedValue, true); + } + + checkButtonEnabled(); + // p:需要repaint. + nameableList.repaint(); + } + } + + /* + * JNameEdList的鼠标事件 + */ + private MouseListener listMouseListener = new MouseAdapter() { + @Override + public void mouseReleased(MouseEvent evt) { + nameableList.stopEditing(); + if (evt.getClickCount() >= 2 + && SwingUtilities.isLeftMouseButton(evt)) { + editingIndex = nameableList.getSelectedIndex(); + selectedName = nameableList.getNameAt(editingIndex); + nameableList.editItemAt(nameableList.getSelectedIndex()); + } + // 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 mouseMoved(MouseEvent e) { + + } + }; + + /** + * 检查按钮可用状态 Check button enabled. + */ + @Override + public void checkButtonEnabled() { + + int selectedIndex = nameableList.getSelectedIndex(); + if (selectedIndex == -1) { + this.cardLayout.show(cardPane, "SELECT"); + } else { + this.cardLayout.show(cardPane, "EDIT"); + } + for (ShortCut4JControlPane sj : getShorts()) { + sj.checkEnable(); + } + } + + + public class AbsoluteEnableShortCut extends ShortCut4JControlPane { + public AbsoluteEnableShortCut(ShortCut shortCut) { + this.shortCut = shortCut; + } + + /** + * 检查是否可用 + */ + @Override + public void checkEnable() { + this.shortCut.setEnabled(true); + } + } + + public class NormalEnableShortCut extends ShortCut4JControlPane { + public NormalEnableShortCut(ShortCut shortCut) { + this.shortCut = shortCut; + } + + /** + * 检查是否可用 + */ + @Override + public void checkEnable() { + this.shortCut.setEnabled(getModel() + .getSize() > 0 + && UIListControlPane.this.nameableList.getSelectedIndex() != -1); + } + } + + public class SortEnableShortCut extends ShortCut4JControlPane { + public SortEnableShortCut(ShortCut shortCut) { + this.shortCut = shortCut; + } + + /** + * 检查是否可用 + */ + @Override + public void checkEnable() { + this.shortCut.setEnabled(getModel().getSize() > 1); + } + + } + + public class MoveUpEnableShortCut extends ShortCut4JControlPane { + public MoveUpEnableShortCut(ShortCut shortCut) { + this.shortCut = shortCut; + } + + /** + * 检查是否可用 + */ + @Override + public void checkEnable() { + this.shortCut.setEnabled(getModel().getSize() > 1 + && UIListControlPane.this.nameableList.getSelectedIndex() > 0); + } + + } + + public class MoveDownEnableShortCut extends ShortCut4JControlPane { + public MoveDownEnableShortCut(ShortCut shortCut) { + this.shortCut = shortCut; + } + + /** + * 检查是否可用 + */ + @Override + public void checkEnable() { + this.shortCut.setEnabled(getModel().getSize() > 1 + && UIListControlPane.this.nameableList.getSelectedIndex() < UIListControlPane.this.nameableList.getModel().getSize() - 1); + } + + } + + private class JControlUpdatePane extends JPanel { + private CardLayout card; + private JPanel cardPane; + private BasicBeanPane[] updatePanes; + + private ListModelElement elEditing; + + public JControlUpdatePane() { + initUpdatePane(); + } + + private void initUpdatePane() { + NameableCreator[] creators = creators(); + if (creators == null) { + return; + } + card = new CardLayout(); + cardPane = FRGUIPaneFactory.createCardLayout_S_Pane(); + cardPane.setLayout(card); + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + this.add(cardPane); + int len = creators.length; + updatePanes = new BasicBeanPane[len]; + } + + public void populate() { + ListModelElement el = (ListModelElement) UIListControlPane.this.nameableList.getSelectedValue(); + if (el == null) { + return; + } + + elEditing = el; + NameableCreator[] creators = creators(); + + for (int i = 0, len = updatePanes.length; i < len; i++) { + Object ob2Populate = creators[i].acceptObject2Populate(el.wrapper); + if (ob2Populate != null) { + if (updatePanes[i] == null) { + if (isMulti(creators[i].getUpdatePane()) || isTree(creators[i].getUpdatePane())) { + updatePanes[i] = createPaneByCreators(creators[i], el.wrapper.getName()); + } else { + updatePanes[i] = createPaneByCreators(creators[i]); + } + cardPane.add(updatePanes[i], String.valueOf(i)); + } + card.show(cardPane, String.valueOf(i)); + doBeforePopulate(el, ob2Populate); + updatePanes[i].populateBean(ob2Populate); + doWhenPopulate(updatePanes[i]); + break; + } + } + } + + public boolean isMulti(Class _class) { + return ComparatorUtils.equals(_class, GlobalMultiTDTableDataPane.class) || ComparatorUtils.equals(_class, MultiTDTableDataPane.class); + } + + public boolean isTree(Class _class) { + return ComparatorUtils.equals(_class, GlobalTreeTableDataPane.class) || ComparatorUtils.equals(_class, TreeTableDataPane.class); + } + + public void update() { + NameableCreator[] creators = creators(); + for (int i = 0; i < updatePanes.length; i++) { + BasicBeanPane pane = updatePanes[i]; + + if (pane != null && pane.isVisible()) { + Object bean = pane.updateBean(); + if (i < creators.length) { + creators[i].saveUpdatedBean(elEditing, bean); + } + } + } + } + + public void checkValid() throws Exception { + if (updatePanes != null) { + for (int i = 0; i < updatePanes.length; i++) { + if (updatePanes[i] != null) { + updatePanes[i].checkValid(); + } + } + } + } + } + + protected BasicBeanPane createPaneByCreators(NameableCreator creator) { + try { + return creator.getUpdatePane().newInstance(); + } catch (InstantiationException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + } + + protected 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); + } + + } + + // 选项添加个数有限制等情况下 要求能控制快捷按钮的状态 + protected void setToolbarDefEnable(int shortCutIndex, int itemIndex, boolean enabled) { + ToolBarDef toolbarDef = getToolbarDef(); + if (toolbarDef.getShortCutCount() > shortCutIndex) { + ShortCut sc = toolbarDef.getShortCut(shortCutIndex); + if (sc instanceof AddItemMenuDef) { + AddItemMenuDef am = (AddItemMenuDef) sc; + if (am.getShortCutCount() > itemIndex) { + am.getShortCut(itemIndex).setEnabled(enabled); + } + } + } + } + + /** + * 检查是否符合规范 + * + * @throws Exception + */ + @Override + public void checkValid() throws Exception { + ((JControlUpdatePane) this.controlUpdatePane).checkValid(); + } + + private int getInValidIndex() { + BasicBeanPane[] p = ((JControlUpdatePane) controlUpdatePane).updatePanes; + if (p != null) { + for (int i = 0; i < p.length; i++) { + if (p[i] != null) { + try { + p[i].checkValid(); + } catch (Exception e) { + return i; + } + } + } + } + return -1; + } + + @Override + protected boolean hasInvalid(boolean isAdd) { + int idx = UIListControlPane.this.getInValidIndex(); + if (isAdd || nameableList.getSelectedIndex() != idx) { + try { + checkValid(); + } catch (Exception exp) { + JOptionPane.showMessageDialog(UIListControlPane.this, exp.getMessage()); + nameableList.setSelectedIndex(idx); + return true; + } + } + return false; + } + /** + * 设置选中项 + * + * @param index 选中项的序列号 + */ + public void setSelectedIndex(int index) { + nameableList.setSelectedIndex(index); + } + +} \ No newline at end of file diff --git a/designer_base/src/com/fr/design/gui/controlpane/UINameableListCellRenderer.java b/designer_base/src/com/fr/design/gui/controlpane/UINameableListCellRenderer.java new file mode 100644 index 000000000..df672e8a1 --- /dev/null +++ b/designer_base/src/com/fr/design/gui/controlpane/UINameableListCellRenderer.java @@ -0,0 +1,146 @@ +package com.fr.design.gui.controlpane; + +import com.fr.base.BaseUtils; +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.stable.Nameable; +import sun.swing.DefaultLookup; + +import javax.swing.*; +import javax.swing.border.Border; +import javax.swing.border.EmptyBorder; +import java.awt.*; + +/** + * Nameable的ListCellRenerer + * Created by plough on 2017/7/21. + */ + +public class UINameableListCellRenderer extends + JPanel implements ListCellRenderer { + private static final Border SAFE_NO_FOCUS_BORDER = new EmptyBorder(1, 1, 1, 1); + private static final Border DEFAULT_NO_FOCUS_BORDER = new EmptyBorder(1, 1, 1, 1); + protected static Border noFocusBorder = DEFAULT_NO_FOCUS_BORDER; + private static final int BUTTON_WIDTH = 40; + private UIButton editButton; + private UILabel label; + private UIListControlPane listControlPane; + + public UINameableListCellRenderer(UIListControlPane listControlPane) { + super(); + this.listControlPane = listControlPane; + initComponents(); + setOpaque(true); + setBorder(getNoFocusBorder()); + setName("List.cellRenderer"); + } + + private void initComponents() { + editButton = new UIButton("edit") { + public Dimension getPreferredSize() { + return new Dimension(BUTTON_WIDTH, BUTTON_WIDTH); + } + }; + editButton.set4LargeToolbarButton(); + label = new UILabel(); +// label.setEditable(false); + this.setLayout(new BorderLayout()); + this.add(editButton, BorderLayout.WEST); + this.add(label, BorderLayout.CENTER); + } + + private Border getNoFocusBorder() { + Border border = DefaultLookup.getBorder(this, ui, "List.cellNoFocusBorder"); + if (System.getSecurityManager() != null) { + if (border != null) return border; + return SAFE_NO_FOCUS_BORDER; + } else { + if (border != null && + (noFocusBorder == null || + noFocusBorder == DEFAULT_NO_FOCUS_BORDER)) { + return border; + } + return noFocusBorder; + } + } + + private void setText(String t) { + label.setText(t); + } + + @Override + public Component getListCellRendererComponent(JList list, Object value, + int index, boolean isSelected, boolean cellHasFocus) { + setComponentOrientation(list.getComponentOrientation()); + + Color bg = null; + Color fg = null; + + JList.DropLocation dropLocation = list.getDropLocation(); + if (dropLocation != null + && !dropLocation.isInsert() + && dropLocation.getIndex() == index) { + + bg = DefaultLookup.getColor(this, ui, "List.dropCellBackground"); + fg = DefaultLookup.getColor(this, ui, "List.dropCellForeground"); + + isSelected = true; + } + + if (isSelected) { + setBackground(bg == null ? list.getSelectionBackground() : bg); + setForeground(fg == null ? list.getSelectionForeground() : fg); + } + else { + setBackground(list.getBackground()); + setForeground(list.getForeground()); + } + +// if (value instanceof Icon) { +// setIcon((Icon)value); +// setText(""); +// } +// else { +// setIcon(null); + setText((value == null) ? "" : value.toString()); +// } + + setEnabled(list.isEnabled()); + setFont(list.getFont()); + + Border border = null; + if (cellHasFocus) { + if (isSelected) { + border = DefaultLookup.getBorder(this, ui, "List.focusSelectedCellHighlightBorder"); + } + if (border == null) { + border = DefaultLookup.getBorder(this, ui, "List.focusCellHighlightBorder"); + } + } else { + border = getNoFocusBorder(); + } + setBorder(border); + + if (value instanceof ListModelElement) { + Nameable wrappee = ((ListModelElement) value).wrapper; + this.setText(((ListModelElement) value).wrapper.getName()); + + boolean iconSet = false; + for (NameableCreator creator : listControlPane.creators()) { + if (creator.menuIcon() != null && creator.acceptObject2Populate(wrappee) != null) { +// this.setIcon(creator.menuIcon()); + this.setToolTipText(creator.createTooltip()); + iconSet = true; + break; + } + } +// if (!iconSet) { +// this.setIcon(BaseUtils.readIcon("/com/fr/base/images/oem/cpt.png")); +// } + } + + return this; + } +} \ No newline at end of file diff --git a/designer_base/src/com/fr/design/gui/frpane/HyperlinkGroupPane.java b/designer_base/src/com/fr/design/gui/frpane/HyperlinkGroupPane.java index d0a824074..fcd9ba383 100644 --- a/designer_base/src/com/fr/design/gui/frpane/HyperlinkGroupPane.java +++ b/designer_base/src/com/fr/design/gui/frpane/HyperlinkGroupPane.java @@ -4,6 +4,7 @@ import com.fr.design.ExtraDesignClassManager; import com.fr.design.fun.HyperlinkProvider; import com.fr.design.gui.controlpane.JListControlPane; import com.fr.design.gui.controlpane.NameableCreator; +import com.fr.design.gui.controlpane.UIListControlPane; import com.fr.design.module.DesignModuleFactory; import com.fr.general.Inter; import com.fr.general.NameObject; @@ -23,7 +24,7 @@ import java.util.Set; * @author kunsnat E-mail:kunsnat@gmail.com * @version 创建时间:2013-6-25 上午11:17:57 */ -public abstract class HyperlinkGroupPane extends JListControlPane { +public abstract class HyperlinkGroupPane extends UIListControlPane { /** * 生成添加按钮的NameableCreator * From 5985819f8e4075d08874e6b071eac96b0b4b93ef Mon Sep 17 00:00:00 2001 From: plough Date: Mon, 24 Jul 2017 10:06:11 +0800 Subject: [PATCH 4/6] =?UTF-8?q?REPORT-3163=20=E5=90=88=E4=BD=9C=E5=BC=80?= =?UTF-8?q?=E5=8F=919.0=E8=AE=BE=E8=AE=A1=E5=99=A8=3D>=E8=B0=83=E6=95=B4?= =?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89=E5=88=97=E8=A1=A8=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../design/gui/controlpane/UIControlPane.java | 42 ++ .../gui/controlpane/UIListControlPane.java | 14 +- .../UINameableListCellRenderer.java | 23 +- .../com/fr/design/gui/ilist/UINameEdList.java | 398 ++++++++++++++++++ 4 files changed, 466 insertions(+), 11 deletions(-) create mode 100644 designer_base/src/com/fr/design/gui/ilist/UINameEdList.java diff --git a/designer_base/src/com/fr/design/gui/controlpane/UIControlPane.java b/designer_base/src/com/fr/design/gui/controlpane/UIControlPane.java index f67512d92..b21b740f5 100644 --- a/designer_base/src/com/fr/design/gui/controlpane/UIControlPane.java +++ b/designer_base/src/com/fr/design/gui/controlpane/UIControlPane.java @@ -6,6 +6,7 @@ import com.fr.design.gui.itoolbar.UIToolbar; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.layout.TableLayout; import com.fr.design.layout.TableLayoutHelper; +import com.fr.design.mainframe.EastRegionContainerPane; import com.fr.design.menu.ShortCut; import com.fr.design.menu.ToolBarDef; import com.fr.design.utils.gui.GUICoreUtils; @@ -28,6 +29,7 @@ public abstract class UIControlPane extends BasicPane implements UnrepeatedNameH private ToolBarDef toolbarDef; private UIToolbar toolBar; + protected PopupEditPane popupEditPane; // peter:这是整体的一个cardLayout Pane protected CardLayout cardLayout; @@ -101,6 +103,7 @@ public abstract class UIControlPane extends BasicPane implements UnrepeatedNameH UILabel selectLabel = new UILabel(); cardPane.add(selectLabel, "SELECT"); cardPane.add(controlUpdatePane, "EDIT"); + popupEditPane = new PopupEditPane(cardPane); // SplitPane // JSplitPane mainSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, getLeftPane(), cardPane); // mainSplitPane.setBorder(BorderFactory.createLineBorder(GUICoreUtils.getTitleLineBorderColor())); @@ -229,4 +232,43 @@ public abstract class UIControlPane extends BasicPane implements UnrepeatedNameH toolBar.repaint(); this.repaint(); } + + // 点击"编辑"按钮,弹出面板 + protected class PopupEditPane extends JPopupMenu { + private JComponent contentPane; + // private PopupToolPane popupToolPane; + private int fixedHeight; + + PopupEditPane(JComponent pane) { + contentPane = pane; + this.setLayout(new BorderLayout()); + this.add(contentPane, BorderLayout.CENTER); + this.setOpaque(false); +// fixedHeight = getPreferredSize().height - contentPane.getPreferredSize().height; +// updateSize(); + } + +// private void updateSize() { +// int newHeight = fixedHeight + contentPane.getPreferredSize().height; +// this.setPreferredSize(new Dimension(CONTAINER_WIDTH - TAB_WIDTH, newHeight)); +// } + + public JComponent getContentPane() { + return contentPane; + } + + public void replaceContentPane(JComponent pane) { +// remove(pane); + this.remove(this.contentPane); + this.add(this.contentPane = pane); +// updateSize(); + refreshContainer(); + } + + private void refreshContainer() { + validate(); + repaint(); + revalidate(); + } + } } \ No newline at end of file diff --git a/designer_base/src/com/fr/design/gui/controlpane/UIListControlPane.java b/designer_base/src/com/fr/design/gui/controlpane/UIListControlPane.java index c36a7902c..878668f0d 100644 --- a/designer_base/src/com/fr/design/gui/controlpane/UIListControlPane.java +++ b/designer_base/src/com/fr/design/gui/controlpane/UIListControlPane.java @@ -10,7 +10,7 @@ import com.fr.design.data.tabledata.tabledatapane.MultiTDTableDataPane; import com.fr.design.data.tabledata.tabledatapane.TreeTableDataPane; import com.fr.design.file.HistoryTemplateListPane; import com.fr.design.gui.icontainer.UIScrollPane; -import com.fr.design.gui.ilist.JNameEdList; +import com.fr.design.gui.ilist.UINameEdList; import com.fr.design.gui.ilist.ListModelElement; import com.fr.design.gui.ilist.ModNameActionListener; import com.fr.design.layout.FRGUIPaneFactory; @@ -48,7 +48,7 @@ import java.util.Comparator; public abstract class UIListControlPane extends UIControlPane { public static final String LIST_NAME = "UIControl_List"; - protected JNameEdList nameableList; + protected UINameEdList nameableList; protected int editingIndex; protected String selectedName; private boolean isNameRepeated = false; @@ -96,8 +96,8 @@ public abstract class UIListControlPane extends UIControlPane { }); } - public JNameEdList createJNameList() { - JNameEdList nameEdList = new JNameEdList(new DefaultListModel()) { + public UINameEdList createJNameList() { + UINameEdList nameEdList = new UINameEdList(new DefaultListModel()) { @Override protected void doAfterLostFocus() { UIListControlPane.this.updateControlUpdatePane(); @@ -216,7 +216,7 @@ public abstract class UIListControlPane extends UIControlPane { } /** - * 根据name,选中JNameEdList中的item + * 根据name,选中UINameEdList中的item */ public void setSelectedName(String name) { DefaultListModel listModel = (DefaultListModel) this.nameableList.getModel(); @@ -277,7 +277,7 @@ public abstract class UIListControlPane extends UIControlPane { * @param index 序号 */ public void addNameable(Nameable nameable, int index) { - JNameEdList nameEdList = UIListControlPane.this.nameableList; + UINameEdList nameEdList = UIListControlPane.this.nameableList; DefaultListModel model = (DefaultListModel) nameEdList.getModel(); ListModelElement el = new ListModelElement(nameable); @@ -631,7 +631,7 @@ public abstract class UIListControlPane extends UIControlPane { } /* - * JNameEdList的鼠标事件 + * UINameEdList的鼠标事件 */ private MouseListener listMouseListener = new MouseAdapter() { @Override diff --git a/designer_base/src/com/fr/design/gui/controlpane/UINameableListCellRenderer.java b/designer_base/src/com/fr/design/gui/controlpane/UINameableListCellRenderer.java index df672e8a1..e8844d385 100644 --- a/designer_base/src/com/fr/design/gui/controlpane/UINameableListCellRenderer.java +++ b/designer_base/src/com/fr/design/gui/controlpane/UINameableListCellRenderer.java @@ -5,6 +5,7 @@ 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; @@ -12,6 +13,8 @@ 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 @@ -23,8 +26,8 @@ public class UINameableListCellRenderer extends private static final Border SAFE_NO_FOCUS_BORDER = new EmptyBorder(1, 1, 1, 1); private static final Border DEFAULT_NO_FOCUS_BORDER = new EmptyBorder(1, 1, 1, 1); protected static Border noFocusBorder = DEFAULT_NO_FOCUS_BORDER; - private static final int BUTTON_WIDTH = 40; - private UIButton editButton; + private static final int BUTTON_WIDTH = 20; + private UILabel editButton; // "编辑按钮",实际上是一个 UILabel,由列表项(UIListControlPane)统一处理点击事件 private UILabel label; private UIListControlPane listControlPane; @@ -38,12 +41,19 @@ public class UINameableListCellRenderer extends } private void initComponents() { - editButton = new UIButton("edit") { + editButton = new UILabel() { public Dimension getPreferredSize() { return new Dimension(BUTTON_WIDTH, BUTTON_WIDTH); } }; - editButton.set4LargeToolbarButton(); +// editButton.set4LargeToolbarButton(); + editButton.setIcon(BaseUtils.readIcon("/com/fr/base/images/cell/control/add.png")); +// editButton.addActionListener(new ActionListener() { +// @Override +// public void actionPerformed(ActionEvent e) { +// popupEditPane(); +// } +// }); label = new UILabel(); // label.setEditable(false); this.setLayout(new BorderLayout()); @@ -51,6 +61,11 @@ public class UINameableListCellRenderer extends this.add(label, BorderLayout.CENTER); } + private void popupEditPane() { + GUICoreUtils.showPopupMenu(listControlPane.popupEditPane, editButton, + - listControlPane.popupEditPane.getPreferredSize().width, 0); + } + private Border getNoFocusBorder() { Border border = DefaultLookup.getBorder(this, ui, "List.cellNoFocusBorder"); if (System.getSecurityManager() != null) { diff --git a/designer_base/src/com/fr/design/gui/ilist/UINameEdList.java b/designer_base/src/com/fr/design/gui/ilist/UINameEdList.java new file mode 100644 index 000000000..73ba2bf82 --- /dev/null +++ b/designer_base/src/com/fr/design/gui/ilist/UINameEdList.java @@ -0,0 +1,398 @@ +package com.fr.design.gui.ilist; + +import com.fr.base.Utils; +import com.fr.design.gui.itextfield.UITextField; +import com.fr.general.Inter; +import com.fr.general.NameObject; +import com.fr.stable.Nameable; +import com.fr.stable.StringUtils; +import com.fr.stable.core.PropertyChangeAdapter; + +import javax.swing.*; +import javax.swing.event.CellEditorListener; +import javax.swing.event.ChangeEvent; +import java.awt.*; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.ArrayList; +import java.util.Vector; + +/** + * Created by plough on 2017/7/23. + */ +public class UINameEdList extends UIList implements CellEditorListener { + private static final int TEST_LIST_LENTH = 20; + private static final int BUTTON_WIDTH = 20; + private boolean editable = true; + + // kunsnat: 是否强制ListName是数字 (int型) + private boolean isNameShouldNumber = false; + + transient protected ListCellEditor cellEditor; + transient protected Component editorComp; + transient protected int editingIndex; + private PropertyChangeAdapter editingListner; + private java.util.List ll = new ArrayList(); + + public UINameEdList(ListModel dataModel) { + super(dataModel); + } + + public UINameEdList(final Object[] listData) { + super(listData); + } + + public UINameEdList(final Vector listData) { + super(listData); + } + + public UINameEdList() { + super(); + } + + /* + * Sets是否可编辑 + */ + public void setEditable(boolean editable) { + this.editable = editable; + } + + /** + * 是否可编辑 + * + * @return 是则返回true + */ + public boolean isEditable() { + return this.editable; + } + + public void setNameShouldNumber(boolean isNameShouldNumber) { + this.isNameShouldNumber = isNameShouldNumber; + } + + /** + * 是否强制ListName是数字 (int型) + * + * @return 是则返回true + */ + public boolean isNameShouldNumber() { + return isNameShouldNumber; + } + + /** + * 添加名字改变时的listener + * + * @param l 监听器 + */ + public void addModNameActionListener(ModNameActionListener l) { + ll.add(l); + } + + /** + * 编辑时的监听器 + * + * @param l 监听器 + */ + public void addEditingListner(PropertyChangeAdapter l) { + this.editingListner = l; + } + + /** + * 移除某名字改变时的listener + * + * @param l 监听器 + */ + public void removeModNameActionListener(ModNameActionListener l) { + ll.remove(l); + } + + public ListCellEditor getCellEditor() { + if (cellEditor == null) { + UITextField editField = new UITextField(); + if (editingListner != null) { + editField.addFocusListener(new FocusListener() { + + @Override + public void focusLost(FocusEvent e) { + editingListner.propertyChange(); + + } + + @Override + public void focusGained(FocusEvent e) { + // TODO Auto-generated method stub + + } + }); + } + cellEditor = new DefaultListCellEditor(editField) { + public boolean stopCellEditing() { + boolean isTrue = super.stopCellEditing(); + stopEditing(); + + return isTrue; + } + }; + cellEditor.addCellEditorListener(this); + } + + return cellEditor; + } + + protected void doAfterLostFocus() { + + } + + public void setCellEditor(ListCellEditor editor) { + this.cellEditor = editor; + } + + /* + * 取得index节点的名字 + */ + public String getNameAt(int index) { + Nameable nameable = ((ListModelElement) getModel().getElementAt(index)).wrapper; + if (nameable != null) { + return nameable.getName(); + } + + return null; + } + + public Object getType(int index) { + Nameable nameable = ((ListModelElement) getModel().getElementAt(index)).wrapper; + if (nameable != null && nameable instanceof NameObject) { + return ((NameObject) nameable).getObject(); + } + return null; + } + + + public void setWarnigText() { + setWarnigText(this.getSelectedIndex()); + } + + public void setWarnigText(int index) { + setNameAt(Inter.getLocText("Please_Rename") + "!", index); + this.repaint(); + } + + /* + * 设置index节点的名字 + */ + // b:edit改变name的时候怎么办? + public void setNameAt(String name, int index) { + Nameable nameable = ((ListModelElement) getModel().getElementAt(index)).wrapper; + if (nameable != null) { + String oldName = nameable.getName(); + + if (isNameShouldNumber()) { + // kunsnat: 限制只能是数字(int型) + Number number = Utils.string2Number(name); + if (number == null) { + nameable.setName(oldName); + } else { + int newName = number.intValue(); + nameable.setName(String.valueOf(newName)); + } + } else { + nameable.setName(name); + } + + for (int i = 0, len = ll.size(); i < len; i++) { + ll.get(i).nameModed(index, oldName, name); + } + } + } + + /* + * 编辑第index个item + */ + private String oldName; + + /** + * 编辑第index项 + * + * @param index 序号 + * @return 成功返回true + */ + public boolean editItemAt(int index) { + // 如果不可编辑,返回 + if (!this.editable) { + return false; + } + + if (cellEditor != null && !cellEditor.stopCellEditing()) { + return false; + } + if (index < 0 || index >= this.getModel().getSize()) { + return false; + } + + ListCellEditor editor = getCellEditor(); + Object value = editor.getCellEditorValue(); + if (!StringUtils.isBlank(value.toString())) { + oldName = value.toString(); + } + editorComp = prepareEditor(editor, index); + if (editorComp == null) { + return false; + } + Rectangle rect = this.getCellBounds(index, index); + // alex:所有的UINameEdList都有Icon,空出前面20 * 20的位置就是放的Icon + rect.setRect(createRect(rect, BUTTON_WIDTH)); + + editorComp.setBounds(rect); + add(editorComp); + editorComp.validate(); + editorComp.requestFocus(); + if (editorComp instanceof UITextField) { + ((UITextField) editorComp).selectAll(); + } + + setEditingIndex(index); + + return true; + } + + public Rectangle createRect(Rectangle rect, int iconWidth) { + return new Rectangle(rect.x + iconWidth, rect.y, rect.width - iconWidth, rect.height); + } + + public String getEditingName() { + return (String) getCellEditor().getCellEditorValue(); + } + + /* + * 根据ListCellEditor取得编辑器的Component + */ + private Component prepareEditor(ListCellEditor cellEditor, int index) { + String name = getNameAt(index); + boolean isSelected = this.isSelectedIndex(index); + Component comp = cellEditor.getListCellEditorComponent(this, name, isSelected, index); + + return comp; + } + + /* + * 记录正在编辑的index + */ + private void setEditingIndex(int idx) { + editingIndex = idx; + } + + /** + * 编辑取消 + * + * @param e 事件 + */ + public void editingCanceled(ChangeEvent e) { + removeComp(); + } + + /** + * 编辑结束 + * + * @param e 事件 + */ + public void editingStopped(ChangeEvent e) { + doAfterLostFocus(); + stopEditing(); + } + + /** + * 停止编辑事件 + */ + public void stopEditing() { + ListCellEditor editor = getCellEditor(); + if (editor != null && editorComp != null) { + Object value = editor.getCellEditorValue(); + String name = StringUtils.isBlank(value.toString()) ? oldName : value.toString(); + setNameAt(name, editingIndex); + removeComp(); + } + } + + public String[] getAllNames() { + int length = this.getModel().getSize(); + String[] names = new String[length]; + for (int i = 0; i < length; i++) { + names[i] = getNameAt(i); + } + return names; + } + + public Object[] getAllTypes() { + int length = this.getModel().getSize(); + Object[] types = new Object[length]; + for (int i = 0; i < length; i++) { + types[i] = getType(i); + } + return types; + } + + + /* + * 移除编辑器的Component + */ + private void removeComp() { + if (editorComp != null) { + remove(editorComp); + } + Rectangle cellRect = this.getCellBounds(editingIndex, editingIndex); + setEditingIndex(-1); + editorComp = null; + repaint(cellRect); + } + + /** + * 主函数 + * + * @param args 参数 + */ + public static void main(String... args) { + JFrame f = new JFrame(); + JPanel c = (JPanel) f.getContentPane(); + c.setLayout(new BorderLayout()); + ListModelElement[] data = new ListModelElement[TEST_LIST_LENTH]; + for (int i = 0; i < TEST_LIST_LENTH; i++) { + data[i] = new ListModelElement(new NameObject(i + 1 + "", i)); + } + final UINameEdList list = new UINameEdList(data); + list.setEditable(true); + list.addMouseListener(new MouseAdapter() { + public void mouseReleased(MouseEvent evt) { + list.stopEditing(); + if (evt.getClickCount() >= 2 + && SwingUtilities.isLeftMouseButton(evt)) { + list.editItemAt(list.getSelectedIndex()); + } + } + }) + ; + + list.setCellEditor(new DefaultListCellEditor(new UITextField())); + list.setCellRenderer(new NameableListCellRenderer()); + c.add(list, BorderLayout.CENTER); + f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + f.setSize(400, 600); + f.setVisible(true); + } + + private static class NameableListCellRenderer extends DefaultListCellRenderer { + @Override + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, + boolean cellHasFocus) { + super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + + if (value instanceof Nameable) { + Nameable wrappee = (Nameable) value; + this.setText(wrappee.getName()); + } + return this; + } + } + +} \ No newline at end of file From 05451d24a6422e6600dd2333774e0a44fecd064d Mon Sep 17 00:00:00 2001 From: plough Date: Mon, 24 Jul 2017 10:52:44 +0800 Subject: [PATCH 5/6] =?UTF-8?q?REPORT-3163=20=E5=90=88=E4=BD=9C=E5=BC=80?= =?UTF-8?q?=E5=8F=919.0=E8=AE=BE=E8=AE=A1=E5=99=A8=3D>=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E9=9D=A2=E6=9D=BF=E5=BC=B9=E5=87=BA=E7=BC=96=E8=BE=91=E6=A1=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/fr/design/gui/controlpane/UIControlPane.java | 5 ++++- .../fr/design/gui/controlpane/UIListControlPane.java | 11 ++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/designer_base/src/com/fr/design/gui/controlpane/UIControlPane.java b/designer_base/src/com/fr/design/gui/controlpane/UIControlPane.java index b21b740f5..4de5f5d86 100644 --- a/designer_base/src/com/fr/design/gui/controlpane/UIControlPane.java +++ b/designer_base/src/com/fr/design/gui/controlpane/UIControlPane.java @@ -236,14 +236,17 @@ public abstract class UIControlPane extends BasicPane implements UnrepeatedNameH // 点击"编辑"按钮,弹出面板 protected class PopupEditPane extends JPopupMenu { private JComponent contentPane; + private static final int WIDTH = 460; + private static final int HEIGHT = 500; // private PopupToolPane popupToolPane; - private int fixedHeight; +// private int fixedHeight; PopupEditPane(JComponent pane) { contentPane = pane; this.setLayout(new BorderLayout()); this.add(contentPane, BorderLayout.CENTER); this.setOpaque(false); + contentPane.setPreferredSize(new Dimension(WIDTH, HEIGHT)); // fixedHeight = getPreferredSize().height - contentPane.getPreferredSize().height; // updateSize(); } diff --git a/designer_base/src/com/fr/design/gui/controlpane/UIListControlPane.java b/designer_base/src/com/fr/design/gui/controlpane/UIListControlPane.java index 878668f0d..a6131b3ed 100644 --- a/designer_base/src/com/fr/design/gui/controlpane/UIListControlPane.java +++ b/designer_base/src/com/fr/design/gui/controlpane/UIListControlPane.java @@ -47,6 +47,7 @@ import java.util.Comparator; public abstract class UIListControlPane extends UIControlPane { public static final String LIST_NAME = "UIControl_List"; + private static final int EDIT_RANGE = 20; // 编辑按钮的x坐标范围 protected UINameEdList nameableList; protected int editingIndex; @@ -356,6 +357,11 @@ public abstract class UIListControlPane extends UIControlPane { } } + private void popupEditPane() { + GUICoreUtils.showPopupMenu(popupEditPane, this, + - popupEditPane.getPreferredSize().width, nameableList.getSelectedIndex() * EDIT_RANGE); + } + /** * 增加项的UpdateAction */ @@ -638,11 +644,14 @@ public abstract class UIListControlPane extends UIControlPane { public void mouseReleased(MouseEvent evt) { nameableList.stopEditing(); if (evt.getClickCount() >= 2 - && SwingUtilities.isLeftMouseButton(evt)) { + && 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) { + popupEditPane(); } + // peter:处理右键的弹出菜单 if (!SwingUtilities.isRightMouseButton(evt)) { return; From 18c5fc394181f4604cd3f202e237988f7f898f55 Mon Sep 17 00:00:00 2001 From: plough Date: Mon, 24 Jul 2017 15:08:05 +0800 Subject: [PATCH 6/6] =?UTF-8?q?REPORT-3163=20=E5=90=88=E4=BD=9C=E5=BC=80?= =?UTF-8?q?=E5=8F=919.0=E8=AE=BE=E8=AE=A1=E5=99=A8=3D>=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E9=9D=A2=E6=9D=BF=3D=E3=80=8B=E5=AE=8C=E5=96=84UI=E7=BB=86?= =?UTF-8?q?=E8=8A=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../design/gui/controlpane/UIControlPane.java | 11 +++++- .../gui/controlpane/UIListControlPane.java | 24 +++++++++++- .../UINameableListCellRenderer.java | 37 ++++++++++--------- .../com/fr/design/gui/ilist/UINameEdList.java | 2 +- 4 files changed, 52 insertions(+), 22 deletions(-) diff --git a/designer_base/src/com/fr/design/gui/controlpane/UIControlPane.java b/designer_base/src/com/fr/design/gui/controlpane/UIControlPane.java index 4de5f5d86..8878cd43a 100644 --- a/designer_base/src/com/fr/design/gui/controlpane/UIControlPane.java +++ b/designer_base/src/com/fr/design/gui/controlpane/UIControlPane.java @@ -110,6 +110,7 @@ public abstract class UIControlPane extends BasicPane implements UnrepeatedNameH // mainSplitPane.setOneTouchExpandable(true); this.add(getLeftPane(), BorderLayout.CENTER); + this.setBorder(BorderFactory.createEmptyBorder(0, 10, 12, 10)); // mainSplitPane.setDividerLocation(getLeftPreferredSize()); this.checkButtonEnabled(); } @@ -134,14 +135,21 @@ public abstract class UIControlPane extends BasicPane implements UnrepeatedNameH toolbarDef.addShortCut(sj.getShortCut()); } toolBar = ToolBarDef.createJToolBar(); +// toolBar.setLayout(new FlowLayout(FlowLayout.LEFT)); toolbarDef.updateToolBar(toolBar); - leftContentPane.add(toolBar, BorderLayout.NORTH); + // 封装一层,加边框 + JPanel toolBarPane = new JPanel(new BorderLayout()); + toolBarPane.add(toolBar, BorderLayout.CENTER); + toolBarPane.setBorder(BorderFactory.createMatteBorder(1, 1, 0, 1, new Color(201, 198, 184))); + leftContentPane.add(toolBarPane, BorderLayout.NORTH); +// leftContentPane.setBorder(BorderFactory.createLineBorder(new Color(201, 198, 184))); // 顶部标签及add按钮 UIToolbar topToolBar = new UIToolbar(); topToolBar.setLayout(new BorderLayout()); ShortCut addItem = addItemShortCut().getShortCut(); addItem.intoJToolBar(topToolBar); + topToolBar.setBorder(BorderFactory.createEmptyBorder(2, 0, 2, 0)); double p = TableLayout.PREFERRED; double f = TableLayout.FILL; double[] columnSize = { p, f }; @@ -150,6 +158,7 @@ public abstract class UIControlPane extends BasicPane implements UnrepeatedNameH new Component[]{new UILabel("add hyperlink "), topToolBar}, }; JPanel leftTopPane = TableLayoutHelper.createTableLayoutPane(components,rowSize,columnSize); + leftTopPane.setBorder(BorderFactory.createEmptyBorder(0, 0, 6, 0)); leftPane.add(leftTopPane, BorderLayout.NORTH); return leftPane; diff --git a/designer_base/src/com/fr/design/gui/controlpane/UIListControlPane.java b/designer_base/src/com/fr/design/gui/controlpane/UIListControlPane.java index a6131b3ed..c082f6698 100644 --- a/designer_base/src/com/fr/design/gui/controlpane/UIListControlPane.java +++ b/designer_base/src/com/fr/design/gui/controlpane/UIListControlPane.java @@ -9,6 +9,7 @@ import com.fr.design.data.tabledata.tabledatapane.GlobalTreeTableDataPane; import com.fr.design.data.tabledata.tabledatapane.MultiTDTableDataPane; import com.fr.design.data.tabledata.tabledatapane.TreeTableDataPane; import com.fr.design.file.HistoryTemplateListPane; +import com.fr.design.gui.ibutton.UIButton; import com.fr.design.gui.icontainer.UIScrollPane; import com.fr.design.gui.ilist.UINameEdList; import com.fr.design.gui.ilist.ListModelElement; @@ -47,7 +48,7 @@ import java.util.Comparator; public abstract class UIListControlPane extends UIControlPane { public static final String LIST_NAME = "UIControl_List"; - private static final int EDIT_RANGE = 20; // 编辑按钮的x坐标范围 + private static final int EDIT_RANGE = 25; // 编辑按钮的x坐标范围 protected UINameEdList nameableList; protected int editingIndex; @@ -358,8 +359,11 @@ public abstract class UIListControlPane extends UIControlPane { } private void popupEditPane() { + if (editingIndex < 0) { + return; + } GUICoreUtils.showPopupMenu(popupEditPane, this, - - popupEditPane.getPreferredSize().width, nameableList.getSelectedIndex() * EDIT_RANGE); + - popupEditPane.getPreferredSize().width, editingIndex * EDIT_RANGE); } /** @@ -394,6 +398,21 @@ public abstract class UIListControlPane extends UIControlPane { wrapActionListener(creators); } + /** + * 生成UIButton + * @return 菜单按钮 + */ + public UIButton createUIButton() { + createdButton = super.createUIButton(); + // 此按钮单独抽出,不应使用工具栏外观 + if (!createdButton.isOpaque()) { + createdButton.setOpaque(true); + createdButton.setNormalPainted(true); + createdButton.setBorderPaintedOnlyWhenPressed(false); + } + return createdButton; + } + private void wrapActionListener(NameableCreator[] creators) { for (final NameableCreator creator : creators) { if (!whetherAdd(creator.menuName())) { @@ -649,6 +668,7 @@ public abstract class UIListControlPane extends UIControlPane { selectedName = nameableList.getNameAt(editingIndex); nameableList.editItemAt(nameableList.getSelectedIndex()); } else if (SwingUtilities.isLeftMouseButton(evt) && evt.getX() <= EDIT_RANGE) { + editingIndex = nameableList.getSelectedIndex(); popupEditPane(); } diff --git a/designer_base/src/com/fr/design/gui/controlpane/UINameableListCellRenderer.java b/designer_base/src/com/fr/design/gui/controlpane/UINameableListCellRenderer.java index e8844d385..e56b03807 100644 --- a/designer_base/src/com/fr/design/gui/controlpane/UINameableListCellRenderer.java +++ b/designer_base/src/com/fr/design/gui/controlpane/UINameableListCellRenderer.java @@ -25,8 +25,9 @@ public class UINameableListCellRenderer extends JPanel implements ListCellRenderer { private static final Border SAFE_NO_FOCUS_BORDER = new EmptyBorder(1, 1, 1, 1); private static final Border DEFAULT_NO_FOCUS_BORDER = new EmptyBorder(1, 1, 1, 1); + private static final Color BORDER_COLOR = new Color(201, 198, 184); protected static Border noFocusBorder = DEFAULT_NO_FOCUS_BORDER; - private static final int BUTTON_WIDTH = 20; + private static final int BUTTON_WIDTH = 25; private UILabel editButton; // "编辑按钮",实际上是一个 UILabel,由列表项(UIListControlPane)统一处理点击事件 private UILabel label; private UIListControlPane listControlPane; @@ -48,6 +49,8 @@ public class UINameableListCellRenderer extends }; // editButton.set4LargeToolbarButton(); editButton.setIcon(BaseUtils.readIcon("/com/fr/base/images/cell/control/add.png")); + editButton.setBorder(BorderFactory.createMatteBorder(0, 0, 0, 1, BORDER_COLOR)); + editButton.setHorizontalAlignment(SwingConstants.CENTER); // editButton.addActionListener(new ActionListener() { // @Override // public void actionPerformed(ActionEvent e) { @@ -55,30 +58,28 @@ public class UINameableListCellRenderer extends // } // }); label = new UILabel(); + label.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 0)); // label.setEditable(false); this.setLayout(new BorderLayout()); this.add(editButton, BorderLayout.WEST); this.add(label, BorderLayout.CENTER); } - private void popupEditPane() { - GUICoreUtils.showPopupMenu(listControlPane.popupEditPane, editButton, - - listControlPane.popupEditPane.getPreferredSize().width, 0); - } - private Border getNoFocusBorder() { - Border border = DefaultLookup.getBorder(this, ui, "List.cellNoFocusBorder"); - if (System.getSecurityManager() != null) { - if (border != null) return border; - return SAFE_NO_FOCUS_BORDER; - } else { - if (border != null && - (noFocusBorder == null || - noFocusBorder == DEFAULT_NO_FOCUS_BORDER)) { - return border; - } - return noFocusBorder; - } +// return BorderFactory.createLineBorder(new Color(201, 198, 184)); + return BorderFactory.createMatteBorder(0, 0, 1, 0, BORDER_COLOR); + // Border border = DefaultLookup.getBorder(this, ui, "List.cellNoFocusBorder"); +// if (System.getSecurityManager() != null) { +// if (border != null) return border; +// return SAFE_NO_FOCUS_BORDER; +// } else { +// if (border != null && +// (noFocusBorder == null || +// noFocusBorder == DEFAULT_NO_FOCUS_BORDER)) { +// return border; +// } +// return noFocusBorder; +// } } private void setText(String t) { diff --git a/designer_base/src/com/fr/design/gui/ilist/UINameEdList.java b/designer_base/src/com/fr/design/gui/ilist/UINameEdList.java index 73ba2bf82..823c95d6e 100644 --- a/designer_base/src/com/fr/design/gui/ilist/UINameEdList.java +++ b/designer_base/src/com/fr/design/gui/ilist/UINameEdList.java @@ -24,7 +24,7 @@ import java.util.Vector; */ public class UINameEdList extends UIList implements CellEditorListener { private static final int TEST_LIST_LENTH = 20; - private static final int BUTTON_WIDTH = 20; + private static final int BUTTON_WIDTH = 25; private boolean editable = true; // kunsnat: 是否强制ListName是数字 (int型)