diff --git a/designer-base/src/com/fr/design/ExtraDesignClassManager.java b/designer-base/src/com/fr/design/ExtraDesignClassManager.java index 179251539..bfef815c8 100644 --- a/designer-base/src/com/fr/design/ExtraDesignClassManager.java +++ b/designer-base/src/com/fr/design/ExtraDesignClassManager.java @@ -17,10 +17,11 @@ import com.fr.design.gui.core.WidgetOption; import com.fr.design.gui.core.WidgetOptionFactory; import com.fr.design.menu.ShortCut; import com.fr.design.widget.Appearance; +import com.fr.design.widget.mobile.WidgetMobilePane; import com.fr.form.ui.Widget; +import com.fr.general.FRLogger; import com.fr.general.GeneralUtils; import com.fr.general.IOUtils; -import com.fr.log.FineLoggerFactory; import com.fr.plugin.AbstractExtraClassManager; import com.fr.plugin.injectable.PluginModule; import com.fr.plugin.injectable.PluginSingleInjection; @@ -41,24 +42,24 @@ import java.util.Set; * 用于设计器扩展的管理类 */ public class ExtraDesignClassManager extends AbstractExtraClassManager implements ExtraDesignClassManagerProvider { - + private static ExtraDesignClassManager classManager = new ExtraDesignClassManager(); - + private Set shortCuts = new CloseableContainedSet<>(HashSet.class); - + public synchronized static ExtraDesignClassManager getInstance() { return classManager; } - + static { PluginModule.registerAgent(PluginModule.ExtraDesign, classManager); } - + public TableDataNameObjectCreator[] getReportTableDataCreators() { return getKindsOfTableDataCreators(TableDataDefineProvider.XML_TAG); } - - + + /** * 添加serverTDCreators * @@ -67,7 +68,7 @@ public class ExtraDesignClassManager extends AbstractExtraClassManager implement public TableDataNameObjectCreator[] getServerTableDataCreators() { return getKindsOfTableDataCreators(ServerTableDataDefineProvider.XML_TAG); } - + private TableDataNameObjectCreator[] getKindsOfTableDataCreators(String tag) { Set set = getArray(tag); if (set.isEmpty()) { @@ -76,19 +77,19 @@ public class ExtraDesignClassManager extends AbstractExtraClassManager implement List creators = new ArrayList<>(); for (TableDataDefineProvider provider : set) { TableDataNameObjectCreator creator = new TableDataNameObjectCreator( - provider.nameForTableData(), - provider.prefixForTableData(), - provider.iconPathForTableData(), - provider.classForTableData(), - provider.classForInitTableData(), - provider.appearanceForTableData() + provider.nameForTableData(), + provider.prefixForTableData(), + provider.iconPathForTableData(), + provider.classForTableData(), + provider.classForInitTableData(), + provider.appearanceForTableData() ); creators.add(creator); } return creators.toArray(new TableDataNameObjectCreator[creators.size()]); } - - + + public Map, Class> getParameterWidgetOptionsMap() { Map, Class> map = new HashMap<>(); Set set = getArray(ParameterWidgetOptionProvider.XML_TAG); @@ -97,7 +98,7 @@ public class ExtraDesignClassManager extends AbstractExtraClassManager implement } return map; } - + public WidgetOption[] getParameterWidgetOptions() { Set set = getArray(ParameterWidgetOptionProvider.XML_TAG); if (set.isEmpty()) { @@ -106,16 +107,16 @@ public class ExtraDesignClassManager extends AbstractExtraClassManager implement Set result = new HashSet<>(); for (ParameterWidgetOptionProvider provider : set) { WidgetOption option = WidgetOptionFactory.createByWidgetClass( - provider.nameForWidget(), - IOUtils.readIcon(provider.iconPathForWidget()), - provider.classForWidget() + provider.nameForWidget(), + IOUtils.readIcon(provider.iconPathForWidget()), + provider.classForWidget() ); result.add(option); } return result.toArray(new WidgetOption[result.size()]); } - - + + public WidgetOption[] getWebWidgetOptions() { Set set = getArray(ToolbarItemProvider.XML_TAG); if (set.isEmpty()) { @@ -124,17 +125,17 @@ public class ExtraDesignClassManager extends AbstractExtraClassManager implement List list = new ArrayList<>(); for (ToolbarItemProvider provider : set) { WidgetOption option = WidgetOptionFactory.createByWidgetClass( - provider.nameForWidget(), - IOUtils.readIcon(provider.iconPathForWidget()), - provider.classForWidget() + provider.nameForWidget(), + IOUtils.readIcon(provider.iconPathForWidget()), + provider.classForWidget() ); list.add(option); } return list.toArray(new WidgetOption[list.size()]); } - - - + + + public Map, Class> getFormWidgetOptionsMap() { Set set = getArray(FormWidgetOptionProvider.XML_TAG); Map, Class> map = new HashMap<>(); @@ -143,15 +144,15 @@ public class ExtraDesignClassManager extends AbstractExtraClassManager implement } return map; } - + public WidgetOption[] getFormWidgetOptions() { return getFormUnits(false); } - + public WidgetOption[] getFormWidgetContainerOptions() { return getFormUnits(true); } - + private WidgetOption[] getFormUnits(boolean isContainer) { Set set = getArray(FormWidgetOptionProvider.XML_TAG); if (set.isEmpty()) { @@ -161,18 +162,18 @@ public class ExtraDesignClassManager extends AbstractExtraClassManager implement for (FormWidgetOptionProvider provider : set) { if (provider.isContainer() == isContainer) { WidgetOption option = WidgetOptionFactory.createByWidgetClass( - provider.nameForWidget(), - BaseUtils.readIcon(provider.iconPathForWidget()), - provider.classForWidget() + provider.nameForWidget(), + BaseUtils.readIcon(provider.iconPathForWidget()), + provider.classForWidget() ); result.add(option); } } return result.toArray(new WidgetOption[result.size()]); } - - - + + + public WidgetOption[] getCellWidgetOptions() { Set set = getArray(CellWidgetOptionProvider.XML_TAG); if (set.isEmpty()) { @@ -181,16 +182,16 @@ public class ExtraDesignClassManager extends AbstractExtraClassManager implement Set result = new HashSet<>(); for (CellWidgetOptionProvider provider : set) { WidgetOption option = WidgetOptionFactory.createByWidgetClass( - provider.nameForWidget(), - IOUtils.readIcon(provider.iconPathForWidget()), - provider.classForWidget() + provider.nameForWidget(), + IOUtils.readIcon(provider.iconPathForWidget()), + provider.classForWidget() ); result.add(option); } return result.toArray(new WidgetOption[result.size()]); - + } - + public Map, Appearance> getCellWidgetOptionsMap() { Set set = getArray(CellWidgetOptionProvider.XML_TAG); Map, Appearance> map = new HashMap<>(); @@ -199,8 +200,17 @@ public class ExtraDesignClassManager extends AbstractExtraClassManager implement } return map; } - - + + public Map, Class> getCellWidgetMobileOptionsMap() { + Set set = getArray(CellWidgetOptionProvider.XML_TAG); + Map, Class> map = new HashMap<>(); + for (CellWidgetOptionProvider provider : set) { + map.put(provider.classForWidget(), provider.classForMobilePane()); + } + return map; + } + + public Feedback getFeedback() { try { Class clazz = GeneralUtils.classForName("com.fr.design.feedback.CurrentFeedback"); @@ -208,33 +218,33 @@ public class ExtraDesignClassManager extends AbstractExtraClassManager implement return (Feedback) clazz.newInstance(); } } catch (Exception e) { - FineLoggerFactory.getLogger().info("no feed back support"); + FRLogger.getLogger().info("no feed back support"); } return Feedback.EMPTY; } - + @Override protected boolean demountSpecific(PluginSingleInjection injection) { - + if (ShortCut.TEMPLATE_TREE.equals(injection.getName()) && injection.getObject() instanceof ShortCut) { shortCuts.remove(injection.getObject()); return true; } return false; } - + @Override protected boolean mountSpecific(PluginSingleInjection injection) { - + if (ShortCut.TEMPLATE_TREE.equals(injection.getName()) && injection.getObject() instanceof ShortCut) { shortCuts.add((ShortCut) injection.getObject()); return true; } return false; } - + public Set getExtraShortCuts() { - + return Collections.unmodifiableSet(shortCuts); } } \ No newline at end of file diff --git a/designer-form/src/com/fr/design/designer/properties/items/Item.java b/designer-base/src/com/fr/design/designer/properties/items/Item.java similarity index 92% rename from designer-form/src/com/fr/design/designer/properties/items/Item.java rename to designer-base/src/com/fr/design/designer/properties/items/Item.java index 31ae4a070..6cba90e41 100644 --- a/designer-form/src/com/fr/design/designer/properties/items/Item.java +++ b/designer-base/src/com/fr/design/designer/properties/items/Item.java @@ -24,7 +24,7 @@ public class Item { } @Override - public boolean equals(Object o) { + public boolean equals(Object o) { if (o == null) { return false; } @@ -32,7 +32,7 @@ public class Item { Item a = (Item) o; Object av = a.getValue(); if (value == null) { - return av == null; + return av == null; } else { if (av == null) { return false; diff --git a/designer-base/src/com/fr/design/fun/CellWidgetOptionProvider.java b/designer-base/src/com/fr/design/fun/CellWidgetOptionProvider.java index 1cb7869d7..e22b68146 100644 --- a/designer-base/src/com/fr/design/fun/CellWidgetOptionProvider.java +++ b/designer-base/src/com/fr/design/fun/CellWidgetOptionProvider.java @@ -1,6 +1,7 @@ package com.fr.design.fun; import com.fr.design.beans.BasicBeanPane; +import com.fr.design.widget.mobile.WidgetMobilePane; import com.fr.form.ui.Widget; import com.fr.stable.fun.Level; @@ -20,4 +21,10 @@ public interface CellWidgetOptionProvider extends ParameterWidgetOptionProvider */ Class> appearanceForWidget(); + /** + * 自定义格子控件的移动端界面类 + * @return 控件移动端界面类 + */ + Class classForMobilePane(); + } \ No newline at end of file diff --git a/designer-base/src/com/fr/design/gui/controlpane/UISimpleListControlPane.java b/designer-base/src/com/fr/design/gui/controlpane/UISimpleListControlPane.java new file mode 100644 index 000000000..a07e4c2ce --- /dev/null +++ b/designer-base/src/com/fr/design/gui/controlpane/UISimpleListControlPane.java @@ -0,0 +1,483 @@ +package com.fr.design.gui.controlpane; + +import com.fr.base.BaseUtils; +import com.fr.design.actions.UpdateAction; +import com.fr.design.constants.UIConstants; +import com.fr.design.dialog.BasicPane; +import com.fr.design.gui.icontainer.UIScrollPane; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.gui.ilist.ListModelElement; +import com.fr.design.gui.ilist.UIList; +import com.fr.design.gui.itoolbar.UIToolBarUI; +import com.fr.design.gui.itoolbar.UIToolbar; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.menu.ShortCut; +import com.fr.design.menu.ToolBarDef; +import com.fr.general.ComparatorUtils; +import com.fr.general.Inter; +import com.fr.stable.ArrayUtils; +import com.fr.stable.Nameable; +import com.fr.stable.StringUtils; +import sun.swing.DefaultLookup; + +import javax.swing.BorderFactory; +import javax.swing.DefaultListModel; +import javax.swing.JComponent; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.ListCellRenderer; +import javax.swing.ListSelectionModel; +import javax.swing.border.Border; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Point; +import java.awt.Toolkit; +import java.awt.event.ActionEvent; +import java.awt.event.InputEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.util.Arrays; +import java.util.Comparator; + +/** + * 简单列表面板 + * Created by plough on 2018/2/1. + */ +public class UISimpleListControlPane extends BasicPane { + public static final String LIST_NAME = "UISimpleControl_List"; + + protected UIList nameList; + protected String selectedName; + private ShortCut4JControlPane[] shorts; + private ToolBarDef toolbarDef; + private UIToolbar toolBar; + + public UISimpleListControlPane() { + initComponentPane(); + } + + public ShortCut4JControlPane[] getShorts() { + return shorts; + } + + protected void initComponentPane() { + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + this.add(getContentPane(), BorderLayout.CENTER); + this.checkButtonEnabled(); + } + + protected JPanel getContentPane() { + JPanel contentPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + + JPanel listPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + initListPane(listPane); + contentPane.add(listPane, BorderLayout.CENTER); + + shorts = this.createShortcuts(); + if (ArrayUtils.isEmpty(shorts)) { + return contentPane; + } + + toolbarDef = new ToolBarDef(); + for (ShortCut4JControlPane sj : shorts) { + toolbarDef.addShortCut(sj.getShortCut()); + } + toolBar = ToolBarDef.createJToolBar(); + toolBar.setUI(new UIToolBarUI(){ + @Override + public void paint(Graphics g, JComponent c) { + Graphics2D g2 = (Graphics2D) g; + g2.setColor(Color.WHITE); + g2.fillRect(0, 0, c.getWidth(), c.getHeight()); + } + }); + toolbarDef.updateToolBar(toolBar); + // 封装一层,加边框 + JPanel toolBarPane = new JPanel(new BorderLayout()); + toolBarPane.add(toolBar, BorderLayout.CENTER); + toolBarPane.setBorder(BorderFactory.createMatteBorder(1, 1, 0, 1, UIConstants.RULER_LINE_COLOR)); + + listPane.add(toolBarPane, BorderLayout.NORTH); + + return contentPane; + } + + protected ShortCut4JControlPane[] createShortcuts() { + return new ShortCut4JControlPane[]{ + moveUpItemShortCut(), + moveDownItemShortCut(), + sortItemShortCut(), + }; + } + + protected void initListPane(JPanel listPane) { + nameList = createJNameList(); + nameList.setName(LIST_NAME); + nameList.setSelectionBackground(UIConstants.ATTRIBUTE_PRESS); + listPane.add(new UIScrollPane(nameList), BorderLayout.CENTER); + + + nameList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); + nameList.addMouseListener(listMouseListener); + nameList.addListSelectionListener(new ListSelectionListener() { + public void valueChanged(ListSelectionEvent evt) { + // richie:避免多次update和populate大大降低效率 + if (!evt.getValueIsAdjusting()) { + UISimpleListControlPane.this.checkButtonEnabled(); + } + } + }); + } + + public UIList createJNameList() { + UIList nameList = new UIList(new DefaultListModel()) { + @Override + public int locationToIndex(Point location) { + int index = super.locationToIndex(location); + if (index != -1 && !getCellBounds(index, index).contains(location)) { + return -1; + } + else { + return index; + } + } + }; + nameList.setCellRenderer(new NameableListCellRenderer(this)); + return nameList; + } + + protected ShortCut4JControlPane moveUpItemShortCut() { + return new NormalEnableShortCut(new MoveUpItemAction()); + } + + protected ShortCut4JControlPane moveDownItemShortCut() { + return new NormalEnableShortCut(new MoveDownItemAction()); + } + + protected ShortCut4JControlPane sortItemShortCut() { + return new NormalEnableShortCut(new SortItemAction()); + } + + public Nameable[] update() { + java.util.List res = new java.util.ArrayList(); + DefaultListModel listModel = (DefaultListModel) this.nameList.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()]); + } + + public void populate(Nameable[] nameableArray) { + DefaultListModel listModel = (DefaultListModel) this.nameList.getModel(); + listModel.removeAllElements(); + if (ArrayUtils.isEmpty(nameableArray)) { + return; + } + + listModel.setSize(nameableArray.length); + for (int i = 0; i < nameableArray.length; i++) { + listModel.set(i, new ListModelElement(nameableArray[i])); + } + if (listModel.size() > 0 || this.nameList.getSelectedIndex() != 0) { + this.nameList.setSelectedIndex(0); + } + this.checkButtonEnabled(); + } + + /** + * 根据name,选中UINameEdList中的item + */ + public void setSelectedName(String name) { + DefaultListModel listModel = (DefaultListModel) this.nameList.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.nameList.setSelectedIndex(i); + break; + } + } + } + + /** + * 获取选中的名字 + */ + public String getSelectedName() { + ListModelElement el = (ListModelElement) this.nameList.getSelectedValue(); + + return el == null ? null : el.wrapper.getName(); + } + + protected DefaultListModel getModel() { + return (DefaultListModel) this.nameList.getModel(); + } + + @Override + protected String title4PopupWindow() { + return null; + } + + /* + * 上移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 = nameList.getSelectedIndex(); + if (selectedIndex == -1) { + return; + } + + // 上移 + if (selectedIndex > 0) { + DefaultListModel listModel = (DefaultListModel) nameList.getModel(); + + Object prevObj = listModel.get(selectedIndex - 1); + Object currentObj = listModel.get(selectedIndex); + listModel.set(selectedIndex - 1, currentObj); + listModel.set(selectedIndex, prevObj); + + nameList.setSelectedIndex(selectedIndex - 1); + nameList.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 = nameList.getSelectedIndex(); + if (selectedIndex == -1) { + return; + } + + if (selectedIndex < nameList.getModel().getSize() - 1) { + DefaultListModel listModel = (DefaultListModel) nameList.getModel(); + + Object nextObj = listModel.get(selectedIndex + 1); + Object currentObj = listModel.get(selectedIndex); + listModel.set(selectedIndex + 1, currentObj); + listModel.set(selectedIndex, nextObj); + + nameList.setSelectedIndex(selectedIndex + 1); + nameList.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 = nameList.getSelectedValue(); + + DefaultListModel listModel = (DefaultListModel) nameList.getModel(); + if (listModel.getSize() <= 0) { + return; + } + Nameable[] nameableArray = new Nameable[listModel.getSize()]; + + 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(o2.getName(), o1.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) { + nameList.setSelectedValue(selectedValue, true); + } + + checkButtonEnabled(); + // p:需要repaint. + nameList.repaint(); + } + } + + /* + * UIList的鼠标事件 + */ + private MouseListener listMouseListener = new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + JList list = (JList) e.getSource(); + if (list.locationToIndex(e.getPoint()) == -1 && !e.isShiftDown() + && !isMenuShortcutKeyDown(e)) { + list.clearSelection(); + } + } + + private boolean isMenuShortcutKeyDown(InputEvent event) { + return (event.getModifiers() & Toolkit.getDefaultToolkit() + .getMenuShortcutKeyMask()) != 0; + } + }; + + /** + * 检查按钮可用状态 Check button enabled. + */ + public void checkButtonEnabled() { + for (ShortCut4JControlPane sj : getShorts()) { + sj.checkEnable(); + } + } + + /** + * 设置选中项 + * + * @param index 选中项的序列号 + */ + public void setSelectedIndex(int index) { + nameList.setSelectedIndex(index); + } + + + public class NormalEnableShortCut extends ShortCut4JControlPane { + public NormalEnableShortCut(ShortCut shortCut) { + this.shortCut = shortCut; + } + + /** + * 检查是否可用 + */ + @Override + public void checkEnable() { + this.shortCut.setEnabled(getModel() + .getSize() > 0 + && UISimpleListControlPane.this.nameList.getSelectedIndex() != -1); + } + } + + + private class NameableListCellRenderer extends + JPanel implements ListCellRenderer { + + private UILabel label; + private UISimpleListControlPane listControlPane; + private Color initialLabelForeground; + + public NameableListCellRenderer(UISimpleListControlPane listControlPane) { + super(); + this.listControlPane = listControlPane; + initComponents(); + setOpaque(true); + setBorder(getNoFocusBorder()); + setName("List.cellRenderer"); + } + + private void initComponents() { + label = new UILabel(); + label.setBorder(BorderFactory.createEmptyBorder(3, 10, 3, 0)); + initialLabelForeground = label.getForeground(); + this.setLayout(new BorderLayout()); + this.add(label, BorderLayout.CENTER); + } + + private Border getNoFocusBorder() { + return BorderFactory.createMatteBorder(0, 0, 1, 0, UIConstants.LIST_ITEM_SPLIT_LINE); + } + + 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); + label.setForeground(Color.WHITE); + } + else { + setBackground(list.getBackground()); + setForeground(list.getForeground()); + label.setForeground(initialLabelForeground); + } + + setText((value == null) ? StringUtils.EMPTY : value.toString()); + + setEnabled(list.isEnabled()); + setFont(list.getFont()); + + if (value instanceof ListModelElement) { + Nameable wrappee = ((ListModelElement) value).wrapper; + this.setText(wrappee.getName()); + } + + return this; + } + } +} diff --git a/designer-base/src/com/fr/design/widget/mobile/WidgetMobilePane.java b/designer-base/src/com/fr/design/widget/mobile/WidgetMobilePane.java new file mode 100644 index 000000000..392b4b500 --- /dev/null +++ b/designer-base/src/com/fr/design/widget/mobile/WidgetMobilePane.java @@ -0,0 +1,47 @@ +package com.fr.design.widget.mobile; + +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.form.ui.Widget; +import com.fr.general.Inter; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.SwingConstants; + +/** + * 单元格控件的"移动端"面板。默认显示"无可用配置项",在子类中扩展 + * Created by plough on 2018/4/25. + */ +public class WidgetMobilePane extends JPanel { + public static WidgetMobilePane DEFAULT_PANE = new WidgetMobilePane(); + + public WidgetMobilePane() { + this.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); + init(); + } + + protected void init() { + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + UILabel label = new UILabel(Inter.getLocText("FR-Designer_No_Settings_Available")); + label.setHorizontalAlignment(SwingConstants.CENTER); + this.add(label); + } + + /** + * 从 widget 中提取数据展示在属性面板中 + * + * @param widget + */ + public void populate(Widget widget) { + // do nothing + } + + /** + * 从属性面板把数据保存到 widget 中 + * @param widget + */ + public void update(Widget widget) { + // do nothing + } +} diff --git a/designer-form/src/com/fr/design/designer/creator/XElementCase.java b/designer-form/src/com/fr/design/designer/creator/XElementCase.java index 0ca67aabf..05f301159 100644 --- a/designer-form/src/com/fr/design/designer/creator/XElementCase.java +++ b/designer-form/src/com/fr/design/designer/creator/XElementCase.java @@ -349,4 +349,12 @@ public class XElementCase extends XBorderStyleWidgetCreator implements FormEleme public boolean supportSetEnable(){ return false; } + + /** + * 是否支持共享-现只支持报表块、图表、tab块、绝对布局 + * @return + */ + public boolean isSupportShared() { + return true; + } } \ No newline at end of file diff --git a/designer-form/src/com/fr/design/mainframe/FormEditorKeyListener.java b/designer-form/src/com/fr/design/mainframe/FormEditorKeyListener.java index 24d067d70..81f3d6efc 100644 --- a/designer-form/src/com/fr/design/mainframe/FormEditorKeyListener.java +++ b/designer-form/src/com/fr/design/mainframe/FormEditorKeyListener.java @@ -1,5 +1,10 @@ package com.fr.design.mainframe; +import com.fr.base.BaseUtils; +import com.fr.common.inputevent.InputEventBaseOnOS; +import java.awt.Cursor; +import java.awt.Point; +import java.awt.Toolkit; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; @@ -10,6 +15,9 @@ import com.fr.design.designer.creator.XLayoutContainer; import com.fr.design.designer.creator.XWAbsoluteLayout; public class FormEditorKeyListener extends KeyAdapter{ + private static final Cursor ADDCURSOR = Toolkit.getDefaultToolkit().createCustomCursor( + BaseUtils.readImage("/com/fr/design/images/form/designer/cursor/add.png"), new Point(0, 0), + "addCursor"); private FormDesigner designer; private boolean moved; @@ -19,6 +27,9 @@ public class FormEditorKeyListener extends KeyAdapter{ @Override public void keyPressed(KeyEvent e) { + if(e.isShiftDown() || InputEventBaseOnOS.isControlDown(e)) { + designer.setCursor(ADDCURSOR); + } int code = e.getKeyCode(); XCreator creator = designer.getSelectionModel().getSelection().getSelectedCreator(); XLayoutContainer container; @@ -26,26 +37,29 @@ public class FormEditorKeyListener extends KeyAdapter{ return; } moved = true; - + switch (code) { - case KeyEvent.VK_LEFT: - designer.getSelectionModel().move(-1, 0); - break; - case KeyEvent.VK_RIGHT: - designer.getSelectionModel().move(1, 0); - break; - case KeyEvent.VK_UP: - designer.getSelectionModel().move(0, -1); - break; - case KeyEvent.VK_DOWN: - designer.getSelectionModel().move(0, 1); - break; - default: - moved = false; + case KeyEvent.VK_LEFT: + designer.getSelectionModel().move(-1, 0); + break; + case KeyEvent.VK_RIGHT: + designer.getSelectionModel().move(1, 0); + break; + case KeyEvent.VK_UP: + designer.getSelectionModel().move(0, -1); + break; + case KeyEvent.VK_DOWN: + designer.getSelectionModel().move(0, 1); + break; + default: + moved = false; } } - + public void keyReleased(KeyEvent e) { + if(!(e.isShiftDown() || InputEventBaseOnOS.isControlDown(e))) { + designer.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + } if (moved) { designer.getEditListenerTable().fireCreatorModified( designer.getSelectionModel().getSelection().getSelectedCreator(), DesignerEvent.CREATOR_RESIZED); diff --git a/designer-form/src/com/fr/design/mainframe/MobileWidgetListPane.java b/designer-form/src/com/fr/design/mainframe/MobileWidgetListPane.java new file mode 100644 index 000000000..40af6f34b --- /dev/null +++ b/designer-form/src/com/fr/design/mainframe/MobileWidgetListPane.java @@ -0,0 +1,71 @@ +package com.fr.design.mainframe; + +import com.fr.design.designer.creator.XCreator; +import com.fr.design.gui.controlpane.UISimpleListControlPane; +import com.fr.form.ui.Widget; +import com.fr.form.ui.container.WSortLayout; +import com.fr.general.NameObject; +import com.fr.stable.ArrayUtils; +import com.fr.stable.Nameable; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by plough on 2018/1/31. + */ +public class MobileWidgetListPane extends UISimpleListControlPane { + public static final String LIST_NAME = "Widget_List"; + + private FormDesigner designer; + private WSortLayout wSortLayout; + private String[] widgetNameList; + + public MobileWidgetListPane(FormDesigner designer, WSortLayout wSortLayout) { + super(); + this.designer = designer; + this.wSortLayout = wSortLayout; + widgetNameList = getData(); + + List nameObjectList = new ArrayList(); + for (String name : widgetNameList) { + nameObjectList.add(new NameObject(name, null)); + } + populate(nameObjectList.toArray(new NameObject[nameObjectList.size()])); + } + + /** + * 保存移动端控件列表顺序 + */ + public void updateToDesigner() { + Nameable[] nameableList = update(); + List newMobileWidgetList = new ArrayList<>(); + for (Nameable nameable : nameableList) { + newMobileWidgetList.add(nameable.getName()); + } + wSortLayout.updateSortedMobileWidgetList(newMobileWidgetList); + } + + /** + * 获取选中控件的控件列表 + * + * @return List widgetNameList + */ + private String[] getData() { + //选择的控件 + XCreator selectedCreator = designer.getSelectionModel().getSelection().getSelectedCreator(); + Widget selectedModel = selectedCreator != null ? selectedCreator.toData() : null; + + if (selectedModel == null || !selectedModel.acceptType(WSortLayout.class)) { + return ArrayUtils.EMPTY_STRING_ARRAY; + } + + // 选择的控件有两种类型,一种是WLayout,代表容器,一种是Widget,代表控件 + List mobileWidgetList = ((WSortLayout) selectedModel).getOrderedMobileWidgetList(); + String[] widgetNames = new String[mobileWidgetList.size()]; + for (int i = 0; i < mobileWidgetList.size(); i++) { + widgetNames[i] = mobileWidgetList.get(i); + } + return widgetNames; + } +} \ No newline at end of file diff --git a/designer-realize/src/com/fr/design/widget/CellWidgetCardPane.java b/designer-realize/src/com/fr/design/widget/CellWidgetCardPane.java index 77d1542cb..c590a84b2 100644 --- a/designer-realize/src/com/fr/design/widget/CellWidgetCardPane.java +++ b/designer-realize/src/com/fr/design/widget/CellWidgetCardPane.java @@ -9,13 +9,16 @@ import com.fr.design.foldablepane.UIExpandablePane; import com.fr.design.gui.ibutton.UIHeadGroup; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.mainframe.ElementCasePane; +import com.fr.design.widget.mobile.WidgetMobilePane; import com.fr.design.widget.ui.BasicWidgetPropertySettingPane; import com.fr.form.event.Listener; import com.fr.form.ui.Widget; import com.fr.general.Inter; -import javax.swing.*; -import java.awt.*; +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import java.awt.BorderLayout; +import java.awt.CardLayout; import java.util.ArrayList; /* @@ -24,6 +27,8 @@ import java.util.ArrayList; public class CellWidgetCardPane extends BasicPane { //当前的编辑器属性定义面板 private DataModify currentEditorDefinePane; + //当前的编辑器移动端面板 + private WidgetMobilePane currentWidgetMobilePane; //属性配置切换面板 private ArrayList paneList; private JPanel center; @@ -40,6 +45,11 @@ public class CellWidgetCardPane extends BasicPane { private JPanel eventTabPane; private WidgetEventPane eventPane; + //移动端属性容器 + private JPanel mobileTabPane; + private JPanel mobileCardPane; + private CardLayout mobileCardLayout; + private ElementCasePane pane; public CellWidgetCardPane(ElementCasePane pane) { @@ -51,27 +61,45 @@ public class CellWidgetCardPane extends BasicPane { this.removeAll(); this.setLayout(FRGUIPaneFactory.createBorderLayout()); - //k tabbedPane = new CardLayout(); center = new JPanel(tabbedPane); this.add(center, BorderLayout.CENTER); + + // 属性 attriTabPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); - eventTabPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); - eventTabPane.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 10)); - initPaneList(); - eventPane = initWidgetEventPane(pane); - eventTabPane.add(eventPane, BorderLayout.CENTER); - //k BasicScrollPane basicScrollPane = new AttrScrollPane() { @Override protected JPanel createContentPane() { return attriTabPane; } }; + widgetPropertyPane = new BasicWidgetPropertySettingPane(); + UIExpandablePane uiExpandablePane = new UIExpandablePane(Inter.getLocText("FR-Designer_Basic"), 280, 24, widgetPropertyPane); + attriTabPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 10)); + attriTabPane.add(uiExpandablePane, BorderLayout.NORTH); + attriCardPane = FRGUIPaneFactory.createCardLayout_S_Pane(); + attriTabPane.add(attriCardPane, BorderLayout.CENTER); + attriCardLayout = (CardLayout) attriCardPane.getLayout(); + + // 事件 + eventTabPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + eventTabPane.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 10)); + eventPane = initWidgetEventPane(pane); + eventTabPane.add(eventPane, BorderLayout.CENTER); + + // 移动端 + mobileTabPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + mobileCardPane = FRGUIPaneFactory.createCardLayout_S_Pane(); + mobileTabPane.add(mobileCardPane, BorderLayout.CENTER); + mobileCardLayout = (CardLayout) mobileCardPane.getLayout(); + center.add(basicScrollPane, Inter.getLocText("FR-Designer_Attribute")); center.add(eventTabPane, Inter.getLocText("FR-Designer_Event")); - final String[] tabTitles = new String[]{Inter.getLocText("FR-Designer_Attribute"), Inter.getLocText("FR-Designer_Event")}; + center.add(mobileTabPane, Inter.getLocText("FR-Widget_Mobile_Terminal")); + initPaneList(); + + final String[] tabTitles = new String[]{Inter.getLocText("FR-Designer_Attribute"), Inter.getLocText("FR-Designer_Event"), Inter.getLocText("FR-Widget_Mobile_Terminal")}; tabsHeaderIconPane = new UIHeadGroup(tabTitles) { @Override public void tabChanged(int index) { @@ -81,24 +109,13 @@ public class CellWidgetCardPane extends BasicPane { tabsHeaderIconPane.setNeedLeftRightOutLine(true); tabsHeaderIconPane.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, UIConstants.SHADOW_GREY)); this.add(tabsHeaderIconPane, BorderLayout.NORTH); - - widgetPropertyPane = new BasicWidgetPropertySettingPane(); - - UIExpandablePane uiExpandablePane = new UIExpandablePane(Inter.getLocText("FR-Designer_Basic"), 280, 24, widgetPropertyPane); - - - attriTabPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 10)); - attriTabPane.add(uiExpandablePane, BorderLayout.NORTH); - - attriCardPane = FRGUIPaneFactory.createCardLayout_S_Pane(); - attriTabPane.add(attriCardPane, BorderLayout.CENTER); - attriCardLayout = (CardLayout) attriCardPane.getLayout(); } private void initPaneList() { paneList = new ArrayList(); paneList.add(attriTabPane); paneList.add(eventPane); + paneList.add(mobileTabPane); } protected WidgetEventPane initWidgetEventPane(ElementCasePane pane){ @@ -112,7 +129,6 @@ public class CellWidgetCardPane extends BasicPane { public void populate(Widget cellWidget) { initComponents(pane); - currentEditorDefinePane = null; WidgetDefinePaneFactory.RN rn = WidgetDefinePaneFactory.createWidgetDefinePane(cellWidget, new Operator() { @Override @@ -123,9 +139,17 @@ public class CellWidgetCardPane extends BasicPane { DataModify definePane = rn.getDefinePane(); attriCardPane.add(definePane.toSwingComponent(), rn.getCardName()); attriCardLayout.show(attriCardPane, rn.getCardName()); + widgetPropertyPane.populate(cellWidget); currentEditorDefinePane = definePane; + eventPane.populate(cellWidget); - widgetPropertyPane.populate(cellWidget); + + WidgetMobilePane mobilePane = WidgetMobilePaneFactory.createWidgetMobilePane(cellWidget); + mobileCardPane.add(mobilePane, mobilePane.getClass().toString()); + mobileCardLayout.show(mobileCardPane, mobilePane.getClass().toString()); + currentWidgetMobilePane = mobilePane; + + tabsHeaderIconPane.setSelectedIndex(0); } @@ -145,6 +169,8 @@ public class CellWidgetCardPane extends BasicPane { widget.addListener(l); } + currentWidgetMobilePane.update(widget); + return widget; } diff --git a/designer-realize/src/com/fr/design/widget/WidgetMobilePaneFactory.java b/designer-realize/src/com/fr/design/widget/WidgetMobilePaneFactory.java new file mode 100644 index 000000000..8b9afc3f2 --- /dev/null +++ b/designer-realize/src/com/fr/design/widget/WidgetMobilePaneFactory.java @@ -0,0 +1,39 @@ +package com.fr.design.widget; + +import com.fr.base.FRContext; +import com.fr.design.ExtraDesignClassManager; +import com.fr.design.widget.mobile.WidgetMobilePane; +import com.fr.design.widget.ui.mobile.MultiFileEditorMobilePane; +import com.fr.form.ui.MultiFileEditor; +import com.fr.form.ui.Widget; + +import java.util.HashMap; +import java.util.Map; + +/** + * Created by plough on 2018/4/25. + */ +public class WidgetMobilePaneFactory { + private static Map, Class> mobilePaneMap = new HashMap<>(); + + static { + mobilePaneMap.put(MultiFileEditor.class, MultiFileEditorMobilePane.class); + mobilePaneMap.putAll(ExtraDesignClassManager.getInstance().getCellWidgetMobileOptionsMap()); + } + + private WidgetMobilePaneFactory() { + } + + public static WidgetMobilePane createWidgetMobilePane(Widget widget) { + WidgetMobilePane mobilePane = WidgetMobilePane.DEFAULT_PANE; + try { + if (mobilePaneMap.containsKey(widget.getClass())) { + mobilePane = mobilePaneMap.get(widget.getClass()).newInstance(); + mobilePane.populate(widget); + } + } catch (Exception e) { + FRContext.getLogger().error(e.getMessage(), e); + } + return mobilePane; + } +} diff --git a/designer-realize/src/com/fr/design/widget/ui/mobile/MultiFileEditorMobilePane.java b/designer-realize/src/com/fr/design/widget/ui/mobile/MultiFileEditorMobilePane.java new file mode 100644 index 000000000..e88e0c05e --- /dev/null +++ b/designer-realize/src/com/fr/design/widget/ui/mobile/MultiFileEditorMobilePane.java @@ -0,0 +1,84 @@ +package com.fr.design.widget.ui.mobile; + +import com.fr.base.mobile.FileUploadModeState; +import com.fr.base.mobile.MultiFileUploaderMobileAttr; +import com.fr.design.constants.LayoutConstants; +import com.fr.design.designer.properties.items.Item; +import com.fr.design.foldablepane.UIExpandablePane; +import com.fr.design.gui.icombobox.UIComboBox; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.layout.TableLayout; +import com.fr.design.layout.TableLayoutHelper; +import com.fr.design.widget.mobile.WidgetMobilePane; +import com.fr.form.ui.MultiFileEditor; +import com.fr.form.ui.Widget; +import com.fr.general.Inter; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.SwingConstants; +import java.awt.BorderLayout; +import java.awt.Component; + +/** + * Created by plough on 2018/4/25. + */ +public class MultiFileEditorMobilePane extends WidgetMobilePane { + private static final Item[] ITEMS = { + new Item(Inter.getLocText("FR-Designer_Take_Photos_And_Choose_From_Album"), FileUploadModeState.TAKE_PHOTOS_AND_CHOOSE_FROM_ALBUM), + new Item(Inter.getLocText("FR-Designer_Only_Take_Photos"), FileUploadModeState.ONLY_TAKE_PHOTOS) + }; + + private UIComboBox uploadModeComboBox;// 上传方式下拉框 + + protected void init() { + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + this.add(getMobileSettingsPane(), BorderLayout.NORTH); + } + + /** + * 从 widget 中提取数据展示在属性面板中 + * + * @param widget + */ + public void populate(Widget widget) { + MultiFileUploaderMobileAttr mobileAttr = ((MultiFileEditor)widget).getMobileAttr(); + FileUploadModeState fileUploadModeState = mobileAttr.getFileUploadModeState(); + uploadModeComboBox.setSelectedIndex(fileUploadModeState.getState()); + } + + /** + * 从属性面板把数据保存到 widget 中 + * @param widget + */ + public void update(Widget widget) { + MultiFileUploaderMobileAttr mobileAttr = ((MultiFileEditor)widget).getMobileAttr(); + mobileAttr.setFileUploadModeState((FileUploadModeState) ((Item)uploadModeComboBox.getSelectedItem()).getValue()); + } + + private UIExpandablePane getMobileSettingsPane() { + initUploadModeComboBox(); + + // 以后可能会扩展 + Component[][] components = new Component[][]{ + new Component[] {new UILabel(Inter.getLocText("FR-Designer_Upload_Mode"), SwingConstants.LEFT), uploadModeComboBox} + }; + + double f = TableLayout.FILL; + double p = TableLayout.PREFERRED; + double[] rowSize = {p}; + double[] columnSize = {p,f}; + int[][] rowCount = {{1, 1}}; + final JPanel panel = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, 30, LayoutConstants.VGAP_LARGE); + panel.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0)); + final JPanel panelWrapper = FRGUIPaneFactory.createBorderLayout_S_Pane(); + panelWrapper.add(panel, BorderLayout.NORTH); + + return new UIExpandablePane(Inter.getLocText("FR-Designer_Terminal"), 280, 20, panelWrapper); + } + + private void initUploadModeComboBox() { + this.uploadModeComboBox = new UIComboBox(ITEMS); + } +}