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 f67512d92f..b21b740f5a 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 c36a7902c2..878668f0d0 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 df672e8a1d..e8844d3856 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 0000000000..73ba2bf82c --- /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