diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/connect/DatabaseConnectionPane.java b/designer-base/src/main/java/com/fr/design/data/datapane/connect/DatabaseConnectionPane.java index 61988cc69..209f4ab7d 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/connect/DatabaseConnectionPane.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/connect/DatabaseConnectionPane.java @@ -74,6 +74,7 @@ public abstract class DatabaseConnectionPane 0) { - DefaultListModel listModel = (DefaultListModel) nameableList.getModel(); + DefaultListModel listModel = (DefaultListModel) listControlPane.getNameableList().getModel(); Object selecteObj1 = listModel.get(selectedIndex - 1); listModel.set(selectedIndex - 1, listModel.get(selectedIndex)); listModel.set(selectedIndex, selecteObj1); - nameableList.setSelectedIndex(selectedIndex - 1); - nameableList.ensureIndexIsVisible(selectedIndex - 1); + listControlPane.getNameableList().setSelectedIndex(selectedIndex - 1); + listControlPane.getNameableList().ensureIndexIsVisible(selectedIndex - 1); } } public void onMoveDownItem() { - int selectedIndex = nameableList.getSelectedIndex(); + int selectedIndex = listControlPane.getNameableList().getSelectedIndex(); if (selectedIndex == -1) { return; } - if (selectedIndex < nameableList.getModel().getSize() - 1) { - DefaultListModel listModel = (DefaultListModel) nameableList + if (selectedIndex < listControlPane.getNameableList().getModel().getSize() - 1) { + DefaultListModel listModel = (DefaultListModel) listControlPane.getNameableList() .getModel(); Object selecteObj1 = listModel.get(selectedIndex + 1); listModel.set(selectedIndex + 1, listModel.get(selectedIndex)); listModel.set(selectedIndex, selecteObj1); - nameableList.setSelectedIndex(selectedIndex + 1); - nameableList.ensureIndexIsVisible(selectedIndex + 1); + listControlPane.getNameableList().setSelectedIndex(selectedIndex + 1); + listControlPane.getNameableList().ensureIndexIsVisible(selectedIndex + 1); } } public void onSortItem(boolean isAtoZ) { + onSortItem(isAtoZ, listControlPane.getNameableList()); + } + + public void onSortItem(boolean isAtoZ, JNameEdList nameEdList) { // p:选中的值. - Object selectedValue = nameableList.getSelectedValue(); + Object selectedValue = nameEdList.getSelectedValue(); - DefaultListModel listModel = (DefaultListModel) nameableList + DefaultListModel listModel = (DefaultListModel) nameEdList .getModel(); Nameable[] nameableArray = new Nameable[listModel.getSize()]; if (nameableArray.length <= 0) { @@ -156,12 +158,12 @@ public class CommonShortCutHandlers { // p:需要选中以前的那个值. if (selectedValue != null) { - nameableList.setSelectedValue(selectedValue, true); + nameEdList.setSelectedValue(selectedValue, true); } listControlPane.checkButtonEnabled(); // p:需要repaint. - nameableList.repaint(); + nameEdList.repaint(); } private String createUnrepeatedCopyName(String suffix) { diff --git a/designer-base/src/main/java/com/fr/design/gui/controlpane/ListControlPaneHelper.java b/designer-base/src/main/java/com/fr/design/gui/controlpane/ListControlPaneHelper.java index 76255d96b..7fe1a27ef 100644 --- a/designer-base/src/main/java/com/fr/design/gui/controlpane/ListControlPaneHelper.java +++ b/designer-base/src/main/java/com/fr/design/gui/controlpane/ListControlPaneHelper.java @@ -4,18 +4,41 @@ import com.fr.design.beans.BasicBeanPane; import com.fr.design.dialog.FineJOptionPane; import com.fr.design.gui.ilist.JNameEdList; import com.fr.design.gui.ilist.ListModelElement; +import com.fr.design.gui.ilist.UINameEdList; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.os.impl.PopupDialogSaveAction; +import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.form.event.Listener; +import com.fr.general.NameObject; import com.fr.stable.Nameable; import com.fr.stable.StringUtils; +import com.fr.stable.os.support.OSSupportCenter; import javax.swing.DefaultListModel; -import javax.swing.JOptionPane; +import javax.swing.JList; +import javax.swing.JPopupMenu; +import javax.swing.SwingUtilities; import java.awt.Component; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Toolkit; +import java.awt.Window; +import java.awt.event.InputEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; /** * 存放一些公用的方法 * Created by plough on 2018/8/13. */ class ListControlPaneHelper { + private static final int EDIT_RANGE = 25; // 编辑按钮的x坐标范围 + private ListControlPaneProvider listControlPane; private ListControlPaneHelper(ListControlPaneProvider listControlPane) { @@ -110,4 +133,123 @@ class ListControlPaneHelper { } + protected void popupEditDialog(Point mousePos, UINameEdList nameableList, UIControlPane controlPane) { + int editingIndex = nameableList.getSelectedIndex(); + Rectangle currentCellBounds = nameableList.getCellBounds(editingIndex, editingIndex); + if (editingIndex < 0 || (mousePos != null && !currentCellBounds.contains(mousePos))) { + return; + } + Window popupEditDialog = controlPane.getPopupEditDialog(); + popupEditDialog.setLocation(getPopupDialogLocation(nameableList, popupEditDialog)); + if (popupEditDialog instanceof UIControlPane.PopupEditDialog) { + ((UIControlPane.PopupEditDialog) popupEditDialog).setTitle(getSelectedName()); + } + popupEditDialog.setVisible(true); + PopupDialogSaveAction osBasedAction = OSSupportCenter.getAction(PopupDialogSaveAction.class); + osBasedAction.register(controlPane, popupEditDialog); + } + + private Point getPopupDialogLocation(UINameEdList nameableList, Window popupEditDialog) { + Point resultPos = new Point(0, 0); + Point listPos = nameableList.getLocationOnScreen(); + resultPos.x = listPos.x - popupEditDialog.getWidth(); + resultPos.y = listPos.y + (nameableList.getSelectedIndex() - 1) * EDIT_RANGE; + + // 当对象在屏幕上的位置比较靠下时,往下移动弹窗至与属性面板平齐 + Window frame = DesignerContext.getDesignerFrame(); + // 不能太低 + int maxY = frame.getLocationOnScreen().y + frame.getHeight() - popupEditDialog.getHeight(); + if (resultPos.y > maxY) { + resultPos.y = maxY; + } + // 也不能太高 + int minY = frame.getLocationOnScreen().y + EDIT_RANGE; + if (resultPos.y < minY) { + resultPos.y = minY; + } + + // 当在左侧显示不下时,在右侧弹出弹窗 + if (resultPos.x < 0) { + resultPos.x = listPos.x + nameableList.getParent().getWidth(); + } + // 如果右侧显示不下,可以向左移动 + int maxX = frame.getLocationOnScreen().x + frame.getWidth() - popupEditDialog.getWidth() - EDIT_RANGE; + if (resultPos.x > maxX) { + resultPos.x = maxX; + } + + return resultPos; + } + + /* + * UINameEdList的鼠标事件 + */ + protected MouseListener getListMouseListener(UINameEdList nameableList, UIControlPane controlPane) { + return new MouseAdapter() { + @Override + public void mouseReleased(MouseEvent evt) { + nameableList.stopEditing(); + if (evt.getClickCount() >= 2 + && SwingUtilities.isLeftMouseButton(evt) && evt.getX() > EDIT_RANGE) { + nameableList.editItemAt(nameableList.getSelectedIndex()); + } else if (SwingUtilities.isLeftMouseButton(evt) && evt.getX() <= EDIT_RANGE) { + popupEditDialog(evt.getPoint(), nameableList, controlPane); + } + + // peter:处理右键的弹出菜单 + if (!SwingUtilities.isRightMouseButton(evt)) { + return; + } + + // peter: 注意,在checkButtonEnabled()方法里面,设置了所有的Action的Enabled. + checkButtonEnabled(); + + // p:右键菜单. + JPopupMenu popupMenu = new JPopupMenu(); + + for (ShortCut4JControlPane sj : listControlPane.getShorts()) { + sj.getShortCut().intoJPopupMenu(popupMenu); + } + + // peter: 只有弹出菜单有子菜单的时候,才需要弹出来. + GUICoreUtils.showPopupMenu(popupMenu, nameableList, evt.getX() - 1, + evt.getY() - 1); + } + + @Override + public void mouseClicked(MouseEvent e) { + JList list = (JList) e.getSource(); + if (list.locationToIndex(e.getPoint()) == -1 && !e.isShiftDown() + && !isMenuShortcutKeyDown(e)) { + list.clearSelection(); + } + } + + private boolean isMenuShortcutKeyDown(InputEvent event) { + return (event.getModifiers() & Toolkit.getDefaultToolkit() + .getMenuShortcutKeyMask()) != 0; + } + + @Override + public void mouseMoved(MouseEvent e) { + + } + }; + } + + public Map> processCatalog(List nameObjectList) { + Map> map = new HashMap<>(); + for (NameObject nameObject : nameObjectList) { + Listener listener = (Listener) nameObject.getObject(); + if (StringUtils.isNotEmpty(listener.getName())) { + nameObject.setName(listener.getName()); + } + List list = map.computeIfAbsent(listener.getEventName(), k -> new ArrayList<>()); + list.add(nameObject); + } + return map; + } + + + } diff --git a/designer-base/src/main/java/com/fr/design/gui/controlpane/UIControlPane.java b/designer-base/src/main/java/com/fr/design/gui/controlpane/UIControlPane.java index 04427b337..b15b9eab9 100644 --- a/designer-base/src/main/java/com/fr/design/gui/controlpane/UIControlPane.java +++ b/designer-base/src/main/java/com/fr/design/gui/controlpane/UIControlPane.java @@ -49,7 +49,7 @@ import java.awt.event.WindowEvent; /** * Created by plough on 2017/7/21. */ -abstract class UIControlPane extends JControlPane { +public abstract class UIControlPane extends JControlPane { private UIToolbar topToolBar; protected Window popupEditDialog; private static final int TOP_TOOLBAR_HEIGHT = 20; @@ -78,7 +78,7 @@ abstract class UIControlPane extends JControlPane { initCardPane(); if (isNewStyle()) { - getPopupEditDialog(cardPane); + createPopupEditDialog(cardPane); this.add(getLeftPane(), BorderLayout.CENTER); this.setBorder(BorderFactory.createEmptyBorder(10, 10, 15, 10)); } else { @@ -100,7 +100,11 @@ abstract class UIControlPane extends JControlPane { this.checkButtonEnabled(); } - private void getPopupEditDialog(JPanel cardPane) { + protected Window getPopupEditDialog(){ + return this.popupEditDialog; + } + + private void createPopupEditDialog(JPanel cardPane) { popupEditDialog = new PopupEditDialog(cardPane); } @@ -400,4 +404,4 @@ abstract class UIControlPane extends JControlPane { return new Dimension(super.getPreferredSize().width, 28); } } -} \ No newline at end of file +} diff --git a/designer-base/src/main/java/com/fr/design/gui/controlpane/UIListControlPane.java b/designer-base/src/main/java/com/fr/design/gui/controlpane/UIListControlPane.java index ec76f5bf7..b7b8674be 100644 --- a/designer-base/src/main/java/com/fr/design/gui/controlpane/UIListControlPane.java +++ b/designer-base/src/main/java/com/fr/design/gui/controlpane/UIListControlPane.java @@ -6,32 +6,18 @@ import com.fr.design.gui.icontainer.UIScrollPane; import com.fr.design.gui.ilist.JNameEdList; import com.fr.design.gui.ilist.ListModelElement; import com.fr.design.gui.ilist.UINameEdList; -import com.fr.design.mainframe.DesignerContext; -import com.fr.design.os.impl.PopupDialogSaveAction; -import com.fr.design.utils.gui.GUICoreUtils; import com.fr.stable.ArrayUtils; import com.fr.stable.Nameable; -import com.fr.stable.os.support.OSSupportCenter; import javax.swing.DefaultListModel; -import javax.swing.JList; import javax.swing.JPanel; -import javax.swing.JPopupMenu; import javax.swing.ListSelectionModel; -import javax.swing.SwingUtilities; import javax.swing.event.ListDataEvent; import javax.swing.event.ListDataListener; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import java.awt.BorderLayout; import java.awt.Point; -import java.awt.Rectangle; -import java.awt.Toolkit; -import java.awt.Window; -import java.awt.event.InputEvent; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; @@ -41,11 +27,8 @@ import java.lang.reflect.InvocationTargetException; public abstract class UIListControlPane extends UIControlPane implements ListControlPaneProvider { private static final String LIST_NAME = "UIControl_List"; - private static final int EDIT_RANGE = 25; // 编辑按钮的x坐标范围 protected UINameEdList nameableList; - private int editingIndex; - protected String selectedName; protected boolean isPopulating = false; private CommonShortCutHandlers commonHandlers; private ListControlPaneHelper helper; @@ -93,7 +76,7 @@ public abstract class UIListControlPane extends UIControlPane implements ListCon nameableList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); - nameableList.addMouseListener(getListMouseListener()); + nameableList.addMouseListener(getHelper().getListMouseListener(nameableList, this)); nameableList.addListSelectionListener(new ListSelectionListener() { public void valueChanged(ListSelectionEvent evt) { // richie:避免多次update和populate大大降低效率 @@ -139,7 +122,7 @@ public abstract class UIListControlPane extends UIControlPane implements ListCon saveSettings(); } }; - nameEdList.setCellRenderer(new UINameableListCellRenderer(this)); + nameEdList.setCellRenderer(new UINameableListCellRenderer(this.isNewStyle(), this.creators)); return nameEdList; } @@ -181,13 +164,6 @@ public abstract class UIListControlPane extends UIControlPane implements ListCon } - /** - * 获取选中的名字 - */ - public String getSelectedName() { - return getHelper().getSelectedName(); - } - /** * 添加 Nameable * @@ -209,51 +185,10 @@ public abstract class UIListControlPane extends UIControlPane implements ListCon protected void popupEditDialog(Point mousePos) { if (isNewStyle()) { - Rectangle currentCellBounds = nameableList.getCellBounds(editingIndex, editingIndex); - if (editingIndex < 0 || (mousePos != null && !currentCellBounds.contains(mousePos))) { - return; - } - popupEditDialog.setLocation(getPopupDialogLocation()); - if (popupEditDialog instanceof PopupEditDialog) { - ((PopupEditDialog)popupEditDialog).setTitle(getSelectedName()); - } - popupEditDialog.setVisible(true); - PopupDialogSaveAction osBasedAction = OSSupportCenter.getAction(PopupDialogSaveAction.class); - osBasedAction.register(this, popupEditDialog); + getHelper().popupEditDialog(mousePos, nameableList, this); } } - private Point getPopupDialogLocation() { - Point resultPos = new Point(0, 0); - Point listPos = nameableList.getLocationOnScreen(); - resultPos.x = listPos.x - popupEditDialog.getWidth(); - resultPos.y = listPos.y + (nameableList.getSelectedIndex() - 1) * EDIT_RANGE; - - // 当对象在屏幕上的位置比较靠下时,往下移动弹窗至与属性面板平齐 - Window frame = DesignerContext.getDesignerFrame(); - // 不能太低 - int maxY = frame.getLocationOnScreen().y + frame.getHeight() - popupEditDialog.getHeight(); - if (resultPos.y > maxY) { - resultPos.y = maxY; - } - // 也不能太高 - int minY = frame.getLocationOnScreen().y + EDIT_RANGE; - if (resultPos.y < minY) { - resultPos.y = minY; - } - - // 当在左侧显示不下时,在右侧弹出弹窗 - if (resultPos.x < 0) { - resultPos.x = listPos.x + nameableList.getParent().getWidth(); - } - // 如果右侧显示不下,可以向左移动 - int maxX = frame.getLocationOnScreen().x + frame.getWidth() - popupEditDialog.getWidth() - EDIT_RANGE; - if (resultPos.x > maxX) { - resultPos.x = maxX; - } - - return resultPos; - } /** * 生成不重复的名字 @@ -301,65 +236,6 @@ public abstract class UIListControlPane extends UIControlPane implements ListCon return getModel().getSize() > 0 && nameableList.getSelectedIndex() != -1; } - /* - * UINameEdList的鼠标事件 - */ - private MouseListener getListMouseListener() { - return new MouseAdapter() { - @Override - public void mouseReleased(MouseEvent evt) { - nameableList.stopEditing(); - if (evt.getClickCount() >= 2 - && SwingUtilities.isLeftMouseButton(evt) && evt.getX() > EDIT_RANGE) { - editingIndex = nameableList.getSelectedIndex(); - selectedName = nameableList.getNameAt(editingIndex); - nameableList.editItemAt(nameableList.getSelectedIndex()); - } else if (SwingUtilities.isLeftMouseButton(evt) && evt.getX() <= EDIT_RANGE) { - editingIndex = nameableList.getSelectedIndex(); - selectedName = nameableList.getNameAt(editingIndex); - popupEditDialog(evt.getPoint()); - } - - // peter:处理右键的弹出菜单 - if (!SwingUtilities.isRightMouseButton(evt)) { - return; - } - - // peter: 注意,在checkButtonEnabled()方法里面,设置了所有的Action的Enabled. - checkButtonEnabled(); - - // p:右键菜单. - JPopupMenu popupMenu = new JPopupMenu(); - - for (ShortCut4JControlPane sj : getShorts()) { - sj.getShortCut().intoJPopupMenu(popupMenu); - } - - // peter: 只有弹出菜单有子菜单的时候,才需要弹出来. - GUICoreUtils.showPopupMenu(popupMenu, nameableList, evt.getX() - 1, - evt.getY() - 1); - } - - @Override - public void mouseClicked(MouseEvent e) { - JList list = (JList) e.getSource(); - if (list.locationToIndex(e.getPoint()) == -1 && !e.isShiftDown() - && !isMenuShortcutKeyDown(e)) { - list.clearSelection(); - } - } - - private boolean isMenuShortcutKeyDown(InputEvent event) { - return (event.getModifiers() & Toolkit.getDefaultToolkit() - .getMenuShortcutKeyMask()) != 0; - } - - @Override - public void mouseMoved(MouseEvent e) { - - } - }; - } /** * 检查按钮可用状态 Check button enabled. diff --git a/designer-base/src/main/java/com/fr/design/gui/controlpane/UINameableListCellRenderer.java b/designer-base/src/main/java/com/fr/design/gui/controlpane/UINameableListCellRenderer.java index b66ee1ef2..40d8d98fa 100644 --- a/designer-base/src/main/java/com/fr/design/gui/controlpane/UINameableListCellRenderer.java +++ b/designer-base/src/main/java/com/fr/design/gui/controlpane/UINameableListCellRenderer.java @@ -1,12 +1,8 @@ package com.fr.design.gui.controlpane; -import com.fr.base.BaseUtils; import com.fr.design.constants.UIConstants; -import com.fr.design.gui.ibutton.UIButton; import com.fr.design.gui.ilable.UILabel; import com.fr.design.gui.ilist.ListModelElement; -import com.fr.design.gui.itextfield.UITextField; -import com.fr.design.utils.gui.GUICoreUtils; import com.fr.stable.Nameable; import sun.swing.DefaultLookup; @@ -14,8 +10,6 @@ import javax.swing.*; import javax.swing.border.Border; import javax.swing.border.EmptyBorder; import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; /** * Nameable的ListCellRenerer @@ -32,12 +26,14 @@ public class UINameableListCellRenderer extends private static final int BUTTON_WIDTH = 25; private UILabel editButton; // "编辑按钮",实际上是一个 UILabel,由列表项(UIListControlPane)统一处理点击事件 private UILabel label; - private UIListControlPane listControlPane; + private boolean isNewStyle; + private NameableCreator[] creators; private Color initialLabelForeground; - public UINameableListCellRenderer(UIListControlPane listControlPane) { + public UINameableListCellRenderer( boolean isNewStyle, NameableCreator[] creators) { super(); - this.listControlPane = listControlPane; + this.isNewStyle = isNewStyle; + this.creators = creators; initComponents(); setOpaque(true); setBorder(getNoFocusBorder()); @@ -50,7 +46,7 @@ public class UINameableListCellRenderer extends return new Dimension(BUTTON_WIDTH, BUTTON_WIDTH); } }; - editButton.setIcon(listControlPane.isNewStyle() ? UIConstants.LIST_EDIT_ICON : UIConstants.CPT_ICON); + editButton.setIcon(isNewStyle ? UIConstants.LIST_EDIT_ICON : UIConstants.CPT_ICON); editButton.setBorder(BorderFactory.createMatteBorder(0, 0, 0, 1, UIConstants.LIST_ITEM_SPLIT_LINE)); editButton.setHorizontalAlignment(SwingConstants.CENTER); label = new UILabel(); @@ -92,7 +88,7 @@ public class UINameableListCellRenderer extends setBackground(bg == null ? list.getSelectionBackground() : bg); setForeground(fg == null ? list.getSelectionForeground() : fg); label.setForeground(Color.WHITE); - if (listControlPane.isNewStyle()) { + if (isNewStyle) { editButton.setIcon(UIConstants.LIST_EDIT_WHITE_ICON); } } @@ -100,7 +96,7 @@ public class UINameableListCellRenderer extends setBackground(list.getBackground()); setForeground(list.getForeground()); label.setForeground(initialLabelForeground); - if (listControlPane.isNewStyle()) { + if (isNewStyle) { editButton.setIcon(UIConstants.LIST_EDIT_ICON); } } @@ -114,7 +110,7 @@ public class UINameableListCellRenderer extends Nameable wrappee = ((ListModelElement) value).wrapper; this.setText(((ListModelElement) value).wrapper.getName()); - for (NameableCreator creator : listControlPane.creators()) { + for (NameableCreator creator : creators) { if (creator.menuIcon() != null && creator.acceptObject2Populate(wrappee) != null) { this.setToolTipText(creator.createTooltip()); break; @@ -124,4 +120,4 @@ public class UINameableListCellRenderer extends return this; } -} \ No newline at end of file +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/OpenLoadingPane.java b/designer-base/src/main/java/com/fr/design/mainframe/OpenLoadingPane.java index 9ee095c99..624f280a7 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/OpenLoadingPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/OpenLoadingPane.java @@ -1,6 +1,7 @@ package com.fr.design.mainframe; import com.fr.design.gui.ilable.UILabel; +import com.fr.general.IOUtils; import java.awt.Color; import java.awt.Component; import java.awt.Container; @@ -16,7 +17,7 @@ import javax.swing.JPanel; */ public class OpenLoadingPane extends JPanel { - private static final ImageIcon LOADING_ICON = new ImageIcon(OpenLoadingPane.class.getResource("/com/fr/design/images/mainframe/loading.gif")); + private static final ImageIcon LOADING_ICON = new ImageIcon(IOUtils.readImage("/com/fr/design/images/mainframe/loading.gif")); private UILabel loadingLabel; diff --git a/designer-base/src/main/java/com/fr/design/os/impl/PopupDialogSaveAction.java b/designer-base/src/main/java/com/fr/design/os/impl/PopupDialogSaveAction.java index 019ee3d97..c0b060005 100644 --- a/designer-base/src/main/java/com/fr/design/os/impl/PopupDialogSaveAction.java +++ b/designer-base/src/main/java/com/fr/design/os/impl/PopupDialogSaveAction.java @@ -1,6 +1,6 @@ package com.fr.design.os.impl; -import com.fr.design.gui.controlpane.UIListControlPane; +import com.fr.design.gui.controlpane.UIControlPane; import com.fr.stable.os.OperatingSystem; import com.fr.stable.os.support.OSBasedAction; @@ -15,7 +15,7 @@ import java.awt.*; */ public class PopupDialogSaveAction implements OSBasedAction { - private UIListControlPane currentControlPane; + private UIControlPane currentControlPane; private Window popupDialog; @Override @@ -26,7 +26,7 @@ public class PopupDialogSaveAction implements OSBasedAction { } } - public void register(UIListControlPane currentControlPane, Window popupDialog) { + public void register(UIControlPane currentControlPane, Window popupDialog) { this.currentControlPane = currentControlPane; this.popupDialog = popupDialog; } diff --git a/designer-base/src/main/java/com/fr/design/widget/EventCreator.java b/designer-base/src/main/java/com/fr/design/widget/EventCreator.java index 4fdfd7ed8..63d40515c 100644 --- a/designer-base/src/main/java/com/fr/design/widget/EventCreator.java +++ b/designer-base/src/main/java/com/fr/design/widget/EventCreator.java @@ -18,6 +18,10 @@ public class EventCreator extends NameableSelfCreator { this.eventName = eventName; } + public String getEventName() { + return eventName; + } + @Override public Nameable createNameable(UnrepeatedNameHelper helper) { return new NameObject(helper.createUnrepeatedName(this.menuName()),new Listener(this.eventName)) ; @@ -47,13 +51,17 @@ public class EventCreator extends NameableSelfCreator { return eventName; } } + @Override - public void saveUpdatedBean(ListModelElement wrapper, Object bean) { - ((NameObject)wrapper.wrapper).setObject(bean); + public void saveUpdatedBean(ListModelElement element, Object bean) { + if (bean instanceof Listener){ + ((Listener)bean).setName(element.wrapper.getName()); + } + ((NameObject)element.wrapper).setObject(bean); } @Override public String createTooltip() { return null; } -} \ No newline at end of file +} diff --git a/designer-base/src/test/java/com/fr/design/gui/controlpane/ListControlPaneHelperTest.java b/designer-base/src/test/java/com/fr/design/gui/controlpane/ListControlPaneHelperTest.java new file mode 100644 index 000000000..8f113089e --- /dev/null +++ b/designer-base/src/test/java/com/fr/design/gui/controlpane/ListControlPaneHelperTest.java @@ -0,0 +1,41 @@ +package com.fr.design.gui.controlpane; + +import com.fr.form.event.Listener; +import com.fr.general.NameObject; +import org.easymock.EasyMock; +import org.junit.Assert; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * Created by kerry on 5/17/21 + */ +public class ListControlPaneHelperTest { + + @Test + public void testProcessCatalog() { + ListControlPaneHelper helper = ListControlPaneHelper.newInstance(EasyMock.mock(ListControlPaneProvider.class)); + List nameObjectList = new ArrayList<>(); + Listener listener1 = new Listener(); + listener1.setEventName("click"); + Listener listener2 = new Listener(); + listener2.setEventName("afterInit"); + Listener listener3 = new Listener(); + listener3.setEventName("click"); + Listener listener4 = new Listener(); + listener4.setEventName("afterInit"); + listener4.setName("test"); + nameObjectList.add(new NameObject("click", listener1)); + nameObjectList.add(new NameObject("afterInit", listener2)); + nameObjectList.add(new NameObject("click", listener3)); + nameObjectList.add(new NameObject("afterInit", listener4)); + Map> map = helper.processCatalog(nameObjectList); + Assert.assertEquals(2, map.size()); + Assert.assertEquals(2, map.get("afterInit").size()); + Assert.assertEquals(2, map.get("click").size()); + + } +} diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XBorderStyleWidgetCreator.java b/designer-form/src/main/java/com/fr/design/designer/creator/XBorderStyleWidgetCreator.java index fdefc019a..e4b5377ba 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XBorderStyleWidgetCreator.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XBorderStyleWidgetCreator.java @@ -1,6 +1,7 @@ package com.fr.design.designer.creator; import com.fr.base.BaseFormula; +import com.fr.base.iofile.attr.ExtendSharableAttrMark; import com.fr.design.border.UIRoundedBorder; import com.fr.form.ui.AbstractBorderStyleWidget; import com.fr.form.ui.Label; @@ -31,6 +32,11 @@ public class XBorderStyleWidgetCreator extends XWidgetCreator{ public XBorderStyleWidgetCreator(Widget widget, Dimension initSize) { super(widget, initSize); + + ExtendSharableAttrMark sharableAttrMark = this.toData().getWidgetAttrMark(ExtendSharableAttrMark.XML_TAG); + if (sharableAttrMark != null) { + this.setShareId(sharableAttrMark.getShareId()); + } } /** diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XChartEditor.java b/designer-form/src/main/java/com/fr/design/designer/creator/XChartEditor.java index a6a29339e..24bea0177 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XChartEditor.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XChartEditor.java @@ -17,7 +17,6 @@ import com.fr.design.mainframe.CoverReportPane; import com.fr.design.mainframe.EastRegionContainerPane; import com.fr.design.mainframe.EditingMouseListener; import com.fr.design.mainframe.FormDesigner; -import com.fr.design.mainframe.HelpDialogManager; import com.fr.design.mainframe.widget.editors.WLayoutBorderStyleEditor; import com.fr.design.module.DesignModuleFactory; import com.fr.form.ui.BaseChartEditor; @@ -273,10 +272,11 @@ public class XChartEditor extends XBorderStyleWidgetCreator { } } } - HelpDialogManager.getInstance().setPane(coverPanel); - if (this.isHelpBtnOnFocus()) { - coverPanel.setMsgDisplay(e); + if (this.isShareConfigButtonFocus()) { + CoverReportPane.showShareConfig(((XCreator) this.getParent()).toData()); } + + } @Override @@ -315,23 +315,6 @@ public class XChartEditor extends XBorderStyleWidgetCreator { return editor; } - /** - * 是否展现覆盖的pane - * - * @param display 是否 - */ - public void displayCoverPane(boolean display) { - isHovering = display; - coverPanel.setVisible(display); - coverPanel.setPreferredSize(editor.getPreferredSize()); - coverPanel.setBounds(editor.getBounds()); - editor.repaint(); - } - - public JComponent getCoverPane() { - return coverPanel; - } - /** * 是否支持设置可用 * return boolean diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XCreator.java b/designer-form/src/main/java/com/fr/design/designer/creator/XCreator.java index c7c91d9aa..3cd33d6c3 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XCreator.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XCreator.java @@ -24,16 +24,11 @@ import com.fr.design.utils.gui.LayoutUtils; import com.fr.form.ui.Widget; import com.fr.form.ui.container.WTitleLayout; import com.fr.stable.Constants; -import com.fr.stable.CoreGraphHelper; import com.fr.stable.StableUtils; import com.fr.stable.StringUtils; -import com.fr.third.javax.annotation.Nullable; import javax.swing.BorderFactory; -import javax.swing.Icon; -import javax.swing.ImageIcon; import javax.swing.JComponent; -import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.border.Border; import java.awt.BorderLayout; @@ -43,7 +38,6 @@ import java.awt.Dimension; import java.awt.Graphics; import java.awt.Rectangle; import java.awt.event.MouseEvent; -import java.awt.image.BufferedImage; import java.beans.IntrospectionException; import java.util.ArrayList; import java.util.List; @@ -71,7 +65,7 @@ public abstract class XCreator extends JPanel implements XComponent, XCreatorToo private int[] directions; private Rectangle backupBound; private String shareId = StringUtils.EMPTY;//如果组件是共享的会有这个属性 - private boolean isHelpBtnOnFocus = false;//焦点是否在帮助按钮上 + private boolean isShareConfigButtonFocus = false;//焦点是否在帮助按钮上 private static final int SHORTS_SEPARATOR_POS = 4; // 弹出菜单分割的位置 public XCreator(Widget ob, Dimension initSize) { @@ -658,6 +652,9 @@ public abstract class XCreator extends JPanel implements XComponent, XCreatorToo public void setShareId(String shareId) { this.shareId = shareId; + if (coverPanel != null) { + coverPanel.setShared(isShared()); + } } public String getShareId() { @@ -668,54 +665,31 @@ public abstract class XCreator extends JPanel implements XComponent, XCreatorToo * 焦点是否在帮助按钮上 * @return 焦点是否在帮助按钮上 */ - public boolean isHelpBtnOnFocus() { - return isHelpBtnOnFocus; + public boolean isShareConfigButtonFocus() { + return isShareConfigButtonFocus; } - public void setHelpBtnOnFocus(boolean helpBtnOnFocus) { - isHelpBtnOnFocus = helpBtnOnFocus; + public void setShareConfigButtonFocus(boolean shareConfigButtonFocus) { + isShareConfigButtonFocus = shareConfigButtonFocus; } - /** - * 设置描述信息 - * @param msg 帮助信息 - */ - public void setXDescrption(String msg){ - if (coverPanel != null) { - coverPanel.setHelpMsg(msg); - } - } - public JComponent getCoverPane(){ + public CoverReportPane getCoverPane(){ return coverPanel; } - /** - * 销毁帮助提示框 - */ - public void destroyHelpDialog(){ - if (coverPanel != null) { - coverPanel.destroyHelpDialog(); - } - } - /** * 是否展现覆盖的pane * @param display 是否 */ public void displayCoverPane(boolean display){ - } - - /** - * 根据widget设置Xcreator描述信息 - * @param widget - */ - public void setXDescrption(Widget widget){ - if (widget != null) { - setXDescrption(widget.getDescription()); + if (coverPanel != null) { + coverPanel.setVisible(display); + coverPanel.setPreferredSize(editor.getPreferredSize()); + coverPanel.setBounds(editor.getBounds()); + editor.repaint(); } } - /** * 按照比例调整组件的宽度 * @param percent 比例 diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XCreatorUtils.java b/designer-form/src/main/java/com/fr/design/designer/creator/XCreatorUtils.java index 260318023..945d3bfdd 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XCreatorUtils.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XCreatorUtils.java @@ -257,7 +257,6 @@ public class XCreatorUtils { FineLoggerFactory.getLogger().error("Error to create xcreator!"); creator = new NullCreator(widget, d); } - creator.setXDescrption(widget);//设置描述信息 return creator; } diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XElementCase.java b/designer-form/src/main/java/com/fr/design/designer/creator/XElementCase.java index 14e0a6511..6aafc8c6e 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XElementCase.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XElementCase.java @@ -34,7 +34,6 @@ import java.util.Set; public class XElementCase extends XBorderStyleWidgetCreator implements FormElementCaseContainerProvider{ private UILabel imageLable; - private CoverReportPane coverPanel; private FormDesigner designer; private static BufferedImage DEFAULT_BACKGROUND; private boolean isHovering = false; @@ -223,28 +222,6 @@ public class XElementCase extends XBorderStyleWidgetCreator implements FormEleme imageLable.setBounds(0, 0, icon.getIconWidth(), icon.getIconHeight()); } - /** - * 是否展现覆盖的pane - * @param display 是否 - */ - public void displayCoverPane(boolean display){ - isHovering = display; - coverPanel.setVisible(display); - coverPanel.setBounds(1, 1, (int) editor.getBounds().getWidth(), (int) editor.getBounds().getHeight()); - editor.repaint(); - } - - /** - * 销毁帮助提示框 - */ - public void destroyHelpDialog(){ - coverPanel.destroyHelpDialog(); - } - - public JComponent getCoverPane(){ - return coverPanel; - } - @Override public void paintBorder(Graphics g, Rectangle bounds){ if (!isHovering) { @@ -316,11 +293,10 @@ public class XElementCase extends XBorderStyleWidgetCreator implements FormEleme * @param e 点击事件 */ public void respondClick(EditingMouseListener editingMouseListener,MouseEvent e){ - HelpDialogManager.getInstance().setPane(coverPanel); super.respondClick(editingMouseListener, e); editingMouseListener.refreshTopXCreator(); - if (this.isHelpBtnOnFocus()) { - coverPanel.setMsgDisplay(e); + if (this.isShareConfigButtonFocus()) { + CoverReportPane.showShareConfig(((XCreator)this.getParent()).toData()); } else { switchTab(e, editingMouseListener); } @@ -342,11 +318,6 @@ public class XElementCase extends XBorderStyleWidgetCreator implements FormEleme return new WidgetPropertyUIProvider[]{ new ElementCasePropertyUI(this)}; } - @Override - public void setXDescrption(String msg) { - coverPanel.setHelpMsg(msg); - } - /** * data属性改变触发其他操作 * @@ -370,7 +341,4 @@ public class XElementCase extends XBorderStyleWidgetCreator implements FormEleme public boolean isSupportShared() { return true; } - - - } diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XWAbsoluteLayout.java b/designer-form/src/main/java/com/fr/design/designer/creator/XWAbsoluteLayout.java index da268b0e6..32273ca08 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XWAbsoluteLayout.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XWAbsoluteLayout.java @@ -4,8 +4,6 @@ package com.fr.design.designer.creator; import com.fr.base.GraphHelper; -import com.fr.base.iofile.attr.SharableAttrMark; -import com.fr.design.constants.UIConstants; import com.fr.design.designer.beans.AdapterBus; import com.fr.design.designer.beans.ComponentAdapter; import com.fr.design.designer.beans.LayoutAdapter; @@ -16,14 +14,11 @@ import com.fr.design.designer.creator.cardlayout.XWTabFitLayout; import com.fr.design.designer.properties.mobile.MobileBooKMarkUsePropertyUI; import com.fr.design.form.layout.FRAbsoluteLayout; import com.fr.design.form.util.FormDesignerUtils; -import com.fr.design.form.util.XCreatorConstants; import com.fr.design.fun.WidgetPropertyUIProvider; -import com.fr.design.icon.IconPathConstants; -import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.CoverReportPane; import com.fr.design.mainframe.EditingMouseListener; import com.fr.design.mainframe.FormArea; import com.fr.design.mainframe.FormDesigner; -import com.fr.design.mainframe.WidgetHelpDialog; import com.fr.design.mainframe.WidgetPropertyPane; import com.fr.form.ui.Connector; import com.fr.form.ui.Widget; @@ -31,26 +26,17 @@ import com.fr.form.ui.container.WAbsoluteLayout; import com.fr.form.ui.container.WAbsoluteLayout.BoundsWidget; import com.fr.form.ui.container.WLayout; import com.fr.general.FRScreen; -import com.fr.general.IOUtils; - -import com.fr.share.ShareConstants; import com.fr.stable.AssistUtils; import com.fr.stable.Constants; -import javax.swing.Icon; -import java.awt.AlphaComposite; import java.awt.Color; -import java.awt.Composite; import java.awt.Cursor; import java.awt.Dimension; import java.awt.Graphics; -import java.awt.Graphics2D; import java.awt.Rectangle; -import java.awt.RenderingHints; import java.awt.Toolkit; import java.awt.event.ContainerEvent; import java.awt.event.MouseEvent; -import java.awt.image.BufferedImage; import java.beans.IntrospectionException; import java.util.ArrayList; import java.util.HashMap; @@ -61,20 +47,14 @@ import java.util.HashMap; */ public class XWAbsoluteLayout extends XLayoutContainer { - private static final int EDIT_BTN_WIDTH = 75; - private static final int EDIT_BTN_HEIGHT = 20; private int minWidth = WLayout.MIN_WIDTH; private int minHeight = WLayout.MIN_HEIGHT; private static final Color OUTER_BORDER_COLOR = new Color(65, 155, 249, 30); private static final Color INNER_BORDER_COLOR = new Color(65, 155, 249); - private static final int BORDER_WIDTH = 1; - private Icon controlMode = IOUtils.readIcon(IconPathConstants.TD_EL_SHARE_HELP_ICON_PATH); //由于屏幕分辨率不同,界面上的容器大小可能不是默认的100%,此时拖入组件时,保存的大小按照100%时的计算 protected double containerPercent = 1.0; - private boolean isHovering = false; - private HashMap xConnectorMap; public XWAbsoluteLayout() { @@ -462,52 +442,10 @@ public class XWAbsoluteLayout extends XLayoutContainer { super.paint(g); //如果鼠标移动到布局内且布局不可编辑,画出编辑蒙层 if (isMouseEnter && !this.editable) { - int x = 0; - int y = 0; - int w = getWidth(); - int h = getHeight(); - - Graphics2D g2d = (Graphics2D) g; - Composite oldComposite = g2d.getComposite(); - //画白色的编辑层 - g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 50 / 100.0F)); - g2d.setColor(XCreatorConstants.COVER_COLOR); - g2d.fillRect(x, y, w, h); - //画编辑按钮所在框 - FormDesigner formDesigner = WidgetPropertyPane.getInstance().getEditingFormDesigner(); - AlphaComposite alphaComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, formDesigner.getCursor().getType() != Cursor.DEFAULT_CURSOR ? 0.9f : 0.7f); - g2d.setColor(XCreatorConstants.EDIT_COLOR); - g2d.setComposite(alphaComposite); - g2d.fillRoundRect((x + w / 2 - EDIT_BTN_WIDTH / 2), (y + h / 2 - EDIT_BTN_HEIGHT / 2), EDIT_BTN_WIDTH, EDIT_BTN_HEIGHT, 4, 4); - g2d.setComposite(oldComposite); - //画编辑按钮图标 - BufferedImage image = IOUtils.readImage(IconPathConstants.EDIT_ICON_PATH); - g2d.drawImage( - image, - (x + w / 2 - 23), - (y + h / 2 - image.getHeight() / 2), - image.getWidth(), - image.getHeight(), - null, - this - ); - g2d.setColor(Color.WHITE); - //画编辑文字 - g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - g2d.drawString(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Edit"), x + w / 2 - 2, y + h / 2 + 5); - g.setColor(XCreatorConstants.FORM_BORDER_COLOR); - GraphHelper.draw(g, new Rectangle(BORDER_WIDTH, BORDER_WIDTH, getWidth() - BORDER_WIDTH * 2, getHeight() - BORDER_WIDTH * 2), Constants.LINE_MEDIUM); - paintExtro(g); - } - } - - public void paintExtro(Graphics g) { - if (this.toData().getWidgetAttrMark(SharableAttrMark.XML_TAG) != null) { - int width = getWidth() - ShareConstants.SHARE_EL_CONTROL_BUTTON_HW; - g.setColor(UIConstants.NORMAL_BACKGROUND); - g.fillArc(width, 0, ShareConstants.SHARE_EL_CONTROL_BUTTON_HW, ShareConstants.SHARE_EL_CONTROL_BUTTON_HW, - 0, 360); - controlMode.paintIcon(this, g, width, 0); + CoverReportPane.paintEditButton(g, this); + if (isShared()) { + CoverReportPane.paintShareButton(g, this); + } } } @@ -529,9 +467,8 @@ public class XWAbsoluteLayout extends XLayoutContainer { * @param e 鼠标点击事件 */ public void respondClick(EditingMouseListener editingMouseListener, MouseEvent e) { - //帮助弹窗 - if (this.isHelpBtnOnFocus()) { - new WidgetHelpDialog(DesignerContext.getDesignerFrame(), this.toData().getDescription()).showWindow(e); + if (this.isShareConfigButtonFocus()) { + CoverReportPane.showShareConfig(this.toData()); return; } FormDesigner designer = editingMouseListener.getDesigner(); diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XWTitleLayout.java b/designer-form/src/main/java/com/fr/design/designer/creator/XWTitleLayout.java index 964f0aa03..7401b5ede 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XWTitleLayout.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XWTitleLayout.java @@ -13,6 +13,7 @@ import com.fr.form.ui.WidgetTitle; import com.fr.form.ui.container.WTitleLayout; import com.fr.general.ComparatorUtils; import com.fr.form.ui.container.WAbsoluteLayout.BoundsWidget; +import com.fr.stable.StringUtils; import java.awt.*; import java.awt.event.ContainerEvent; @@ -190,4 +191,9 @@ public class XWTitleLayout extends DedicateLayoutContainer { return creator.getWidgetPropertyUIProviders(); } + @Override + public void setShareId(String shareId) { + super.setShareId(shareId); + this.getEditingChildCreator().setShareId(shareId); + } } \ No newline at end of file diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardMainBorderLayout.java b/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardMainBorderLayout.java index 5b37ad313..2d5b5ba91 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardMainBorderLayout.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardMainBorderLayout.java @@ -3,9 +3,6 @@ */ package com.fr.design.designer.creator.cardlayout; -import com.fr.base.GraphHelper; -import com.fr.base.iofile.attr.SharableAttrMark; -import com.fr.design.constants.UIConstants; import com.fr.design.designer.beans.AdapterBus; import com.fr.design.designer.beans.ComponentAdapter; import com.fr.design.designer.beans.LayoutAdapter; @@ -16,13 +13,9 @@ import com.fr.design.designer.creator.XCreatorUtils; import com.fr.design.designer.creator.XLayoutContainer; import com.fr.design.designer.creator.XWBorderLayout; import com.fr.design.designer.creator.XWidgetCreator; -import com.fr.design.form.util.XCreatorConstants; -import com.fr.design.icon.IconPathConstants; -import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.CoverReportPane; import com.fr.design.mainframe.EditingMouseListener; import com.fr.design.mainframe.FormDesigner; -import com.fr.design.mainframe.WidgetHelpDialog; -import com.fr.design.mainframe.WidgetPropertyPane; import com.fr.form.event.Listener; import com.fr.form.ui.CardSwitchButton; import com.fr.form.ui.LayoutBorderStyle; @@ -36,25 +29,15 @@ import com.fr.form.ui.container.cardlayout.WCardMainBorderLayout; import com.fr.form.ui.container.cardlayout.WCardTagLayout; import com.fr.form.ui.container.cardlayout.WCardTitleLayout; import com.fr.general.ComparatorUtils; -import com.fr.general.IOUtils; import com.fr.general.act.BorderPacker; -import com.fr.share.ShareConstants; -import com.fr.stable.Constants; -import javax.swing.Icon; -import java.awt.AlphaComposite; -import java.awt.Color; import java.awt.Component; -import java.awt.Composite; import java.awt.Cursor; import java.awt.Dimension; import java.awt.Graphics; -import java.awt.Graphics2D; import java.awt.Rectangle; -import java.awt.RenderingHints; import java.awt.event.MouseEvent; -import java.awt.image.BufferedImage; import java.util.ArrayList; import java.util.List; @@ -67,15 +50,10 @@ import java.util.List; */ public class XWCardMainBorderLayout extends XWBorderLayout { - private Icon controlMode = IOUtils.readIcon(IconPathConstants.TD_EL_SHARE_HELP_ICON_PATH); private static final int CENTER = 1; private static final int NORTH = 0; private static final int TITLE_STYLE = 2; - private static final int EDIT_BTN_WIDTH = 75; - private static final int EDIT_BTN_HEIGHT = 20; - private static final int BORDER_WIDTH = 1; - private final int CARDMAINLAYOUT_CHILD_COUNT = 1; /** @@ -358,53 +336,10 @@ public class XWCardMainBorderLayout extends XWBorderLayout { super.paint(g); //如果鼠标移动到布局内且布局不可编辑,画出编辑蒙层 if (isMouseEnter && !editable) { - int x = 0; - int y = 0; - int w = getWidth(); - int h = getHeight(); - - Graphics2D g2d = (Graphics2D) g; - Composite oldComposite = g2d.getComposite(); - //画白色的编辑层 - g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 50 / 100.0F)); - g2d.setColor(XCreatorConstants.COVER_COLOR); - g2d.fillRect(x, y, w, h); - //画编辑按钮所在框 - FormDesigner formDesigner = WidgetPropertyPane.getInstance().getEditingFormDesigner(); - AlphaComposite alphaComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, formDesigner.getCursor().getType() != Cursor.DEFAULT_CURSOR ? 0.9f : 0.7f); - g2d.setColor(XCreatorConstants.EDIT_COLOR); - g2d.setComposite(alphaComposite); - g2d.fillRoundRect((x + w / 2 - EDIT_BTN_WIDTH / 2), (y + h / 2 - EDIT_BTN_HEIGHT / 2), EDIT_BTN_WIDTH, EDIT_BTN_HEIGHT, 4, 4); - g2d.setComposite(oldComposite); - - //画编辑按钮图标 - BufferedImage image = IOUtils.readImage(IconPathConstants.EDIT_ICON_PATH); - g2d.drawImage( - image, - (x + w / 2 - 23), - (y + h / 2 - image.getHeight() / 2), - image.getWidth(), - image.getHeight(), - null, - this - ); - g2d.setColor(Color.WHITE); - //画编辑文字 - g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - g2d.drawString(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Edit"), x + w / 2 - 2, y + h / 2 + 5); - g.setColor(XCreatorConstants.FORM_BORDER_COLOR); - GraphHelper.draw(g, new Rectangle(BORDER_WIDTH, BORDER_WIDTH, getWidth() - BORDER_WIDTH * 2, getHeight() - BORDER_WIDTH * 2), Constants.LINE_MEDIUM); - paintExtro(g); - } - } - - public void paintExtro(Graphics g) { - if (this.toData().getWidgetAttrMark(SharableAttrMark.XML_TAG) != null) { - int width = getWidth() - ShareConstants.SHARE_EL_CONTROL_BUTTON_HW; - g.setColor(UIConstants.NORMAL_BACKGROUND); - g.fillArc(width, 0, ShareConstants.SHARE_EL_CONTROL_BUTTON_HW, ShareConstants.SHARE_EL_CONTROL_BUTTON_HW, - 0, 360); - controlMode.paintIcon(this, g, width, 0); + CoverReportPane.paintEditButton(g, this); + if (isShared()) { + CoverReportPane.paintShareButton(g, this); + } } } @@ -423,9 +358,8 @@ public class XWCardMainBorderLayout extends XWBorderLayout { */ @Override public void respondClick(EditingMouseListener editingMouseListener, MouseEvent e){ - //帮助弹窗 - if (this.isHelpBtnOnFocus()) { - new WidgetHelpDialog(DesignerContext.getDesignerFrame(), this.toData().getDescription()).showWindow(e); + if (this.isShareConfigButtonFocus()) { + CoverReportPane.showShareConfig(this.toData()); return; } FormDesigner designer = editingMouseListener.getDesigner(); diff --git a/designer-form/src/main/java/com/fr/design/gui/controlpane/EventPropertyPane.java b/designer-form/src/main/java/com/fr/design/gui/controlpane/EventPropertyPane.java new file mode 100644 index 000000000..cc3f34669 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/gui/controlpane/EventPropertyPane.java @@ -0,0 +1,533 @@ +package com.fr.design.gui.controlpane; + + +import com.fr.design.beans.BasicBeanPane; +import com.fr.design.constants.UIConstants; +import com.fr.design.designer.creator.XCreator; +import com.fr.design.designer.properties.EventPropertyTable; +import com.fr.design.gui.icontainer.UIScrollPane; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.gui.ilist.JNameEdList; +import com.fr.design.gui.ilist.ListModelElement; +import com.fr.design.gui.ilist.ModNameActionListener; +import com.fr.design.gui.ilist.UINameEdList; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.FormDesigner; +import com.fr.design.widget.EventCreator; +import com.fr.form.event.Listener; +import com.fr.form.ui.Widget; +import com.fr.general.NameObject; +import com.fr.report.web.util.ReportEngineEventMapping; +import com.fr.stable.ArrayUtils; +import com.fr.stable.Nameable; +import javax.swing.BorderFactory; +import javax.swing.DefaultListModel; +import javax.swing.JPanel; +import javax.swing.ListSelectionModel; +import javax.swing.event.ListDataEvent; +import javax.swing.event.ListDataListener; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +/** + * Created by kerry on 5/17/21 + */ +public class EventPropertyPane extends UIControlPane implements ListControlPaneProvider { + private XCreator creator; + private boolean isPopulating = false; + private UINameEdList selectNameEdList; + + private Map nameEdListMap = new HashMap<>(); + + private CommonShortCutHandlers commonHandlers; + + private ListControlPaneHelper helper; + + private JPanel contentPane; + + private FormDesigner designer; + + + private ListControlPaneHelper getHelper() { + if (helper == null) { + helper = ListControlPaneHelper.newInstance(this); + } + return helper; + } + + private CommonShortCutHandlers getCommonHandlers() { + if (commonHandlers == null) { + commonHandlers = CommonShortCutHandlers.newInstance(this); + } + return commonHandlers; + } + + + public EventPropertyPane(FormDesigner designer) { + super(); + this.designer = designer; + } + + + @Override + protected void initLeftPane(JPanel leftPane) { + leftPane.add(new UIScrollPane(contentPane = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, FlowLayout.LEADING, 0, 0)), BorderLayout.CENTER); + } + + /** + * 刷新 + */ + public void refresh() { + int selectionSize = designer.getSelectionModel().getSelection().size(); + if (selectionSize == 0 || selectionSize == 1) { + this.creator = selectionSize == 0 ? designer.getRootComponent() : designer.getSelectionModel() + .getSelection().getSelectedCreator(); + } else { + this.creator = null; + contentPane.removeAll(); + checkButtonEnabled(); + return; + } + Widget widget = creator.toData(); + + refreshContentPane(widget.supportedEvents()); + refreshNameableCreator(EventCreator.createEventCreator(widget.supportedEvents(), EventPropertyTable.WidgetEventListenerUpdatePane.class)); + populateNameObjects(); + } + + + private void refreshContentPane(String[] supportedEvents) { + for (String event : supportedEvents) { + if (nameEdListMap.containsKey(event)) { + continue; + } + UINameEdList list = createJNameList(event); + EventListWrapperPane wrapperPane = new EventListWrapperPane(switchLang(event), list); + if (this.selectNameEdList == null) { + this.selectNameEdList = wrapperPane.getNameEdList(); + } + contentPane.add(wrapperPane); + nameEdListMap.put(event, wrapperPane); + } + } + + public void populateNameObjects() { + Widget widget = creator.toData(); + + ArrayList nameObjectList = new ArrayList<>(); + for (int i = 0, size = widget.getListenerSize(); i < size; i++) { + Listener listener = widget.getListener(i); + if (!listener.isDefault()) { + nameObjectList.add(i, new NameObject(switchLang(listener.getEventName()) + (i + 1), listener)); + } + } + populate(getHelper().processCatalog(nameObjectList)); + checkButtonEnabled(); + this.repaint(); + } + + public void populate(Map> map) { + isPopulating = true; // 加一个标识位,避免切换单元格时,触发 saveSettings + Iterator>> iterator = map.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry> entry = iterator.next(); + List valueList = entry.getValue(); + EventListWrapperPane eventListWrapperPane = nameEdListMap.get(entry.getKey()); + populateChildNameList(eventListWrapperPane.getNameEdList(), valueList.toArray(new NameObject[valueList.size()])); + } + this.checkButtonEnabled(); + refreshEventListWrapperPane(); + isPopulating = false; + } + + private void refreshEventListWrapperPane() { + Iterator> iterator = nameEdListMap.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry entry = iterator.next(); + EventListWrapperPane eventListWrapperPane = entry.getValue(); + UINameEdList nameEdList = eventListWrapperPane.getNameEdList(); + int listSize = nameEdList.getModel().getSize(); + if (this.selectNameEdList.getModel().getSize() == 0 && listSize > 0) { + this.selectNameEdList = nameEdList; + } + eventListWrapperPane.setVisible(listSize > 0); + } + this.selectNameEdList.setSelectedIndex(0); + this.repaint(); + } + + + private void populateChildNameList(UINameEdList nameableList, Nameable[] nameableArray) { + nameableList.getCellEditor().stopCellEditing(); + DefaultListModel listModel = (DefaultListModel) nameableList.getModel(); + listModel.removeAllElements(); + if (ArrayUtils.isEmpty(nameableArray)) { + isPopulating = false; + return; + } + + listModel.setSize(nameableArray.length); + for (int i = 0; i < nameableArray.length; i++) { + listModel.set(i, new ListModelElement(nameableArray[i])); + } + + } + + + protected UINameEdList createJNameList(String text) { + UINameEdList nameEdList = new UINameEdList(new DefaultListModel()) { + @Override + protected void doAfterLostFocus() { + ((JControlUpdatePane) controlUpdatePane).update(); + } + + @Override + protected void doAfterStopEditing() { + saveSettings(); + } + }; + + nameEdList.setCellRenderer(new UINameableListCellRenderer(true, this.creators)); + nameEdList.setName(text); + nameEdList.setSelectionBackground(UIConstants.ATTRIBUTE_PRESS); + nameEdList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); + nameEdList.addMouseListener(getHelper().getListMouseListener(nameEdList, this)); + nameEdList.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + selectNameEdList = nameEdList; + updateUINameListSelect(); + } + }); + nameEdList.addModNameActionListener(new ModNameActionListener() { + @Override + public void nameModed(int index, String oldName, String newName) { + saveSettings(); + } + }); + nameEdList.addListSelectionListener(new ListSelectionListener() { + public void valueChanged(ListSelectionEvent evt) { + // richie:避免多次update和populate大大降低效率 + if (!evt.getValueIsAdjusting() && !isPopulating) { + // shoc 切换的时候加检验 + if (hasInvalid(false)) { + return; + } + ((JControlUpdatePane) EventPropertyPane.this.controlUpdatePane).update(); + ((JControlUpdatePane) EventPropertyPane.this.controlUpdatePane).populate(); + EventPropertyPane.this.checkButtonEnabled(); + } + } + }); + nameEdList.getModel().addListDataListener(new ListDataListener() { + @Override + public void intervalAdded(ListDataEvent e) { + saveSettings(); + } + + @Override + public void intervalRemoved(ListDataEvent e) { + saveSettings(); + } + + @Override + public void contentsChanged(ListDataEvent e) { + saveSettings(); + } + }); + return nameEdList; + } + + private void updateUINameListSelect() { + Iterator> iterator = nameEdListMap.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry entry = iterator.next(); + UINameEdList nameEdList = entry.getValue().getNameEdList(); + if (nameEdList != selectNameEdList) { + nameEdList.clearSelection(); + } + } + } + + @Override + public void checkButtonEnabled() { + getHelper().checkButtonEnabled(); + } + + + + private String switchLang(String eventName) { + // 在 properties 文件中找到相应的 key 值 + String localeKey = ReportEngineEventMapping.getLocaleName(eventName); + return com.fr.design.i18n.Toolkit.i18nText(localeKey); + } + + /** + * 更新控件事件 + * + * @param creator 控件 + */ + public void updateWidgetListener(XCreator creator) { + (creator.toData()).clearListeners(); + Nameable[] res = this.update(); + for (int i = 0; i < res.length; i++) { + NameObject nameObject = (NameObject) res[i]; + (creator.toData()).addListener((Listener) nameObject.getObject()); + } + + designer.fireTargetModified(); + checkButtonEnabled(); + } + + + /** + * 生成不重复的名字 + * + * @param prefix 名字前缀 + * @return 名字 + */ + @Override + public String createUnrepeatedName(String prefix) { + return getCommonHandlers().createUnrepeatedName(prefix); + } + + private void updateSelectedNameList(NameableCreator creator) { + String eventName = ((EventCreator) creator).getEventName(); + EventListWrapperPane wrapperPane = nameEdListMap.get(eventName); + wrapperPane.setVisible(true); + setSelectNameEdList(wrapperPane.getNameEdList()); + } + + private void setSelectNameEdList(UINameEdList nameEdList) { + if (this.selectNameEdList != null) { + this.selectNameEdList.clearSelection(); + } + this.selectNameEdList = nameEdList; + } + + @Override + public void onAddItem(NameableCreator creator) { + updateSelectedNameList(creator); + getCommonHandlers().onAddItem(creator); + } + + @Override + public void onRemoveItem() { + getCommonHandlers().onRemoveItem(); + refreshEventListWrapperPane(); + } + + @Override + public void onCopyItem() { + getCommonHandlers().onCopyItem(); + } + + @Override + public void onMoveUpItem() { + getCommonHandlers().onMoveUpItem(); + } + + @Override + public void onMoveDownItem() { + getCommonHandlers().onMoveDownItem(); + } + + @Override + public void onSortItem(boolean isAtoZ) { + Iterator> iterator = nameEdListMap.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry entry = iterator.next(); + UINameEdList nameEdList = entry.getValue().getNameEdList(); + getCommonHandlers().onSortItem(isAtoZ, nameEdList); + } + + } + + @Override + public boolean isItemSelected() { + return getModel().getSize() > 0 && getSelectedIndex() != -1; + } + + + @Override + protected JPanel createControlUpdatePane() { + return JControlUpdatePane.newInstance(this); + } + + + @Override + public Nameable[] update() { + java.util.List res = new java.util.ArrayList(); + getControlUpdatePane().update(); + Iterator> iterator = nameEdListMap.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry entry = iterator.next(); + UINameEdList nameEdList = entry.getValue().getNameEdList(); + DefaultListModel listModel = (DefaultListModel) nameEdList.getModel(); + for (int i = 0, len = listModel.getSize(); i < len; i++) { + res.add(((ListModelElement) listModel.getElementAt(i)).wrapper); + } + } + return res.toArray(new Nameable[0]); + } + + + @Override + public NameableCreator[] createNameableCreators() { + return new NameableCreator[]{ + new EventCreator(Widget.EVENT_STATECHANGE, EventPropertyTable.WidgetEventListenerUpdatePane.class) + }; + } + + @Override + public void saveSettings() { + if (isPopulating) { + return; + } + updateWidgetListener(creator); + } + + @Override + protected String title4PopupWindow() { + return "Event"; + } + + @Override + public String getAddItemText() { + return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Add_Event"); + } + + public BasicBeanPane createPaneByCreators(NameableCreator creator) { + try { + return creator.getUpdatePane().newInstance(); + } catch (InstantiationException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + } + + public BasicBeanPane createPaneByCreators(NameableCreator creator, String string) { + Constructor constructor = null; + try { + constructor = creator.getUpdatePane().getDeclaredConstructor(new Class[]{String.class}); + constructor.setAccessible(true); + return (BasicBeanPane) constructor.newInstance(string); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } catch (InstantiationException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } catch (InvocationTargetException e) { + throw new RuntimeException(e); + } + } + + @Override + public DefaultListModel getModel() { + if (this.selectNameEdList == null) { + return new DefaultListModel(); + } + return (DefaultListModel) this.selectNameEdList.getModel(); + } + + /** + * 检查是否符合规范 + * + * @throws Exception + */ + @Override + public void checkValid() throws Exception { + ((JControlUpdatePane) this.controlUpdatePane).checkValid(); + } + + @Override + public boolean hasInvalid(boolean isAdd) { + return getHelper().hasInvalid(isAdd); + } + + public void addNameable(Nameable nameable, int index) { + getHelper().addNameable(nameable, index); + popupEditDialog(); + } + + + /** + * 设置选中项 + * + * @param index 选中项的序列号 + */ + public void setSelectedIndex(int index) { + if (this.selectNameEdList != null) { + this.selectNameEdList.setSelectedIndex(index); + + } + } + + @Override + public int getSelectedIndex() { + if (this.selectNameEdList == null) { + return -1; + } + return this.selectNameEdList.getSelectedIndex(); + } + + + @Override + public ListModelElement getSelectedValue() { + if (this.selectNameEdList == null) { + return null; + } + return (ListModelElement) this.selectNameEdList.getSelectedValue(); + } + + @Override + public JControlUpdatePane getControlUpdatePane() { + return (JControlUpdatePane) controlUpdatePane; + } + + @Override + public JNameEdList getNameableList() { + return this.selectNameEdList; + } + + private void popupEditDialog() { + getHelper().popupEditDialog(null, this.selectNameEdList, this); + } + + + private class EventListWrapperPane extends JPanel { + private UINameEdList nameEdList; + + public EventListWrapperPane(String labelText, UINameEdList nameEdList) { + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + UILabel label = new UILabel(labelText + Toolkit.i18nText("Fine-Design_Report_Event")); + label.setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 0)); + label.setBackground(Color.decode("#FFFFFF")); + label.setPreferredSize(new Dimension(226, 26)); + this.nameEdList = nameEdList; + this.add(label, BorderLayout.NORTH); + this.add(this.nameEdList, BorderLayout.CENTER); + } + + public UINameEdList getNameEdList() { + return this.nameEdList; + } + + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/CoverPane.java b/designer-form/src/main/java/com/fr/design/mainframe/CoverPane.java index a4c401440..f63c43055 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/CoverPane.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/CoverPane.java @@ -13,13 +13,12 @@ import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Component; import java.awt.Composite; -import java.awt.Container; import java.awt.Cursor; -import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; -import java.awt.LayoutManager; import java.awt.Rectangle; +import java.awt.RenderingHints; +import java.awt.image.BufferedImage; /** @@ -29,29 +28,52 @@ import java.awt.Rectangle; * Time: 上午9:09 */ public class CoverPane extends JComponent { - - private UIButton editButton; private AlphaComposite composite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f); - private static final int BORDER_WIDTH = 2; - private static final Color COVER_COLOR = new Color(216, 242, 253); - private static final int EDIT_BTN_WIDTH = 75; - private static final int EDIT_BTN_HEIGHT = 20; + protected static final int BORDER_WIDTH = 2; + public static final int EDIT_BTN_W = 75; + public static final int EDIT_BTN_H = 20; + + public static void paintEditButton(Graphics g, Component component) { + int x = 0; + int y = 0; + int w = component.getWidth(); + int h = component.getHeight(); + + Graphics2D g2d = (Graphics2D) g; + Composite oldComposite = g2d.getComposite(); + //画白色的编辑层 + g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 50 / 100.0F)); + g2d.setColor(XCreatorConstants.COVER_COLOR); + g2d.fillRect(x, y, w, h); + //画编辑按钮所在框 + FormDesigner formDesigner = WidgetPropertyPane.getInstance().getEditingFormDesigner(); + AlphaComposite alphaComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, formDesigner.getCursor().getType() != Cursor.DEFAULT_CURSOR ? 0.9f : 0.7f); + g2d.setColor(XCreatorConstants.EDIT_COLOR); + g2d.setComposite(alphaComposite); + g2d.fillRoundRect((x + w / 2 - EDIT_BTN_W / 2), (y + h / 2 - EDIT_BTN_H / 2), EDIT_BTN_W, EDIT_BTN_H, 4, 4); + g2d.setComposite(oldComposite); + //画编辑按钮图标 + BufferedImage image = IOUtils.readImage(IconPathConstants.EDIT_ICON_PATH); + g2d.drawImage( + image, + (x + w / 2 - 23), + (y + h / 2 - image.getHeight() / 2), + image.getWidth(), + image.getHeight(), + null + ); + g2d.setColor(Color.WHITE); + //画编辑文字 + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2d.drawString(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Edit"), x + w / 2 - 2, y + h / 2 + 5); + + g.setColor(XCreatorConstants.FORM_BORDER_COLOR); + GraphHelper.draw(g, new Rectangle(BORDER_WIDTH, BORDER_WIDTH, w - BORDER_WIDTH * 2, h - BORDER_WIDTH * 2), Constants.LINE_MEDIUM); + } public CoverPane() { - setLayout(getCoverLayout()); setBackground(null); setOpaque(false); - - editButton = new UIButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Edit"), IOUtils.readIcon(IconPathConstants.EDIT_ICON_PATH)) { - @Override - public Dimension getPreferredSize() { - return new Dimension(60, 24); - } - }; - editButton.setBorderPainted(false); - editButton.setExtraPainted(false); - editButton.setForeground(Color.WHITE); - add(editButton); } public AlphaComposite getComposite() { @@ -62,72 +84,9 @@ public class CoverPane extends JComponent { this.composite = composite; } - public UIButton getEditButton() { - return editButton; - } - - public void setEditButton(UIButton editButton) { - this.editButton = editButton; - } - - protected LayoutManager getCoverLayout() { - return new LayoutManager() { - - @Override - public void removeLayoutComponent(Component comp) { - } - - @Override - public Dimension preferredLayoutSize(Container parent) { - return parent.getPreferredSize(); - } - - @Override - public Dimension minimumLayoutSize(Container parent) { - return null; - } - - @Override - public void layoutContainer(Container parent) { - int width = parent.getParent().getWidth(); - int height = parent.getParent().getHeight(); - int preferWidth = editButton.getPreferredSize().width; - int preferHeight = editButton.getPreferredSize().height; - editButton.setBounds((width - preferWidth) / 2, (height - preferHeight) / 2, preferWidth, preferHeight); - } - - @Override - public void addLayoutComponent(String name, Component comp) { - } - }; - } - public void paint(Graphics g) { - int x = 0; - int y = 0; - int w = getWidth(); - int h = getHeight(); - Graphics2D g2d = (Graphics2D) g; - Composite oldComposite = g2d.getComposite(); - g2d.setComposite(composite); - g2d.setColor(COVER_COLOR); - g2d.fillRect(0, 0, getWidth(), getHeight()); - FormDesigner formDesigner = WidgetPropertyPane.getInstance().getEditingFormDesigner(); - g2d.setColor(XCreatorConstants.EDIT_COLOR); - boolean editHover = formDesigner.getCursor().getType() != Cursor.DEFAULT_CURSOR; - AlphaComposite alphaComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, editHover ? 0.9f : 0.7f); - g2d.setComposite(alphaComposite); - g2d.fillRoundRect((x + w / 2 - EDIT_BTN_WIDTH / 2), (y + h / 2 - EDIT_BTN_HEIGHT / 2), EDIT_BTN_WIDTH, EDIT_BTN_HEIGHT, 4, 4); - g2d.setComposite(oldComposite); - g.setColor(XCreatorConstants.FORM_BORDER_COLOR); - GraphHelper.draw(g, getPaintBorderBounds(), Constants.LINE_MEDIUM); - - super.paint(g); - } - - protected Rectangle getPaintBorderBounds(){ - return new Rectangle(BORDER_WIDTH, BORDER_WIDTH, getWidth() - BORDER_WIDTH * 2 , getHeight() - BORDER_WIDTH * 2); + paintEditButton(g, this); } } diff --git a/designer-form/src/main/java/com/fr/design/mainframe/CoverReportPane.java b/designer-form/src/main/java/com/fr/design/mainframe/CoverReportPane.java index d976691c6..14b8aed7a 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/CoverReportPane.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/CoverReportPane.java @@ -1,18 +1,20 @@ package com.fr.design.mainframe; -import com.fr.design.constants.UIConstants; -import com.fr.design.gui.ibutton.UIButton; -import com.fr.design.icon.IconPathConstants; -import com.fr.share.ShareConstants; -import com.fr.general.FRScreen; -import com.fr.general.IOUtils; -import com.fr.stable.StringUtils; - -import javax.swing.*; -import java.awt.*; -import java.awt.event.MouseEvent; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; +import com.fr.base.BaseUtils; +import com.fr.design.dialog.BasicPane; +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.share.constants.ShareEntryKey; +import com.fr.form.ui.Widget; +import com.fr.stable.Constants; +import com.fr.stable.bridge.StableFactory; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.image.BufferedImage; +import java.util.HashMap; /** * 报表块的封面(如果后面所有的组件都有帮助信息的话就抽接口吧) @@ -20,123 +22,61 @@ import java.awt.event.WindowEvent; * Date: 2016/11/2 * Time: 11:32 */ -public class CoverReportPane extends CoverPane implements HelpDialogHandler{ - private static final int BORDER_WIDTH = 1; - private Icon controlMode = IOUtils.readIcon(IconPathConstants.TD_EL_SHARE_HELP_ICON_PATH); - private JComponent controlButton = new JComponent() { - protected void paintComponent(Graphics g) { - g.setColor(UIConstants.NORMAL_BACKGROUND); - g.fillArc(0, 0, ShareConstants.SHARE_EL_CONTROL_BUTTON_HW, ShareConstants.SHARE_EL_CONTROL_BUTTON_HW, - 0, 360); - controlMode.paintIcon(this, g, 0, 0); - } - }; - - - private String helpMsg;//帮助信息(后续帮助信息可能会变成标配,就直接放这边了) - - private WidgetHelpDialog helpDialog = null; - - public CoverReportPane() { - this(StringUtils.EMPTY); - } - - public CoverReportPane(String helpMsg) { - super(); - this.helpMsg = helpMsg; +public class CoverReportPane extends CoverPane{ + public static final int SHARE_CONF_BTN_W = 90; + public static final int SHARE_CONF_BTN_H = 24; + + public static final Color SHARE_BTN_BG = new Color(152, 193, 250); + + public static void showShareConfig(Widget widget) { + Object[] compositeArg = new Object[]{widget}; + HashMap compoClass = new HashMap(); + compoClass.put(Constants.ARG_0, Widget.class); + BasicPane shareGuidePane = StableFactory.getMarkedInstanceObjectFromClass(ShareEntryKey.SHARE_CONFIG, compositeArg, compoClass, BasicPane.class); + shareGuidePane.show(); } - public String getHelpMsg() { - return helpMsg; + public static void paintShareButton(Graphics g, Component component) { + int x = component.getWidth() - SHARE_CONF_BTN_W; + int y = 0; + + Graphics2D g2d = (Graphics2D) g; + g2d.setColor(SHARE_BTN_BG); + g2d.fillRoundRect(x ,y, SHARE_CONF_BTN_W, SHARE_CONF_BTN_H,5,5); + g2d.setColor(Color.WHITE); + + // 画配置文字 + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2d.drawString(Toolkit.i18nText("Fine-Design_Share_Help_Settings"),x + 30, 17); + // 画图标 + BufferedImage image = BaseUtils.readImage("com/fr/base/images/share/config.png"); + g2d.drawImage(image, x + 10, 5, image.getWidth(), image.getHeight(), null); } - public void setHelpMsg(String helpMsg) { - this.helpMsg = helpMsg; - //帮助信息为空就不显示帮助按钮 - if (StringUtils.isNotEmpty(helpMsg)) { - add(controlButton); - } - } + private boolean isShared = false; - public void setMsgDisplay(MouseEvent e) { - if (helpDialog == null) { -// controlMode = IOUtils.readIcon(IconPathConstants.TD_EL_SHARE_CLOSE_ICON_PATH); - controlButton.setVisible(false); - helpDialog = new WidgetHelpDialog(DesignerContext.getDesignerFrame(), helpMsg); - double screenValue = FRScreen.getDesignScreenByDimension(Toolkit.getDefaultToolkit().getScreenSize()).getValue(); - int offsetX = 0; - if (screenValue < FormArea.DEFAULT_SLIDER) { - offsetX = (int) ((1 - screenValue / FormArea.DEFAULT_SLIDER) - * WidgetPropertyPane.getInstance().getEditingFormDesigner().getRootComponent().getWidth() / 2); - } - int rX = WestRegionContainerPane.getInstance().getWidth() + e.getX() + offsetX - 227;//弹出框宽度190加上图标的宽度27加上10的偏移 - int rY = 165 + e.getY();//165是设计器最上面几个面板的高度 - helpDialog.setLocationRelativeTo(DesignerContext.getDesignerFrame(), rX, rY); - helpDialog.showWindow(); - helpDialog.addWindowListener(new WindowAdapter() { - @Override - public void windowClosed(WindowEvent e) { - helpDialog = null; - controlButton.setVisible(true); - } - }); - HelpDialogManager.getInstance().setPane(this); - } + public CoverReportPane() { + this(false); } - protected LayoutManager getCoverLayout() { - return new LayoutManager() { - - @Override - public void removeLayoutComponent(Component comp) { - } - - @Override - public Dimension preferredLayoutSize(Container parent) { - return parent.getPreferredSize(); - } - - @Override - public Dimension minimumLayoutSize(Container parent) { - return null; - } - - @Override - public void layoutContainer(Container parent) { - UIButton editButton = getEditButton(); - int width = parent.getParent().getWidth(); - int height = parent.getParent().getHeight(); - int preferWidth = editButton.getPreferredSize().width; - int preferHeight = editButton.getPreferredSize().height; - editButton.setBounds((width - preferWidth) / 2, (height - preferHeight) / 2, preferWidth, preferHeight); - controlButton.setBounds((width - 28), 0, 27, 27); - } - - @Override - public void addLayoutComponent(String name, Component comp) { - } - }; + public CoverReportPane(boolean shared) { + super(); + isShared = shared; } - public void destroyHelpDialog() { - if (helpDialog != null) { - controlMode = IOUtils.readIcon(IconPathConstants.TD_EL_SHARE_HELP_ICON_PATH); - controlButton.repaint(); - helpDialog.dispose(); - helpDialog = null; - } + public boolean isShared() { + return isShared; } - @Override - protected Rectangle getPaintBorderBounds(){ - return new Rectangle(BORDER_WIDTH, BORDER_WIDTH, getWidth() - 3 * BORDER_WIDTH , getHeight() - 3 * BORDER_WIDTH); + public void setShared(boolean shared) { + isShared = shared; } @Override - public void setVisible(boolean aFlag) { - super.setVisible(aFlag); -// if (aFlag) { -// HelpDialogManager.getInstance().setPane(this); -// } + public void paint(Graphics g) { + super.paint(g); + if (isShared()) { + paintShareButton(g, this); + } } } diff --git a/designer-form/src/main/java/com/fr/design/mainframe/EditingMouseListener.java b/designer-form/src/main/java/com/fr/design/mainframe/EditingMouseListener.java index 524dd8bf1..fd1236091 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/EditingMouseListener.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/EditingMouseListener.java @@ -11,6 +11,7 @@ import com.fr.design.designer.beans.location.Direction; import com.fr.design.designer.beans.location.Location; import com.fr.design.designer.beans.models.SelectionModel; import com.fr.design.designer.beans.models.StateModel; +import com.fr.design.designer.creator.XBorderStyleWidgetCreator; import com.fr.design.designer.creator.XChartEditor; import com.fr.design.designer.creator.XCreator; import com.fr.design.designer.creator.XCreatorUtils; @@ -28,9 +29,7 @@ import com.fr.design.icon.IconPathConstants; import com.fr.design.utils.ComponentUtils; import com.fr.design.utils.gui.GUICoreUtils; import com.fr.design.utils.gui.LayoutUtils; -import com.fr.share.ShareConstants; import com.fr.stable.Constants; -import com.fr.stable.StringUtils; import javax.swing.BorderFactory; import javax.swing.JComponent; @@ -41,6 +40,7 @@ import javax.swing.event.MouseInputAdapter; import java.awt.Color; import java.awt.Container; import java.awt.Cursor; +import java.awt.Insets; import java.awt.Rectangle; import java.awt.event.MouseEvent; @@ -106,10 +106,10 @@ public class EditingMouseListener extends MouseInputAdapter { private int minDragSize = 5; private int minMoveSize = 8; - private static final int EDIT_BTN_WIDTH = 60; - private static final int EDIT_BTN_HEIGHT = 24; + private static final Insets DEEFAULT_INSETS = new Insets(0,0,0,0); + //报表块的编辑按钮不灵敏,范围扩大一点 - private static final int GAP = 10; + private static final int GAP = 5; private XElementCase xElementCase; private XChartEditor xChartEditor; @@ -353,62 +353,48 @@ public class EditingMouseListener extends MouseInputAdapter { } - private void elementCaseMouseMoved(MouseEvent e, XCreator component) { - xElementCase = (XElementCase) component; - UIButton button = (UIButton) xElementCase.getCoverPane().getComponent(0); - if (designer.getCursor().getType() == Cursor.HAND_CURSOR) { - designer.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); - } // component.getParent() 是报表块所在的XWTitleLayout - int minX = button.getX() + getParentPositionX(component, 0) - designer.getHorizontalScaleValue(); - int minY = button.getY() + getParentPositionY(component, 0) - designer.getVerticalScaleValue() + xElementCase.getY(); - if (e.getX() + GAP - xElementCase.getInsets().left > minX && e.getX() - GAP - xElementCase.getInsets().left < minX + button.getWidth()) { - if (e.getY() + GAP - xElementCase.getInsets().top > minY && e.getY() - GAP - xElementCase.getInsets().top < minY + button.getHeight()) { - designer.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + private boolean isShareConfigButton(MouseEvent e, XCreator component, Insets insets) { + if (component.isShared()) { + int minX = getParentPositionX(component, component.getX()) + component.getWidth() - insets.right - CoverReportPane.SHARE_CONF_BTN_W - designer.getHorizontalScaleValue(); + int maxX = minX + CoverReportPane.SHARE_CONF_BTN_W; + int minY = getParentPositionY(component, component.getY()) + insets.top - designer.getVerticalScaleValue(); + int maxY = minY + CoverReportPane.SHARE_CONF_BTN_H; + + if ((e.getX() > minX - GAP) && e.getX() < maxX + GAP) { + if (e.getY() > minY - GAP && e.getY() < maxY + GAP) { + return true; + } } } - setHelpBtnFocus(e, xElementCase); + return false; } - private void setHelpBtnFocus(MouseEvent e, XCreator component) { - component.setHelpBtnOnFocus(false); - if (component.getCoverPane() != null) { - if (component.getCoverPane().getComponentCount() > 1) { - JComponent button1 = (JComponent) component.getCoverPane().getComponent(1); - int minX1 = button1.getX() + getParentPositionX(component, 0) - designer.getHorizontalScaleValue(); - int minY1 = button1.getY() + getParentPositionY(component, 0) - designer.getVerticalScaleValue() + component.getY(); - if (e.getX() + GAP - component.getInsets().left > minX1 && e.getX() - GAP - component.getInsets().left < minX1 + button1.getWidth()) { - if (e.getY() + GAP - component.getInsets().top > minY1 && e.getY() - GAP - component.getInsets().top < minY1 + button1.getHeight()) { - designer.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); - component.setHelpBtnOnFocus(true); - } - } - } - component.displayCoverPane(true); - component.setDirections(Direction.TOP_BOTTOM_LEFT_RIGHT); - } else { - //没有帮助信息时,不显示帮助图标 - if (StringUtils.isEmpty(component.toData().getDescription())) { - return; - } - int minX1 = getParentPositionX(component, component.getX()) + component.getWidth() - ShareConstants.SHARE_EL_CONTROL_BUTTON_HW - designer.getHorizontalScaleValue(); - int minY1 = getParentPositionY(component, component.getY()) - designer.getVerticalScaleValue(); - if (e.getX() + GAP - component.getInsets().left > minX1 && e.getX() - GAP - component.getInsets().left < minX1 + ShareConstants.SHARE_EL_CONTROL_BUTTON_HW) { - if (e.getY() + GAP - component.getInsets().top > minY1 && e.getY() - GAP - component.getInsets().top < minY1 + ShareConstants.SHARE_EL_CONTROL_BUTTON_HW) { - designer.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); - component.setHelpBtnOnFocus(true); - } + private boolean isEditButton(MouseEvent e, XCreator component, Insets insets) { + int innerWidth = component.getWidth() - insets.left - insets.right; + int innerHeight = component.getHeight() - insets.top - insets.bottom; + + int minX = getParentPositionX(component, component.getX()) + insets.left + (innerWidth - CoverReportPane.EDIT_BTN_W) / 2 - designer.getHorizontalScaleValue(); + int maxX = minX + CoverReportPane.EDIT_BTN_W; + int minY = getParentPositionY(component, component.getY()) + insets.top + (innerHeight - CoverReportPane.EDIT_BTN_H) / 2 - designer.getVerticalScaleValue(); + int maxY = minY + CoverReportPane.EDIT_BTN_H; + if (e.getX() > minX - GAP && e.getX() < maxX + GAP) { + if (e.getY() > minY - GAP && e.getY() < maxY + GAP) { + return true; } } + return false; } - private void setCoverPaneNotDisplay(XCreator component, MouseEvent e, boolean isLinkedHelpDialog) { + private void elementCaseMouseMoved(MouseEvent e, XCreator component) { + xElementCase = (XElementCase) component; + component.displayCoverPane(true); + processCoverMouseMove(component, e); + } + private void setCoverPaneNotDisplay(XCreator component, MouseEvent e, boolean isLinkedHelpDialog) { if (xChartEditor != null) { xChartEditor.displayCoverPane(false); } - if (isLinkedHelpDialog) { - component.destroyHelpDialog(); - } component.displayCoverPane(false); if (xTopLayoutContainer != null) { xTopLayoutContainer.setMouseEnter(false); @@ -432,19 +418,7 @@ public class EditingMouseListener extends MouseInputAdapter { xTopLayoutContainer.setMouseEnter(true); designer.repaint(); if (!xTopLayoutContainer.isEditable()) { - if (designer.getCursor().getType() == Cursor.HAND_CURSOR) { - designer.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); - } - int minX = getParentPositionX(parent, parent.getX()) + parent.getWidth() / 2; - int minY = getParentPositionY(parent, parent.getY()) + parent.getHeight() / 2; - int offsetX = EDIT_BTN_WIDTH / 2 + GAP; - int offsetY = EDIT_BTN_HEIGHT / 2 + GAP; - if (e.getX() > (minX - offsetX) && e.getX() < (minX + offsetX)) { - if (e.getY() > (minY - offsetY) && e.getY() < (minY + offsetY + designer.getParaHeight())) { - designer.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); - } - } - setHelpBtnFocus(e, xTopLayoutContainer); + processCoverMouseMove(parent, e); return true; } } @@ -454,19 +428,28 @@ public class EditingMouseListener extends MouseInputAdapter { private void processChartEditorMouseMove(XCreator component, MouseEvent e) { if (component instanceof XChartEditor) { xChartEditor = (XChartEditor) component; - UIButton button = (UIButton) xChartEditor.getCoverPane().getComponent(0); - if (designer.getCursor().getType() == Cursor.HAND_CURSOR) { - designer.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); - } - int minX = button.getX() + getParentPositionX(component, 0) - designer.getHorizontalScaleValue(); - int minY = button.getY() + getParentPositionY(component, 0) - designer.getVerticalScaleValue() + xChartEditor.getY(); - if (e.getX() + GAP > minX && e.getX() - GAP < minX + button.getWidth()) { - if (e.getY() + GAP > minY && e.getY() - GAP < minY + button.getHeight()) { - designer.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); - } - } - setHelpBtnFocus(e, xChartEditor); - designer.repaint(); + component.displayCoverPane(true); + processCoverMouseMove(component, e); + + } + } + + private void processCoverMouseMove(XCreator component, MouseEvent e) { + component.setShareConfigButtonFocus(false); + Insets insets; + if (component instanceof XBorderStyleWidgetCreator) { + insets = ((XBorderStyleWidgetCreator) component).getInsets(); + } else { + insets = DEEFAULT_INSETS; + } + if (designer.getCursor().getType() == Cursor.HAND_CURSOR) { + designer.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + } + if (isShareConfigButton(e, component, insets)) { + designer.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + component.setShareConfigButtonFocus(true); + } else if (isEditButton(e, component, insets)) { + designer.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); } } diff --git a/designer-form/src/main/java/com/fr/design/mainframe/FormCreatorDropTarget.java b/designer-form/src/main/java/com/fr/design/mainframe/FormCreatorDropTarget.java index e35580b91..eb036239b 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/FormCreatorDropTarget.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/FormCreatorDropTarget.java @@ -22,10 +22,9 @@ import com.fr.design.gui.ibutton.UIButton; import com.fr.design.icon.IconPathConstants; import com.fr.design.mainframe.chart.info.ChartInfoCollector; import com.fr.design.utils.ComponentUtils; -import com.fr.form.share.SharableEditorProvider; +import com.fr.form.share.editor.SharableEditorProvider; import com.fr.form.share.SharableWidgetProvider; import com.fr.form.share.ShareLoader; -import com.fr.form.ui.ChartEditor; import com.fr.form.ui.Widget; import com.fr.stable.Constants; import com.fr.stable.StringUtils; @@ -43,7 +42,6 @@ import java.awt.dnd.DropTarget; import java.awt.dnd.DropTargetDragEvent; import java.awt.dnd.DropTargetDropEvent; import java.awt.dnd.DropTargetEvent; -import java.util.Map; /** * 添加模式下鼠标事件处理器。 diff --git a/designer-form/src/main/java/com/fr/design/mainframe/FormWidgetDetailPane.java b/designer-form/src/main/java/com/fr/design/mainframe/FormWidgetDetailPane.java index 311ea4cb7..fdad24577 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/FormWidgetDetailPane.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/FormWidgetDetailPane.java @@ -1,45 +1,20 @@ package com.fr.design.mainframe; import com.fr.base.BaseUtils; -import com.fr.base.FRContext; -import com.fr.design.gui.ibutton.UIButton; -import com.fr.design.gui.icombobox.UIComboBox; -import com.fr.design.gui.icontainer.UIScrollPane; -import com.fr.design.gui.ifilechooser.UINativeFileChooser; -import com.fr.design.gui.ilable.UILabel; +import com.fr.design.dialog.BasicPane; +import com.fr.design.gui.ibutton.UIHeadGroup; import com.fr.design.layout.FRGUIPaneFactory; -import com.fr.design.os.impl.SupportOSImpl; -import com.fr.design.widget.FRWidgetFactory; -import com.fr.form.share.SharableWidgetProvider; -import com.fr.form.share.ShareLoader; -import com.fr.general.CloudCenter; -import com.fr.log.FineLoggerFactory; -import com.fr.share.ShareConstants; -import com.fr.stable.ArrayUtils; -import com.fr.stable.StringUtils; +import com.fr.design.mainframe.share.collect.ComponentCollector; +import com.fr.design.mainframe.share.ui.local.LocalWidgetRepoPane; +import com.fr.design.mainframe.share.ui.online.OnlineWidgetRepoPane; -import javax.swing.BorderFactory; -import javax.swing.DefaultComboBoxModel; import javax.swing.Icon; -import javax.swing.JFileChooser; -import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; -import javax.swing.SwingWorker; -import javax.swing.filechooser.FileNameExtensionFilter; import java.awt.BorderLayout; -import java.awt.Color; -import java.awt.Desktop; -import java.awt.Dimension; -import java.awt.FlowLayout; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.ItemEvent; -import java.awt.event.ItemListener; -import java.io.File; -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; +import java.awt.CardLayout; +import java.util.ArrayList; +import java.util.List; /** * Created with IntelliJ IDEA. @@ -48,19 +23,8 @@ import java.net.URISyntaxException; * Time: 下午8:18 */ public class FormWidgetDetailPane extends FormDockView{ - private static final int LOCAL_WIDGET_LABEL_WIDTH = 90; - - private UIScrollPane downPane; - private JPanel reuWidgetPanel; - private UIComboBox comboBox; - private SharableWidgetProvider[] elCaseBindInfoList; - private UIButton deleteButton; - private JPanel editPanel; - private JPanel resetPanel; - private JPanel menutPanelNorthPane; - private SwingWorker sw; - //组件面板是否可以编辑 - private boolean isEdit; + private JPanel centerPane; + private List paneList; public static FormWidgetDetailPane getInstance() { if (HOLDER.singleton == null) { @@ -99,348 +63,32 @@ public class FormWidgetDetailPane extends FormDockView{ public void refreshDockingView(){ FormDesigner designer = this.getEditingFormDesigner(); removeAll(); - if(designer == null){ + if (designer == null) { clearDockingView(); return; } - reuWidgetPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); - reuWidgetPanel.setBorder(null); - if (elCaseBindInfoList == null) { - if (sw != null) { - sw.cancel(true); - } - sw = new SwingWorker() { - @Override - protected Object doInBackground() throws Exception { - elCaseBindInfoList = ShareLoader.getLoader().getAllBindInfoList(); - refreshDownPanel(false); - return null; - } - }; - sw.execute(); - } - initReuWidgetPanel(); - initMenuPanel(); - - add(reuWidgetPanel, BorderLayout.CENTER); - - } - - /** - * 初始化组件共享和复用面板 - */ - private void initReuWidgetPanel() { - elCaseBindInfoList = ShareLoader.getLoader().getAllBindInfoList(); - downPane = new UIScrollPane(new ShareWidgetPane(elCaseBindInfoList, false)); - downPane.setBorder(null); - reuWidgetPanel.add(downPane); - } - - /** - * 初始化菜单栏面板 - */ - private void initMenuPanel() { - JPanel menutPanel = new JPanel(); - menutPanel.setLayout(FRGUIPaneFactory.createBorderLayout()); - menutPanel.setBorder(BorderFactory.createEmptyBorder(3, 10, 10, 15)); - - menutPanelNorthPane = new JPanel(new BorderLayout()); - UILabel localWidgetLabel = FRWidgetFactory.createLineWrapLabel( - com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Local_Widget"), - LOCAL_WIDGET_LABEL_WIDTH); - menutPanelNorthPane.add(localWidgetLabel, BorderLayout.WEST); - menutPanelNorthPane.add(initEditButtonPane(), BorderLayout.EAST); - menutPanelNorthPane.setBorder(BorderFactory.createEmptyBorder(0, 0, 5, 0)); - - menutPanel.add(menutPanelNorthPane, BorderLayout.NORTH); - comboBox = new UIComboBox(getFormCategories()); - comboBox.setPreferredSize(new Dimension(240, comboBox.getPreferredSize().height)); - initComboBoxSelectedListener(); - menutPanel.add(comboBox, BorderLayout.CENTER); - reuWidgetPanel.add(menutPanel, BorderLayout.NORTH); - - } - - /** - * 创建菜单栏按钮面板 - */ - private JPanel initEditButtonPane() { - editPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 0, 0)); - - editPanel.add(createRefreshButton()); - editPanel.add(createDownloadButton()); - editPanel.add(createInstallButton()); - editPanel.add(createDeleteButton()); - - return editPanel; - } - - /** - * 创建取消删除面板 - */ - private JPanel initResetButtonPane() { - resetPanel = new JPanel(); - UIButton resetButton = new UIButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Reset")); - resetPanel.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2)); - resetButton.setBackground(Color.white); - resetButton.setForeground(new Color(0x333334)); - resetButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - refreshDownPanel(false); - replaceButtonPanel(false); - reuWidgetPanel.remove(deleteButton); - } - }); - - deleteButton = new UIButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Remove_Item")); - deleteButton.setBackground(Color.white); - deleteButton.setForeground(new Color(0xeb1d1f)); - deleteButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - if (ShareLoader.getLoader().removeModulesFromList()) { - refreshShareMoudule(); - reuWidgetPanel.remove(deleteButton); - elCaseBindInfoList = ShareLoader.getLoader().getAllBindInfoList(); - JOptionPane.showMessageDialog(null, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Share_Module_Removed_Successful")); - refreshDownPanel(false); - replaceButtonPanel(false); - refreshComboxData(); - } else { - JOptionPane.showMessageDialog(null, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Share_Module_Removed_Failed")); - } - - } - }); - JPanel deletePane = new JPanel(new BorderLayout()); - deletePane.add(deleteButton, BorderLayout.CENTER); - deletePane.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5)); - - resetPanel.setLayout(FRGUIPaneFactory.createBorderLayout()); - resetPanel.add(resetButton, BorderLayout.CENTER); - resetPanel.add(deletePane, BorderLayout.WEST); - - refreshDownPanel(true); - - return resetPanel; - - } - - - private void initComboBoxSelectedListener() { - comboBox.addItemListener(new ItemListener() { - @Override - public void itemStateChanged(ItemEvent e) { - ShareLoader.getLoader().resetRemovedModuleList(); - int filterIndex = comboBox.getSelectedIndex(); - if (filterIndex == 0) { - elCaseBindInfoList = ShareLoader.getLoader().getAllBindInfoList(); - } else { - String filterName = comboBox.getSelectedItem().toString(); - elCaseBindInfoList = ShareLoader.getLoader().getFilterBindInfoList(filterName); - } - refreshDownPanel(isEdit); - - } - }); - } - - /** - * 创建工具条按钮 - */ - private UIButton createToolButton(Icon icon, String toolTip, ActionListener actionListener) { - UIButton toolButton = new UIButton(); - toolButton.setIcon(icon); - toolButton.setToolTipText(toolTip); - toolButton.set4ToolbarButton(); - toolButton.addActionListener(actionListener); - return toolButton; - - } - - /** - * 创建刷新按钮 - */ - private UIButton createRefreshButton() { - return createToolButton( - BaseUtils.readIcon("/com/fr/design/form/images/refresh.png"), - com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Refresh"), - new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - if (sw != null) { - sw.cancel(true); - } - sw = new SwingWorker() { - @Override - protected Object doInBackground() throws Exception { - ShareLoader.getLoader().refreshModule(); - elCaseBindInfoList = ShareLoader.getLoader().getAllBindInfoList(); - refreshComboxData(); - refreshDownPanel(false); - return null; - } - }; - sw.execute(); - } - } - ); - } - - private void refreshComboxData() { - comboBox.setSelectedIndex(0); - comboBox.setModel(new DefaultComboBoxModel(getFormCategories())); - } - /** - * 创建下载模板的按钮 - */ - private UIButton createDownloadButton() { - UIButton downloadButton = new UIButton(); - downloadButton.setIcon(BaseUtils.readIcon("/com/fr/design/form/images/download icon.png")); - downloadButton.set4ToolbarButton(); - downloadButton.setToolTipText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Download_Template")); - downloadButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - String url = CloudCenter.getInstance().acquireUrlByKind("reuse.url"); - if (StringUtils.isEmpty(url)) { - FRContext.getLogger().info("The URL is empty!"); - return; - } - try { - Desktop.getDesktop().browse(new URI(url)); - } catch (IOException exp) { - JOptionPane.showMessageDialog(null, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Set_Default_Browser_Duplicate")); - FineLoggerFactory.getLogger().error(exp.getMessage(), exp); - } catch (URISyntaxException exp) { - FineLoggerFactory.getLogger().error(exp.getMessage(), exp); - } catch (Exception exp) { - FineLoggerFactory.getLogger().error(exp.getMessage(), exp); - FineLoggerFactory.getLogger().error("Can not open the browser for URL: " + url); - } - } - }); - return downloadButton; - } - - /** - * 创建安装模板的按钮 - */ - private UIButton createInstallButton() { - return createToolButton( - BaseUtils.readIcon("/com/fr/design/form/images/install icon.png"), - com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Install_Template"), - new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - if (SupportOSImpl.NATIVE_CHOOSER.support()) { - UINativeFileChooser nativeFileChooser = new UINativeFileChooser(); - nativeFileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); - nativeFileChooser.setMultiSelectionEnabled(true); - nativeFileChooser.setExtensionFilter("*.reu"); - nativeFileChooser.setDialogTitle(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Select")); - int returnValue = nativeFileChooser.showOpenDialog(new UILabel()); - if (returnValue == JFileChooser.APPROVE_OPTION) { - final File[] chosenFiles = nativeFileChooser.getSelectedFiles(); - for (File file : chosenFiles) { - installFromDiskZipFile(file); - } - } - } else { - JFileChooser fileChooser = new JFileChooser(); - fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); - fileChooser.setMultiSelectionEnabled(true); - fileChooser.setFileFilter(new FileNameExtensionFilter(".reu", "reu")); - int returnValue = fileChooser.showDialog(new UILabel(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Select")); - if (returnValue == JFileChooser.APPROVE_OPTION) { - final File[] chosenFiles = fileChooser.getSelectedFiles(); - for (File file : chosenFiles) { - installFromDiskZipFile(file); - } - } - } - } - } - ); - } - - /** - * 创建删除模板的按钮 - */ - private UIButton createDeleteButton() { - return createToolButton( - BaseUtils.readIcon("/com/fr/design/form/images/delete icon.png"), - com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Delete_Template"), - new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - replaceButtonPanel(true); - } - } - ); - } - - private void replaceButtonPanel(boolean isEdit) { - this.isEdit = isEdit; - if (isEdit) { - menutPanelNorthPane.remove(editPanel); - menutPanelNorthPane.add(initResetButtonPane(), BorderLayout.EAST); - } else { - menutPanelNorthPane.remove(resetPanel); - menutPanelNorthPane.add(initEditButtonPane(), BorderLayout.EAST); - ShareLoader.getLoader().resetRemovedModuleList(); + initPaneList(); + this.setBorder(null); + final CardLayout cardLayout = new CardLayout(); + centerPane = new JPanel(cardLayout); + String[] paneNames = new String[paneList.size()]; + for (int i = 0; i < paneList.size(); i++) { + String title = paneList.get(i).getTitle(); + paneNames[i] = title; + centerPane.add(paneList.get(i), title); } - } - - private void installFromDiskZipFile(File chosenFile) { - if (chosenFile != null && chosenFile.getName().endsWith(ShareConstants.SUFFIX_MODULE)) { - try { - if (ShareLoader.getLoader().installModuleFromDiskZipFile(chosenFile)) { - refreshShareMoudule(); - elCaseBindInfoList = ShareLoader.getLoader().getAllBindInfoList(); - refreshDownPanel(false); - refreshComboxData(); - JOptionPane.showMessageDialog(null, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Share_Module_OK")); - } else { - JOptionPane.showMessageDialog(null, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Share_Module_Error")); + UIHeadGroup headGroup = new UIHeadGroup(paneNames) { + protected void tabChanged(int newSelectedIndex) { + if (newSelectedIndex == 1) { + ComponentCollector.getInstance().collectMarkerClick(); } - } catch (IOException e) { - JOptionPane.showMessageDialog(null, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Share_Module_Error")); - FineLoggerFactory.getLogger().error(e.getMessage(), e); + cardLayout.show(centerPane, paneList.get(newSelectedIndex).getTitle()); } - } - } - - private void refreshShareMoudule() { - try { - ShareLoader.getLoader().refreshModule(); - } catch (Exception e) { - FineLoggerFactory.getLogger().error(e.getMessage(), e); - } - } - - /** - * 获取报表块组件分类 - */ - public String[] getFormCategories() { - return ArrayUtils.addAll(new String[] {com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_AllCategories")}, ShareLoader.getLoader().getModuleCategory()); - } - - public void refreshDownPanel(boolean isEdit) { - reuWidgetPanel.remove(downPane); - downPane = new UIScrollPane(new ShareWidgetPane(elCaseBindInfoList, isEdit)); - downPane.setBorder(null); - reuWidgetPanel.add(downPane); - repaintContainer(); - - } - - public void repaintContainer() { - validate(); - repaint(); - revalidate(); + }; + headGroup.setSelectedIndex(0); + this.add(headGroup, BorderLayout.NORTH); + this.add(centerPane, BorderLayout.CENTER); } /** @@ -453,14 +101,20 @@ public class FormWidgetDetailPane extends FormDockView{ } - /** * 定位 - * @return 位置 + * + * @return 位置 */ + @Override public Location preferredLocation() { return Location.WEST_BELOW; } + private void initPaneList() { + paneList = new ArrayList<>(); + paneList.add(LocalWidgetRepoPane.getInstance()); + paneList.add(OnlineWidgetRepoPane.getInstance()); + } } diff --git a/designer-form/src/main/java/com/fr/design/mainframe/ShareWidgetButton.java b/designer-form/src/main/java/com/fr/design/mainframe/ShareWidgetButton.java deleted file mode 100644 index cdfa095bf..000000000 --- a/designer-form/src/main/java/com/fr/design/mainframe/ShareWidgetButton.java +++ /dev/null @@ -1,314 +0,0 @@ -package com.fr.design.mainframe; - -import com.fr.base.iofile.attr.SharableAttrMark; -import com.fr.base.vcs.DesignerMode; -import com.fr.design.designer.creator.XCreator; -import com.fr.design.designer.creator.XCreatorUtils; -import com.fr.design.gui.ilable.UILabel; -import com.fr.form.share.SharableWidgetProvider; -import com.fr.form.share.ShareLoader; -import com.fr.form.ui.AbstractBorderStyleWidget; -import com.fr.form.ui.Widget; -import com.fr.form.ui.container.cardlayout.WCardMainBorderLayout; -import com.fr.general.ComparatorUtils; -import com.fr.general.IOUtils; -import com.fr.share.ShareConstants; -import com.fr.stable.StringUtils; -import org.jetbrains.annotations.NotNull; - -import javax.swing.Icon; -import javax.swing.ImageIcon; -import javax.swing.JComponent; -import javax.swing.JPanel; -import java.awt.AlphaComposite; -import java.awt.BorderLayout; -import java.awt.Color; -import java.awt.Component; -import java.awt.Composite; -import java.awt.Container; -import java.awt.Dimension; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.LayoutManager; -import java.awt.Rectangle; -import java.awt.datatransfer.DataFlavor; -import java.awt.datatransfer.Transferable; -import java.awt.datatransfer.UnsupportedFlavorException; -import java.awt.dnd.DnDConstants; -import java.awt.dnd.DragGestureEvent; -import java.awt.dnd.DragGestureListener; -import java.awt.dnd.DragSource; -import java.awt.dnd.DragSourceAdapter; -import java.awt.dnd.DragSourceDragEvent; -import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; -import java.awt.event.MouseMotionListener; -import java.io.IOException; -import java.io.Serializable; - -/** - * Coder: zack - * Date: 2016/10/9 - * Time: 16:14 - */ -public class ShareWidgetButton extends JPanel implements MouseListener, MouseMotionListener, Serializable { - - protected SharableWidgetProvider bindInfo; - protected MouseEvent lastPressEvent; - protected JPanel reportPane; - protected boolean isEdit; - protected boolean isMarked; - private ShareWidgetUI ui; - private Icon markedMode = IOUtils.readIcon("/com/fr/design/form/images/marked.png"); - private Icon unMarkedMode = IOUtils.readIcon("/com/fr/design/form/images/unmarked.png"); - private AlphaComposite composite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 60 / 100.0F); - private JComponent markedButton = new JComponent() { - protected void paintComponent(Graphics g) { - markedMode.paintIcon(this, g, 0, 0); - } - }; - private JComponent unMarkedButton = new JComponent() { - protected void paintComponent(Graphics g) { - unMarkedMode.paintIcon(this, g, 0, 0); - } - }; - - public ShareWidgetButton(SharableWidgetProvider bindInfo, ShareWidgetUI ui) { - - this.bindInfo = bindInfo; - this.ui = ui; - this.setPreferredSize(new Dimension(108, 68)); - initUI(); - this.setLayout(getCoverLayout()); - this.addMouseListener(this); - this.addMouseMotionListener(this); - new DragAndDropDragGestureListener(this, DnDConstants.ACTION_COPY_OR_MOVE); - } - - public ShareWidgetButton(SharableWidgetProvider bindInfo) { - - this(bindInfo, new ShareWidgetUI()); - } - - public void paint(Graphics g) { - Graphics2D g2d = (Graphics2D) g; - Composite oldComposite = g2d.getComposite(); - g2d.setComposite(composite); - g2d.setColor(Color.WHITE); - g2d.fillRect(0, 0, getWidth(), getHeight()); - g2d.setComposite(oldComposite); - super.paint(g); - } - - public void setElementCaseEdit(boolean isEdit) { - this.isEdit = isEdit; - if (isEdit) { - this.add(unMarkedButton, 0); - repaint(); - } - - - } - - private void initUI() { - - reportPane = new JPanel(new BorderLayout()); - reportPane.add(new UILabel(new ImageIcon(bindInfo.getCover())), BorderLayout.CENTER); - JPanel labelPane = new JPanel(new BorderLayout()); - UILabel label = new UILabel(bindInfo.getName(), UILabel.CENTER); - labelPane.setBackground(new Color(184, 220, 242)); - labelPane.add(label, BorderLayout.CENTER); - reportPane.add(labelPane, BorderLayout.SOUTH); - add(reportPane); - } - - protected LayoutManager getCoverLayout() { - return new LayoutManager() { - - @Override - public void removeLayoutComponent(Component comp) { - } - - @Override - public Dimension preferredLayoutSize(Container parent) { - return parent.getPreferredSize(); - } - - @Override - public Dimension minimumLayoutSize(Container parent) { - return null; - } - - @Override - public void layoutContainer(Container parent) { - int width = parent.getWidth(); - int height = parent.getHeight(); - markedButton.setBounds((width - 25), 0, 25, 25); - unMarkedButton.setBounds((width - 25), 0, 25, 25); - reportPane.setBounds(0, 0, width, height); - - - - } - - @Override - public void addLayoutComponent(String name, Component comp) { - } - }; - } - - public SharableWidgetProvider getBindInfo() { - return bindInfo; - } - - public void setBindInfo(SharableWidgetProvider bindInfo) { - this.bindInfo = bindInfo; - } - - public String getFileName() { - return bindInfo.getName() +"." + bindInfo.getId() + ShareConstants.SUFFIX_MODULE; - } - - @Override - public void mouseClicked(MouseEvent e) { - if (isEdit) { - if (isMarked) { - remove(markedButton); - ShareLoader.getLoader().removeModuleForList(getFileName()); - isMarked = false; - } else { - add(markedButton,0); - ShareLoader.getLoader().addModuleToList(getFileName()); - isMarked = true; - } - } - - repaint(); - } - - @Override - public void mousePressed(MouseEvent e) { - lastPressEvent = e; - } - - @Override - public void mouseReleased(MouseEvent e) { - - } - - @Override - public void mouseEntered(MouseEvent e) { - - } - - @Override - public void mouseExited(MouseEvent e) { - - } - - @Override - public void mouseDragged(MouseEvent e) { - if (DesignerMode.isAuthorityEditing()) { - return; - } - if (lastPressEvent == null) { - return; - } - Object source = e.getSource(); - Widget creatorSource = null; - String shareId = StringUtils.EMPTY; - if (source instanceof ShareWidgetButton) { - ShareWidgetButton no = (ShareWidgetButton) e.getSource(); - if (no == null) { - return; - } - shareId = no.getBindInfo().getId(); - creatorSource = ShareLoader.getLoader().getElCaseEditorById(shareId); - if (creatorSource != null) { - ((AbstractBorderStyleWidget)creatorSource).addWidgetAttrMark(new SharableAttrMark(true)); - //tab布局WCardMainBorderLayout通过反射出来的大小是960*480 - XCreator xCreator = ui.createXCreator(creatorSource, shareId, no.getBindInfo()); - WidgetToolBarPane.getTarget().startDraggingBean(xCreator); - lastPressEvent = null; - this.setBorder(null); - } - } - } - - @Override - public void mouseMoved(MouseEvent e) { - - } - - public class DragAndDropDragGestureListener extends DragSourceAdapter implements DragGestureListener { - private DragSource source; - - public DragAndDropDragGestureListener(ShareWidgetButton tt, int actions) { - source = new DragSource(); - source.createDefaultDragGestureRecognizer(tt, actions, this); - } - - public void dragGestureRecognized(DragGestureEvent dge) { - ShareWidgetButton shareWidgetButton = (ShareWidgetButton) dge.getComponent(); - if (shareWidgetButton != null) { - Widget widget = ShareLoader.getLoader().getElCaseEditorById(shareWidgetButton.getBindInfo().getId()); - DragAndDropTransferable dragAndDropTransferable = new DragAndDropTransferable(widget); - dge.startDrag(DragSource.DefaultCopyDrop, dragAndDropTransferable, this); - } - } - - @Override - public void dragEnter(DragSourceDragEvent dragSourceDragEvent) { - - } - } - - public class DragAndDropTransferable implements Transferable { - private Widget widget; - - public DragAndDropTransferable(Widget widget) { - this.widget = widget; - } - - DataFlavor[] flavors = {new DataFlavor(Widget.class, "Widget")}; - - public DataFlavor[] getTransferDataFlavors() { - return flavors; - } - - public boolean isDataFlavorSupported(DataFlavor flavor) { - for (DataFlavor df : flavors) { - if (ComparatorUtils.equals(df, flavor)) { - return true; - } - } - return false; - } - - public Object getTransferData(DataFlavor df) throws UnsupportedFlavorException, IOException { - return widget; - } - } - - /** - * 抽出来,专门为了创建 ui 来搞 - */ - public static class ShareWidgetUI { - - private static final Dimension TAB_DEFAULT_SIZE = new Dimension(500, 300); - - @NotNull - public XCreator createXCreator(Widget creatorSource, String shareId, SharableWidgetProvider provider) { - - XCreator xCreator = null; - if (creatorSource instanceof WCardMainBorderLayout) { - xCreator = XCreatorUtils.createXCreator(creatorSource, TAB_DEFAULT_SIZE); - } else { - xCreator = XCreatorUtils.createXCreator(creatorSource, new Dimension(provider.getWidth(), provider.getHeight())); - } - xCreator.setBackupBound(new Rectangle(provider.getWidth(), provider.getHeight())); - xCreator.setShareId(shareId); - return xCreator; - } - } -} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/ShareWidgetPane.java b/designer-form/src/main/java/com/fr/design/mainframe/ShareWidgetPane.java deleted file mode 100644 index 549a4b174..000000000 --- a/designer-form/src/main/java/com/fr/design/mainframe/ShareWidgetPane.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.fr.design.mainframe; - - - -import com.fr.form.share.SharableWidgetProvider; - -import javax.swing.*; -import java.awt.*; - - -/** - * Created by xiaxiang on 2016/10/10. - */ -public class ShareWidgetPane extends JPanel { - - public ShareWidgetPane(SharableWidgetProvider[] elCaseBindInfoList, boolean isEdit) { - this.setBorder(BorderFactory.createEmptyBorder(10, 3, 0, 0));// 设置面板的边框 ,距离上、左、下、右 的距离 - if (elCaseBindInfoList != null) { - int rowCount = (elCaseBindInfoList.length + 1) / 2; - this.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 10)); - for (SharableWidgetProvider rbModuleInfo : elCaseBindInfoList) { - ShareWidgetButton widgetButton = new ShareWidgetButton(rbModuleInfo); - widgetButton.setElementCaseEdit(isEdit); - this.add(widgetButton); - } - this.setPreferredSize(new Dimension(240, rowCount * 80)); - } - } -} \ No newline at end of file diff --git a/designer-form/src/main/java/com/fr/design/mainframe/WidgetPropertyPane.java b/designer-form/src/main/java/com/fr/design/mainframe/WidgetPropertyPane.java index c37b4ba9a..fd64d3aab 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/WidgetPropertyPane.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/WidgetPropertyPane.java @@ -6,13 +6,12 @@ import com.fr.design.constants.UIConstants; import com.fr.design.designer.beans.events.DesignerEditListener; import com.fr.design.designer.beans.events.DesignerEvent; import com.fr.design.designer.creator.*; -import com.fr.design.designer.creator.cardlayout.XWCardMainBorderLayout; import com.fr.design.designer.creator.cardlayout.XWCardTagLayout; -import com.fr.design.designer.properties.EventPropertyTable; import com.fr.design.designer.properties.mobile.MobileBookMarkPropertyUI; import com.fr.design.designer.properties.mobile.MobileStylePropertyUI; import com.fr.design.form.util.FormDesignerUtils; import com.fr.design.fun.WidgetPropertyUIProvider; +import com.fr.design.gui.controlpane.EventPropertyPane; import com.fr.design.gui.ibutton.UIHeadGroup; import com.fr.design.gui.icontainer.UIScrollPane; import com.fr.design.gui.ilable.UILabel; @@ -38,7 +37,7 @@ public class WidgetPropertyPane extends FormDockView implements BaseWidgetProper private static final int PADDING = 10; private static final int PADDING_M = 12; private FormWidgetCardPane formWidgetCardPane; // 控件的属性表 - private EventPropertyTable eventTable; // 控件的事件表 + private EventPropertyPane eventTable; // 控件的事件表 private List widgetPropertyTables; // 这个变量应该是保存控件拓展的属性tab private List mobileExtraPropertyPanes; // 保存9.0设计器下移动端拓展的属性tab,舍弃JTable private FormDesigner designer; // 当前designer @@ -141,7 +140,7 @@ public class WidgetPropertyPane extends FormDockView implements BaseWidgetProper * 创建事件表(事件选项卡不是JTable) */ private void createEventTable() { - eventTable = new EventPropertyTable(designer); + eventTable = new EventPropertyPane(designer); designer.addDesignerEditListener(new EventPropertyDesignerAdapter(eventTable)); } @@ -337,9 +336,9 @@ public class WidgetPropertyPane extends FormDockView implements BaseWidgetProper * 事件表监听界面事件(编辑,选中) */ private class EventPropertyDesignerAdapter implements DesignerEditListener { - EventPropertyTable propertyTable; + EventPropertyPane propertyTable; - EventPropertyDesignerAdapter(EventPropertyTable eventTable) { + EventPropertyDesignerAdapter(EventPropertyPane eventTable) { this.propertyTable = eventTable; } diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/AbstractWidgetSelectPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/AbstractWidgetSelectPane.java new file mode 100644 index 000000000..96b321c93 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/AbstractWidgetSelectPane.java @@ -0,0 +1,62 @@ +package com.fr.design.mainframe.share; + +import com.fr.design.mainframe.share.ui.base.PopupPreviewPane; +import com.fr.design.mainframe.share.ui.block.PreviewWidgetBlock; +import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.general.ComparatorUtils; +import com.fr.stable.StringUtils; + +import javax.swing.JPanel; +import java.awt.Container; + +/** + * @Author: Yuan.Wang + * @Date: 2021/1/15 + */ +public abstract class AbstractWidgetSelectPane extends JPanel { + private static final int SCROLL_BAR_HEIGHT = 10; + private final PopupPreviewPane previewPane; + private String currentShowWidgetID; + + public AbstractWidgetSelectPane() { + this.previewPane = new PopupPreviewPane(); + } + + public void showPreviewPane(PreviewWidgetBlock comp, String showWidgetID) { + if (ComparatorUtils.equals(currentShowWidgetID, showWidgetID)) { + return; + } + popupPreviewPane(comp, showWidgetID); + } + + public void hidePreviewPane() { + if (previewPane != null && previewPane.isVisible()) { + previewPane.setVisible(false); + } + this.currentShowWidgetID = StringUtils.EMPTY; + } + + private void popupPreviewPane(PreviewWidgetBlock comp, String showWidgetID) { + if (previewPane.isVisible()) { + previewPane.setVisible(false); + } + + if (!previewPane.isVisible() && comp.getWidth() != 0 && comp.getHeight() != 0) { + //父容器是GroupPane,要获得的是GroupPane的父容器 + Container parentContainer =getParentContainer(); + previewPane.setComp(comp.getPreviewImage()); + int popupPosY = comp.getLocationOnScreen().y - parentContainer.getLocationOnScreen().y; + if (previewPane.getHeight() + popupPosY > parentContainer.getHeight() + SCROLL_BAR_HEIGHT) { + popupPosY -= (previewPane.getHeight() + popupPosY - parentContainer.getHeight() - SCROLL_BAR_HEIGHT); + } + int popupPosX = -previewPane.getPreferredSize().width; + if (parentContainer.getLocationOnScreen().x < previewPane.getPreferredSize().width) { + popupPosX = parentContainer.getWidth(); + } + GUICoreUtils.showPopupMenu(previewPane, parentContainer, popupPosX, popupPosY); + this.currentShowWidgetID = showWidgetID; + } + } + + abstract protected Container getParentContainer(); +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/Bean/ComponentGenerateInfo.java b/designer-form/src/main/java/com/fr/design/mainframe/share/Bean/ComponentGenerateInfo.java new file mode 100644 index 000000000..a5bd419a2 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/Bean/ComponentGenerateInfo.java @@ -0,0 +1,59 @@ +package com.fr.design.mainframe.share.Bean; + +import com.fr.design.mainframe.JTemplate; +import com.fr.form.share.DefaultSharableWidget; +import com.fr.form.ui.Widget; + +import java.util.Map; + +/** + * created by Harrison on 2020/04/13 + * + * 组件生成信息 + **/ +public class ComponentGenerateInfo { + + private boolean autoUpload; + + private JTemplate jt; + + private Map paraMap; + + private Widget widget; + + private DefaultSharableWidget info; + + public ComponentGenerateInfo(boolean autoUpload, JTemplate jt, Map paraMap, Widget widget, DefaultSharableWidget info) { + + this.autoUpload = autoUpload; + this.jt = jt; + this.paraMap = paraMap; + this.widget = widget; + this.info = info; + } + + public boolean isAutoUpload() { + + return autoUpload; + } + + public JTemplate getJt() { + + return jt; + } + + public Map getParaMap() { + + return paraMap; + } + + public Widget getWidget() { + + return widget; + } + + public DefaultSharableWidget getInfo() { + + return info; + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/Bean/LinkageChangeBean.java b/designer-form/src/main/java/com/fr/design/mainframe/share/Bean/LinkageChangeBean.java new file mode 100644 index 000000000..b286cfb41 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/Bean/LinkageChangeBean.java @@ -0,0 +1,114 @@ +package com.fr.design.mainframe.share.Bean; + +import com.fr.design.mainframe.share.constants.ComponentTypes; +import com.fr.form.share.bean.WidgetDeviceBean; +import com.fr.form.share.bean.WidgetTypeBean; +import com.fr.design.mainframe.share.constants.DisplayDevice; +import com.fr.stable.AssistUtils; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 下拉框与下拉复现框联动状态 + * @author hades + * @version 10.0 + * Created by hades on 2020/6/9 + */ +public class LinkageChangeBean { + + private static final Map> STATE_MAP = new HashMap<>(); + + static { + // all or default + STATE_MAP.put(new LinkageChangeBean(new WidgetDeviceBean(false, false), new WidgetTypeBean(false, false)), ComponentTypes.allTypes()); + STATE_MAP.put(new LinkageChangeBean(new WidgetDeviceBean(true, true), new WidgetTypeBean(true, true)), ComponentTypes.allTypes()); + STATE_MAP.put(new LinkageChangeBean(new WidgetDeviceBean(false, false), new WidgetTypeBean(true, true)), ComponentTypes.allTypes()); + STATE_MAP.put(new LinkageChangeBean(new WidgetDeviceBean(true, true), new WidgetTypeBean(false, false)), ComponentTypes.allTypes()); + + // pc + STATE_MAP.put(new LinkageChangeBean(new WidgetDeviceBean(false, true), new WidgetTypeBean(false, false)), ComponentTypes.allTypesByDevice(DisplayDevice.PC.getType())); + STATE_MAP.put(new LinkageChangeBean(new WidgetDeviceBean(false, true), new WidgetTypeBean(true, true)), ComponentTypes.allTypesByDevice(DisplayDevice.PC.getType())); + + // mobile + STATE_MAP.put(new LinkageChangeBean(new WidgetDeviceBean(true, false), new WidgetTypeBean(false, false)), ComponentTypes.allTypesByDevice(DisplayDevice.MOBILE.getType())); + STATE_MAP.put(new LinkageChangeBean(new WidgetDeviceBean(true, false), new WidgetTypeBean(true, true)), ComponentTypes.allTypesByDevice(DisplayDevice.MOBILE.getType())); + + // report + STATE_MAP.put(new LinkageChangeBean(new WidgetDeviceBean(false, false), new WidgetTypeBean(true, false)), ComponentTypes.REPORT.types()); + STATE_MAP.put(new LinkageChangeBean(new WidgetDeviceBean(true, true), new WidgetTypeBean(true, false)), ComponentTypes.REPORT.types()); + + // chart + STATE_MAP.put(new LinkageChangeBean(new WidgetDeviceBean(false, false), new WidgetTypeBean(false, true)), ComponentTypes.CHART.types()); + STATE_MAP.put(new LinkageChangeBean(new WidgetDeviceBean(true, true), new WidgetTypeBean(false, true)), ComponentTypes.CHART.types()); + + // pc-report + STATE_MAP.put(new LinkageChangeBean(new WidgetDeviceBean(false, true), new WidgetTypeBean(true, false)), ComponentTypes.REPORT.children(DisplayDevice.PC.getType())); + + // pc-chart + STATE_MAP.put(new LinkageChangeBean(new WidgetDeviceBean(false, true), new WidgetTypeBean(false, true)), ComponentTypes.CHART.children(DisplayDevice.PC.getType())); + + // mobile-report + STATE_MAP.put(new LinkageChangeBean(new WidgetDeviceBean(true, false), new WidgetTypeBean(true, false)), ComponentTypes.REPORT.children(DisplayDevice.MOBILE.getType())); + + // mobile-chart + STATE_MAP.put(new LinkageChangeBean(new WidgetDeviceBean(true, false), new WidgetTypeBean(false, true)), ComponentTypes.CHART.children(DisplayDevice.MOBILE.getType())); + + } + + public static List getComboBoxItems(LinkageChangeBean bean) { + return STATE_MAP.get(bean); + } + + private LinkageChangeBean(WidgetDeviceBean widgetDeviceBean, WidgetTypeBean widgetTypeBean) { + this.widgetDeviceBean = widgetDeviceBean; + this.widgetTypeBean = widgetTypeBean; + } + + private WidgetTypeBean widgetTypeBean; + private WidgetDeviceBean widgetDeviceBean; + + public static class Builder { + private boolean report; + private boolean chart; + private boolean mobile; + private boolean pc; + + public Builder setReport(boolean report) { + this.report = report; + return this; + } + + public Builder setChart(boolean chart) { + this.chart = chart; + return this; + } + + public Builder setMobile(boolean mobile) { + this.mobile = mobile; + return this; + } + + public Builder setPc(boolean pc) { + this.pc = pc; + return this; + } + + public LinkageChangeBean build() { + return new LinkageChangeBean(new WidgetDeviceBean(this.mobile, this.pc), new WidgetTypeBean(this.report, this.chart)); + } + } + + @Override + public boolean equals(Object o) { + return o instanceof LinkageChangeBean + && AssistUtils.equals(this.widgetDeviceBean, ((LinkageChangeBean) o).widgetDeviceBean) + && AssistUtils.equals(this.widgetTypeBean, ((LinkageChangeBean) o).widgetTypeBean); + } + + @Override + public int hashCode() { + return AssistUtils.hashCode(this.widgetDeviceBean, this.widgetTypeBean); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/action/CreateComponentAction.java b/designer-form/src/main/java/com/fr/design/mainframe/share/action/CreateComponentAction.java new file mode 100644 index 000000000..1baac868f --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/action/CreateComponentAction.java @@ -0,0 +1,398 @@ +package com.fr.design.mainframe.share.action; + +import com.fr.base.Parameter; +import com.fr.base.ParameterMapNameSpace; +import com.fr.base.TableData; +import com.fr.chart.chartattr.Chart; +import com.fr.chart.chartattr.ChartCollection; +import com.fr.chart.chartdata.TableDataDefinition; +import com.fr.data.impl.NameTableData; +import com.fr.data.impl.TableDataDictionary; +import com.fr.design.actions.UpdateAction; +import com.fr.design.data.DesignTableDataManager; +import com.fr.design.designer.creator.XCreator; +import com.fr.design.dialog.BasicPane; +import com.fr.design.dialog.DialogActionAdapter; +import com.fr.design.dialog.FineJOptionPane; +import com.fr.design.file.HistoryTemplateListPane; +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.DesignerFrame; +import com.fr.design.mainframe.FormSelection; +import com.fr.design.mainframe.JForm; +import com.fr.design.mainframe.JTemplate; +import com.fr.design.mainframe.share.constants.ShareEntryKey; +import com.fr.design.mainframe.share.select.ComponentTransformerFactory; +import com.fr.design.parameter.ParameterInputPane; +import com.fr.form.FormElementCaseProvider; +import com.fr.form.main.Form; +import com.fr.form.main.FormIO; +import com.fr.form.main.WidgetGather; +import com.fr.form.ui.BaseChartEditor; +import com.fr.form.ui.ChartEditor; +import com.fr.form.ui.DataControl; +import com.fr.form.ui.DictionaryContainer; +import com.fr.form.ui.ElementCaseEditor; +import com.fr.form.ui.Widget; +import com.fr.general.IOUtils; +import com.fr.log.FineLoggerFactory; +import com.fr.report.cell.DefaultTemplateCellElement; +import com.fr.report.cell.cellattr.core.group.DSColumn; +import com.fr.script.Calculator; +import com.fr.stable.ArrayUtils; +import com.fr.stable.Constants; +import com.fr.stable.CoreGraphHelper; +import com.fr.stable.DependenceProvider; +import com.fr.stable.ParameterProvider; +import com.fr.stable.StringUtils; +import com.fr.stable.bridge.StableFactory; +import com.fr.stable.script.CalculatorProvider; +import com.fr.stable.script.NameSpace; +import com.fr.third.guava.base.Preconditions; +import com.fr.third.org.apache.commons.lang3.tuple.ImmutableTriple; +import com.fr.third.org.apache.commons.lang3.tuple.Triple; + +import javax.swing.Action; +import javax.swing.UIManager; +import java.awt.Color; +import java.awt.Component; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.Rectangle; +import java.awt.event.ActionEvent; +import java.awt.image.BufferedImage; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Callable; +import java.util.concurrent.FutureTask; +import java.util.concurrent.TimeUnit; + +import static javax.swing.JOptionPane.ERROR_MESSAGE; + +/** + * @Author: Yuan.Wang + * @Date: 2020/11/3 + * 创建组件事件 + */ +public class CreateComponentAction extends UpdateAction { + ShareUIAspect aspect; + /** + * 等待时间 500 ms. + */ + private static final int WAIT_TIME = 500; + + private final HashMap parameterMap = new HashMap<>(); + private String[] widgetPara = new String[]{}; + + + public CreateComponentAction(ShareUIAspect aspect) { + this.putValue(Action.SMALL_ICON, null); + this.setName(Toolkit.i18nText("Fine-Design_Share_Create")); + this.aspect = aspect; + } + + @Override + public void actionPerformed(ActionEvent event) { + DesignerFrame designerFrame = DesignerContext.getDesignerFrame(); + // 停止编辑 + JTemplate jt = HistoryTemplateListPane.getInstance().getCurrentEditingTemplate(); + jt.stopEditing(); + Form form = null; + try { + form = (Form) jt.getTarget().clone(); + } catch (CloneNotSupportedException e1) { + FineLoggerFactory.getLogger().error(e1.getMessage(), e1); + } + FormSelection selection = ((JForm) jt).getFormDesign().getSelectionModel().getSelection(); + + // 获取选中的组件 + Triple sharedTriple = ComponentTransformerFactory.getInstance().transform(selection); + if (sharedTriple == null) { + FineJOptionPane.showMessageDialog(designerFrame, Toolkit.i18nText("Fine-Design_Share_Select_Error_Tip"), + Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"), ERROR_MESSAGE, IOUtils.readIcon("/com/fr/base/images/share/Information_Icon_warning_normal_32x32.png")); + return; + } + + Widget widget = sharedTriple.getLeft(); + + try { + + if (form == null) { + throw new NullPointerException("tpl get failed"); + } + //准备参数 + prepareParameter(widget, designerFrame); + + //准备的封面大小 + //组件大小 + Rectangle reportRec = FormIO.getContentRect(form); + Image coverImage = toCoverImage(form, sharedTriple, parameterMap, reportRec); + + Object[] compositeArg = new Object[]{jt, widget, sharedTriple.getRight(), coverImage, parameterMap, (ShareUIAspect)aspect}; + HashMap compoClass = new HashMap(); + compoClass.put(Constants.ARG_0, JTemplate.class); + compoClass.put(Constants.ARG_1, Widget.class); + compoClass.put(Constants.ARG_2, Rectangle.class); + compoClass.put(Constants.ARG_3, Image.class); + compoClass.put(Constants.ARG_4, HashMap.class); + compoClass.put(Constants.ARG_5, ShareUIAspect.class); + + BasicPane ShareGuidePane = StableFactory.getMarkedInstanceObjectFromClass(ShareEntryKey.SHARE_GENERATE, compositeArg, compoClass, BasicPane.class); +// ShareGuidePane moduleGuidePane = new ShareGuidePane(jt, widget, sharedTriple.getRight(), coverImage, parameterMap, aspect); + ShareGuidePane.show(); + } catch (Exception e) { + FineJOptionPane.showMessageDialog(designerFrame, Toolkit.i18nText("Fine-Design_Share_Create_Share_Pane_Failed"), + Toolkit.i18nText("Fine-Design_Basic_Error"), ERROR_MESSAGE, UIManager.getIcon("OptionPane.errorIcon")); + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + } + + /** + * 准备参数 + */ + private void prepareParameter(Widget widget, DesignerFrame designerFrame) { + + final Calculator ca = Calculator.createCalculator(); + Parameter[] tplParameters = ((Form)HistoryTemplateListPane.getInstance().getCurrentEditingTemplate().getTarget()).getParameters(); + widgetPara = new String[]{}; + calWidgetParameter(widget, ca); + List tplPList = new ArrayList(); + //只弹出使用到参数,其他的不要 + for (String wp : widgetPara) { + for (Parameter tplParameter : tplParameters) { + if (wp.length() > 0 && StringUtils.equals(wp, tplParameter.getName())) { + tplPList.add(tplParameter); + } else if (wp.contains("$") && StringUtils.equals(wp.substring(1, wp.length()), tplParameter.getName())){ + tplPList.add(tplParameter); + } + } + } + Parameter[] parameters = new Parameter[tplPList.size()]; + tplPList.toArray(parameters); + if (ArrayUtils.isNotEmpty(parameters)) {// 检查Parameter. + final ParameterInputPane pPane = new ParameterInputPane(parameters); + pPane.showSmallWindow(designerFrame, new DialogActionAdapter() { + + @Override + public void doOk() { + parameterMap.putAll(pPane.update()); + } + }).setVisible(true); + } + } + + private Triple prepareImageArgs(Triple pair, Rectangle reportRec) { + + Widget widget = pair.getLeft(); + XCreator xCreator = pair.getMiddle(); + Rectangle rectangle = pair.getRight(); + + if (widget instanceof ElementCaseEditor) { + rectangle = reportRec; + } + return new ImmutableTriple<>(widget, xCreator, rectangle); + } + + /** + * 准备封面 + *

+ * 操作可能会很耗时,所以加个时间限制 + */ + private Image toCoverImage(final Form form, + final Triple triple, + final Map parameterMap, + Rectangle reportRec) { + + final Triple imageArgs = prepareImageArgs(triple, reportRec); + FutureTask task = new FutureTask<>(new Callable() { + @Override + public Image call() throws Exception { + + Preconditions.checkNotNull(imageArgs); + Widget widget = imageArgs.getLeft(); + XCreator xCreator = imageArgs.getMiddle(); + Rectangle rectangle = imageArgs.getRight(); + if (widget instanceof ElementCaseEditor) { + return moduleToImage(form, (ElementCaseEditor) widget, parameterMap, rectangle); + } else { + return componentToImage(xCreator, rectangle); + } + } + }); + Thread imgThread = new Thread(task, "img-thread"); + try { + imgThread.start(); + //等待一段时间 + return task.get(WAIT_TIME, TimeUnit.MILLISECONDS); + } catch (Throwable throwable) { + + FineLoggerFactory.getLogger().debug("--- img generate failed ---"); + FineLoggerFactory.getLogger().debug(throwable.getMessage(), throwable); + FineLoggerFactory.getLogger().debug("--- prepare use default img ---"); + try (InputStream in = this.getClass().getResourceAsStream("/com/fr/base/images/share/default_cover.png")) { + //读取默认图表 + return IOUtils.readImage(in); + } catch (Throwable e) { + //随便画一个 + Rectangle realRec = triple.getRight(); + BufferedImage allInOne = CoreGraphHelper.createBufferedImage(realRec.width, realRec.height); + Graphics2D g2d = allInOne.createGraphics(); + g2d.setBackground(Color.white); + return allInOne; + } + } + } + + private Image componentToImage(Component comp, Rectangle rect) { + + BufferedImage im = new BufferedImage((int) rect.getWidth(), (int) rect.getHeight(), BufferedImage.TYPE_INT_ARGB); + comp.paint(im.getGraphics()); + return im; + } + + //画报表块的缩略图 + private Image moduleToImage(Form form, ElementCaseEditor editor, Map parameterMap, Rectangle rect) { + + if (editor == null) { + return new BufferedImage((int) rect.getWidth(), (int) rect.getHeight(), BufferedImage.TYPE_INT_ARGB); + } + FormElementCaseProvider provider = editor.getElementCase(); + provider.setName(editor.getWidgetName()); + provider.setTabledataSource(form); + final Calculator ca = Calculator.createCalculator(); + NameSpace ns = ParameterMapNameSpace.create(parameterMap); + ca.pushNameSpace(ns); + BufferedImage image = provider.toImage(ca, (int) rect.getWidth(), (int) rect.getHeight(), parameterMap, true); + return image; + + } + + //计算容器内使用到的参数 + private void calWidgetParameter(Widget widget, final Calculator ca) { + + Form.traversalWidget(widget, new WidgetGather() { + + @Override + public void dealWith(Widget widget) { + DataControl dc = (DataControl) widget; + TableData tableData = null; + try { + tableData = ((TableDataDictionary)(((DictionaryContainer) dc).getDictionary())).getTableData(); + } catch (Exception ignore) { + //ignore + } + widgetPara = ArrayUtils.addAll(widgetPara, getTableDataPara(tableData)); + + } + + @Override + public boolean dealWithAllCards() { + return true; + } + + }, DataControl.class); + + Form.traversalWidget(widget, new WidgetGather() { + + @Override + public void dealWith(Widget widget) { + ElementCaseEditor el = (ElementCaseEditor) widget; + widgetPara = ArrayUtils.addAll(widgetPara, getCellParameters(el.getElementCase(), ca)); + widgetPara = ArrayUtils.addAll(widgetPara, el.getElementCase().dependence(ca)); + } + + public boolean dealWithAllCards() { + return true; + } + + }, ElementCaseEditor.class); + + Form.traversalWidget(widget, new WidgetGather() { + + @Override + public void dealWith(Widget widget) { + //算的好麻烦,本来直接用dependence就好了,但是表单的selectedChart中的tabledata只有一个name,里面的_tableData是null、、所以从环境中重新取一下 + Chart selectedChart = ((ChartCollection) ((ChartEditor) widget).getChartCollection()).getSelectedChart(); + TableData tableData = null; + try { + tableData = ((TableDataDefinition)selectedChart.getFilterDefinition()).getTableData(); + } catch (Exception ignore) { + //ignore + } + widgetPara = ArrayUtils.addAll(widgetPara, getTableDataPara(tableData)); + } + + public boolean dealWithAllCards() { + return true; + } + + }, BaseChartEditor.class); + } + + private ArrayList getTableDataName(FormElementCaseProvider el, CalculatorProvider ca) { + Iterator it = el.cellIterator(); + ArrayList allECDepends = new ArrayList(); + while(it.hasNext()){ + DefaultTemplateCellElement ce = it.next(); + Object value = ce.getValue(); + //先处理单元格值(图表, 公式) + if(value instanceof DSColumn){ + String[] valueDep = ((DependenceProvider) value).dependence(ca); + allECDepends.addAll(Arrays.asList(valueDep)); + } + } + return allECDepends; + } + + private String[] getTableDataPara(TableData tableData) { + try { + return getTableParameters(((NameTableData) tableData).getName()); + } catch (Exception ignore) { + return new String[]{}; + } + } + + private String[] getCellParameters(FormElementCaseProvider formElementCase,Calculator ca) { + Iterator it = formElementCase.cellIterator(); + ArrayList allECDepends = new ArrayList(); + while(it.hasNext()){ + DefaultTemplateCellElement ce = it.next(); + Object value = ce.getValue(); + //处理单元格值(图表, 公式) + if(value instanceof DependenceProvider){ + String[] valueDep = ((DependenceProvider) value).dependence(ca); + allECDepends.addAll(Arrays.asList(valueDep)); + if (value instanceof DSColumn) { + String[] dsPara = getTableParameters(((DSColumn) value).getDSName()); + allECDepends.addAll(Arrays.asList(dsPara)); + } + } + } + //去掉重复的dependence + HashSet removeRepeat = new HashSet(allECDepends); + return removeRepeat.toArray(new String[removeRepeat.size()]); + } + + //通过tableName获取所用参数 + private String[] getTableParameters(String name) { + final Calculator ca = Calculator.createCalculator(); + ParameterProvider[] parameterProviders = new ParameterProvider[]{}; + TableData tableData = DesignTableDataManager.getEditingTableDataSource().getTableData(name); + //只使用自定义数据集的数据 + if (tableData == null) { + return new String[]{}; + } + parameterProviders = tableData.getParameters(ca); + String[] paras = new String[parameterProviders.length]; + for (int i = 0; i < parameterProviders.length; i++) { + paras[i] = parameterProviders[0].getName(); + } + return paras; + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/action/InstallComponentAction.java b/designer-form/src/main/java/com/fr/design/mainframe/share/action/InstallComponentAction.java new file mode 100644 index 000000000..d3173e36b --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/action/InstallComponentAction.java @@ -0,0 +1,163 @@ +package com.fr.design.mainframe.share.action; + +import com.fr.design.actions.UpdateAction; +import com.fr.design.dialog.BasicDialog; +import com.fr.design.dialog.DialogActionAdapter; +import com.fr.design.dialog.FineJOptionPane; +import com.fr.design.gui.ifilechooser.UINativeFileChooser; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.share.ui.base.FailureMessagePane; +import com.fr.design.mainframe.share.ui.local.LocalWidgetRepoPane; +import com.fr.design.mainframe.share.util.InstallUtils; +import com.fr.design.mainframe.share.util.ShareComponentUtils; +import com.fr.design.mainframe.share.util.ShareUIUtils; +import com.fr.design.os.impl.SupportOSImpl; +import com.fr.form.share.record.ShareWidgetInfoManager; +import com.fr.form.share.utils.ReuxUtils; +import com.fr.log.FineLoggerFactory; + +import javax.swing.Action; +import javax.swing.JFileChooser; +import javax.swing.SwingWorker; +import javax.swing.filechooser.FileNameExtensionFilter; +import java.awt.event.ActionEvent; +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ExecutionException; + +/** + * @Author: Yuan.Wang + * @Date: 2020/12/8 + */ + +public class InstallComponentAction extends UpdateAction { + + public InstallComponentAction() { + this.putValue(Action.SMALL_ICON, null); + this.setName(Toolkit.i18nText("Fine-Design_Share_Install")); + } + + @Override + public void actionPerformed(ActionEvent e) { + + if (SupportOSImpl.NATIVE_CHOOSER.support()) { + UINativeFileChooser nativeFileChooser = new UINativeFileChooser(); + nativeFileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); + nativeFileChooser.setMultiSelectionEnabled(true); + nativeFileChooser.setFileFilter(new FileNameExtensionFilter("reu reus", "reu", "reus")); + nativeFileChooser.setDialogTitle(Toolkit.i18nText("Fine-Design_Basic_Select")); + int returnValue = nativeFileChooser.showOpenDialog(new UILabel()); + installComponent(returnValue, nativeFileChooser.getSelectedFiles()); + } else { + JFileChooser fileChooser = new JFileChooser(); + fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); + fileChooser.setMultiSelectionEnabled(true); + fileChooser.setFileFilter(new FileNameExtensionFilter("reu reus", "reu", "reus")); + int returnValue = fileChooser.showDialog(new UILabel(), Toolkit.i18nText("Fine-Design_Basic_Select")); + installComponent(returnValue, fileChooser.getSelectedFiles()); + } + } + + private void installComponent(int returnValue, File[] selectedFiles) { + if (returnValue != JFileChooser.APPROVE_OPTION) { + return; + } + LocalWidgetRepoPane.getInstance().switch2InstallingPane(); + final File[] chosenFiles = selectedFiles; + new SwingWorker() { + @Override + protected InstallBackInfo doInBackground() { + return batchInstallZipFiles(chosenFiles); + } + + @Override + protected void done() { + try { + InstallBackInfo info = get(); + LocalWidgetRepoPane.getInstance().refreshAllGroupPane(); + showMessageDialog(info); + } catch (InterruptedException | ExecutionException e) { + FineLoggerFactory.getLogger().error(e, e.getMessage()); + } + } + }.execute(); + } + + private InstallBackInfo batchInstallZipFiles(File[] chosenFiles) { + try { + long installTime = System.currentTimeMillis(); + boolean installStatus = true; + //记录安装失败的组件 + List failureList = new ArrayList<>(); + for (File file : chosenFiles) { + installStatus &= installFromDiskZipFile(file, installTime, failureList); + } + ShareWidgetInfoManager.getInstance().saveXmlInfo(); + + boolean needShowMessage = (chosenFiles.length > 1 && chosenFiles.length != failureList.size()) || containRues(chosenFiles); + return new InstallBackInfo(installStatus, needShowMessage, failureList); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + return new InstallBackInfo(false, false, new ArrayList<>()); + } + } + + private void showMessageDialog(InstallBackInfo info) { + if (info.success) { + FineJOptionPane.showMessageDialog(null, Toolkit.i18nText("Fine-Design_Form_Share_Module_OK")); + return; + } + if (info.needShowMessage) { + final FailureMessagePane failureMessagePane = new FailureMessagePane(appendString(info.failureInfo)); + BasicDialog dialog = failureMessagePane.showSmallWindow(DesignerContext.getDesignerFrame(), new DialogActionAdapter() { + }); + dialog.setVisible(true); + } else { + ShareUIUtils.showErrorMessageDialog(Toolkit.i18nText("Fine-Design_Share_Share_Module_Install_Error")); + } + } + + private boolean containRues(File[] chosenFiles) { + for (File file : chosenFiles) { + if (file.getName().endsWith(ReuxUtils.REUS_SUFFIX)) + return true; + } + return false; + } + + private String appendString(List list) { + StringBuilder builder = new StringBuilder(); + for (String str : list) { + builder.append(str).append("\n"); + } + return builder.toString(); + } + + /** + * 安装选中文件 + */ + private boolean installFromDiskZipFile(File chosenFile, long installTime, List failList) { + if (chosenFile == null) { + return false; + } + ShareComponentUtils.checkReadMe(); + boolean isReus = chosenFile.getName().endsWith(ReuxUtils.REUS_SUFFIX); + return isReus ? InstallUtils.installReusFile(chosenFile, installTime, failList) : InstallUtils.installReuFile(chosenFile, installTime, failList); + } + + private static class InstallBackInfo { + final boolean success; + final boolean needShowMessage; + final List failureInfo; + + public InstallBackInfo(boolean success, boolean needShowMessage, List failureInfo) { + this.success = success; + this.needShowMessage = needShowMessage; + this.failureInfo = failureInfo; + } + } + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/action/ShareUIAspect.java b/designer-form/src/main/java/com/fr/design/mainframe/share/action/ShareUIAspect.java new file mode 100644 index 000000000..27643e06a --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/action/ShareUIAspect.java @@ -0,0 +1,9 @@ +package com.fr.design.mainframe.share.action; + +/** + * created by Harrison on 2020/04/22 + **/ +public interface ShareUIAspect { + + void afterOk(); +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/collect/CollectorManager.java b/designer-form/src/main/java/com/fr/design/mainframe/share/collect/CollectorManager.java new file mode 100644 index 000000000..3ccb62429 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/collect/CollectorManager.java @@ -0,0 +1,89 @@ +package com.fr.design.mainframe.share.collect; + +import com.fr.concurrent.NamedThreadFactory; +import com.fr.stable.StringUtils; +import com.fr.third.joda.time.DateTime; +import com.fr.third.joda.time.Days; +import com.fr.third.joda.time.format.DateTimeFormat; +import com.fr.third.joda.time.format.DateTimeFormatter; + +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +/** + * created by Harrison on 2020/03/25 + **/ +public class CollectorManager { + + /** + * 1 天 + */ + private static final int DELTA = 1; + + /** + * 发送间隔 5 分钟 + */ + private static final long SEND_DELAY = 300 * 1000L; + + /** + * 线程 + */ + private ScheduledExecutorService service; + + private static class ConfigManagerHolder { + private static CollectorManager instance = new CollectorManager(); + } + + public static CollectorManager getInstance() { + + return ConfigManagerHolder.instance; + } + + public void execute() { + + service = Executors + .newSingleThreadScheduledExecutor(new NamedThreadFactory("plugin-CollectorManager", true)); + service.scheduleAtFixedRate(new Runnable() { + @Override + public void run() { + sendCloudCenter(); + } + }, SEND_DELAY, SEND_DELAY, TimeUnit.MILLISECONDS); + } + + public void shutdown() { + + ComponentCollector.getInstance().saveInfo(); + if (service != null) { + service.shutdown(); + } + } + + private void sendCloudCenter() { + + String lastTime = ComponentCollector.getInstance().getLastTime(); + if (validate(lastTime)) { + boolean sendSuccess = ComponentSender.send(); + String currentTime = DateTime.now().toString("yyyy-MM-dd"); + ComponentCollector.getInstance().setLastTime(currentTime); + if (sendSuccess) { + ComponentCollector.getInstance().clear(); + } + } + ComponentCollector.getInstance().saveInfo(); + } + + private boolean validate(String lastTime) { + + if (StringUtils.isEmpty(lastTime)) { + return true; + } + DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd"); + DateTime last = formatter.parseDateTime(lastTime); + DateTime current = DateTime.now(); + return Days.daysBetween(last, current).getDays() >= DELTA; + } + + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/collect/ComponentCollector.java b/designer-form/src/main/java/com/fr/design/mainframe/share/collect/ComponentCollector.java new file mode 100644 index 000000000..a2c4ba5d9 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/collect/ComponentCollector.java @@ -0,0 +1,541 @@ +package com.fr.design.mainframe.share.collect; + +import com.fr.base.io.XMLReadHelper; +import com.fr.config.MarketConfig; +import com.fr.design.DesignerEnvManager; +import com.fr.form.share.DefaultSharableWidget; +import com.fr.form.share.SharableWidgetProvider; +import com.fr.form.share.constants.ComponentPath; +import com.fr.form.share.group.DefaultShareGroupManager; +import com.fr.form.share.Group; +import com.fr.form.share.group.filter.DirFilter; +import com.fr.form.share.group.filter.ReuFilter; +import com.fr.general.ComparatorUtils; +import com.fr.json.JSON; +import com.fr.json.JSONArray; +import com.fr.json.JSONException; +import com.fr.json.JSONFactory; +import com.fr.json.JSONObject; +import com.fr.log.FineLoggerFactory; +import com.fr.plugin.context.PluginContexts; +import com.fr.stable.ProductConstants; +import com.fr.stable.StableUtils; +import com.fr.stable.StringUtils; +import com.fr.stable.xml.XMLPrintWriter; +import com.fr.stable.xml.XMLTools; +import com.fr.stable.xml.XMLable; +import com.fr.stable.xml.XMLableReader; +import com.fr.third.javax.xml.stream.XMLStreamException; +import com.fr.third.joda.time.DateTime; +import com.fr.third.joda.time.Days; +import com.fr.third.org.apache.commons.io.FileUtils; +import com.fr.workspace.WorkContext; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.Iterator; + +/** + * created by Harrison on 2020/03/25 + **/ +public class ComponentCollector implements XMLable { + private static final String SIMPLE_DATE_PATTERN = "yyyy-MM-dd"; + + private static final String XML = "ComponentCollector"; + + private static final String ACTIVATE_VALUE = "activateValue"; + + private static final String COMP_PKT_CLICK = "cmpPktClick"; + + private static final String DOWNLOAD_PKT_NUM = "downloadPktNum"; + + private static final String DOWNLOAD_CMP = "downloadCmp"; + + private static final int ACTIVATE_INITIAL_VALUE = 1; + + private static final String ACTIVATE_DATE = "date"; + + private static final String GENERATE_CMP_RECORD_NAME = "name"; + + private static final String GENERATE_CMP_RECORD_TYPE = "type"; + + private static final String GENERATE_CMP_RECORD_UUID = "uuid"; + + private static final String HELP_CONFIG_INFO = "helpConfigInfo"; + + private static final String HELP_CONFIG_USE_INFO = "helpConfigUseInfo"; + + private static final String TEMPLATE_ID = "templateId"; + + private static final String SHOW_COUNT = "showCount"; + + private static final String USE_COUNT = "useCount"; + + private static final String GROUPING_DETAIL = "groupingDetail"; + + private static final String GROUP_NAME = "groupName"; + + private static final String CONTAIN_AMOUNT = "containAmount"; + + private static final String SEARCH_CONTENT = "searchContent"; + + private static final String FILTER_CONTENT = "filterContent"; + + private static final String SORT_TYPE = "sortType"; + + private static final String MARKET_CLICK = "marketClick"; + + private static final String uuid = DesignerEnvManager.getEnvManager().getUUID(); + private static ComponentCollector instance; + + private int localCmpNumber = 0; + + private int remoteCmpNumber = 0; + + private int generateCmpNumber = 0; + + private int uploadCmpNumber = 0; + + private int cmpBoardClick = 0; + + private JSONArray activateRecord = JSONFactory.createJSON(JSON.ARRAY); + + private JSONArray generateCmpRecord = JSONFactory.createJSON(JSON.ARRAY); + + private JSONArray helpConfigInfo = JSONFactory.createJSON(JSON.ARRAY); + + private JSONArray searchContent = JSONFactory.createJSON(JSON.ARRAY); + + private JSONArray filterContent = JSONFactory.createJSON(JSON.ARRAY); + + private JSONArray sortType = JSONFactory.createJSON(JSON.ARRAY); + + private String startTime = StringUtils.EMPTY; + + private String lastTime = StringUtils.EMPTY; + + private JSONArray helpConfigUseInfo = JSONFactory.createJSON(JSON.ARRAY); + + private static class ComponentCollectorHolder { + + private static ComponentCollector collector = new ComponentCollector(); + } + + public static ComponentCollector getInstance() { + return ComponentCollectorHolder.collector; + } + + private ComponentCollector() { + + loadFromFile(); + if (StringUtils.isEmpty(startTime)) { + startTime = DateTime.now().toString(SIMPLE_DATE_PATTERN); + } + } + + public void collectGenerateCmpNumber() { + + generateCmpNumber++; + saveInfo(); + } + + public void collectUploadCmpNumber() { + + uploadCmpNumber++; + saveInfo(); + } + + public void collectTepMenuEnterClick() { + + saveInfo(); + } + + public void collectCmpBoardClick() { + collectActivateRecord(); + cmpBoardClick++; + saveInfo(); + } + + public void collectCmpNumber() { + int count = 0; + //默认分组组件数量 + String[] reus = WorkContext.getWorkResource().list(ComponentPath.SHARE_PATH.path(), new ReuFilter()); + count += reus.length; + + //其他分组组件数量 + String[] groups = WorkContext.getWorkResource().list(ComponentPath.SHARE_PATH.path(), new DirFilter()); + for (String groupName : groups) { + String relativePath = StableUtils.pathJoin(ComponentPath.SHARE_PATH.path(), groupName); + String[] groupReus = WorkContext.getWorkResource().list(relativePath, new ReuFilter()); + count += groupReus.length; + } + + if (WorkContext.getCurrent().isLocal()) { + localCmpNumber = count; + } else { + remoteCmpNumber = count; + } + saveInfo(); + } + + public void collectCmpPktClick() { + collectAttrActiveCount(COMP_PKT_CLICK); + saveInfo(); + } + + public void collectDownloadPktNum() { + collectAttrActiveCount(DOWNLOAD_PKT_NUM); + saveInfo(); + } + + public void collectMarkerClick() { + collectAttrActiveCount(MARKET_CLICK); + } + + public void clearActiveRecord() { + String currentDate = DateTime.now().toString(SIMPLE_DATE_PATTERN); + Iterator iterator = activateRecord.iterator(); + while (iterator.hasNext()) { + JSONObject jo = (JSONObject) iterator.next(); + if (!ComparatorUtils.equals(currentDate, jo.getString(ACTIVATE_DATE))) { + iterator.remove(); + } + } + } + + public void collectGenerateCmpRecord(SharableWidgetProvider bindInfo) { + JSONObject jo = JSONFactory.createJSON(JSON.OBJECT); + jo.put(GENERATE_CMP_RECORD_NAME, bindInfo.getName()) + .put(GENERATE_CMP_RECORD_TYPE, ((DefaultSharableWidget) bindInfo).getChildClassify()) + .put(GENERATE_CMP_RECORD_UUID, bindInfo.getId()); + generateCmpRecord.add(jo); + } + + public void clearGenerateCmpRecord() { + generateCmpRecord = JSONFactory.createJSON(JSON.ARRAY); + } + + public void collectCmpDownLoad(String uuid) { + String currentDate = DateTime.now().toString(SIMPLE_DATE_PATTERN); + for (int i = 0; i < activateRecord.size(); i++) { + JSONObject jo = activateRecord.getJSONObject(i); + if (ComparatorUtils.equals(currentDate, jo.getString(ACTIVATE_DATE))) { + JSONArray downloadComp = jo.containsKey(DOWNLOAD_CMP) ? jo.getJSONArray(DOWNLOAD_CMP) : JSONFactory.createJSON(JSON.ARRAY); + downloadComp.add(uuid); + jo.put(DOWNLOAD_CMP, downloadComp); + saveInfo(); + return; + } + } + JSONObject jo = JSONFactory.createJSON(JSON.OBJECT); + jo.put(ACTIVATE_DATE, currentDate).put(DOWNLOAD_CMP, JSONFactory.createJSON(JSON.ARRAY).add(uuid)); + activateRecord.add(jo); + saveInfo(); + } + + public JSONArray getActivateRecord() { + return activateRecord; + } + + public JSONArray getGenerateCmpRecord() { + return generateCmpRecord; + } + + private void collectActivateRecord() { + collectAttrActiveCount(ACTIVATE_VALUE); + } + + private void collectAttrActiveCount(String attrName) { + String currentDate = DateTime.now().toString(SIMPLE_DATE_PATTERN); + for (int i = 0; i < activateRecord.size(); i++) { + JSONObject jo = activateRecord.getJSONObject(i); + if (ComparatorUtils.equals(currentDate, jo.getString(ACTIVATE_DATE))) { + int attrNum = jo.getInt(attrName); + attrNum++; + jo.put(attrName, attrNum); + return; + } + } + JSONObject jo = JSONFactory.createJSON(JSON.OBJECT); + jo.put(ACTIVATE_DATE, currentDate).put(attrName, ACTIVATE_INITIAL_VALUE); + activateRecord.add(jo); + } + + + private JSONArray getGroupingDetail() { + JSONArray ja = JSONFactory.createJSON(JSON.ARRAY); + Group[] groups = DefaultShareGroupManager.getInstance().getAllGroup(); + for(Group group : groups) { + JSONObject jo = JSONFactory.createJSON(JSON.OBJECT); + jo.put(GROUP_NAME, group.getGroupName()); + jo.put(CONTAIN_AMOUNT, group.getAllBindInfoList().length); + ja.add(jo); + } + return ja; + } + + public void collectHelpConfigInfo(String templateId, int showCount, int useCount) { + JSONObject jo = JSONFactory.createJSON(JSON.OBJECT); + jo.put(TEMPLATE_ID, templateId); + jo.put(SHOW_COUNT, showCount); + jo.put(USE_COUNT, useCount); + helpConfigInfo.add(jo); + saveInfo(); + } + + public void clearHelpConfigInfo() { + helpConfigInfo = JSONFactory.createJSON(JSON.ARRAY); + } + + public void collectSearchContent(String search) { + searchContent.add(search); + } + + public void clearSearchContent() { + searchContent = JSONFactory.createJSON(JSON.ARRAY); + } + + public void collectFilterContent(String filter) { + filterContent.add(filter); + saveInfo(); + } + + public void clearFilterContent() { + filterContent = JSONFactory.createJSON(JSON.ARRAY); + } + + public void collectSortType(String type) { + sortType.add(type); + saveInfo(); + } + + public void clearSortType() { + sortType = JSONFactory.createJSON(JSON.ARRAY); + } + + private int cmpBoardClickDaily() { + + DateTime dateTime = DateTime.parse(startTime); + DateTime currTime = DateTime.now(); + int days = (Days.daysBetween(dateTime, currTime).getDays() + 1); + return cmpBoardClick / days; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + /** + * 保存埋点信息到文件中 + */ + public void saveInfo() { + + try { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + XMLTools.writeOutputStreamXML(this, out); + out.flush(); + out.close(); + String fileContent = new String(out.toByteArray(), StandardCharsets.UTF_8); + FileUtils.writeStringToFile(getInfoFile(), fileContent, StandardCharsets.UTF_8); + } catch (Exception ex) { + FineLoggerFactory.getLogger().error(ex.getMessage()); + } + } + + /** + * 从文件中读取埋点信息 + */ + private void loadFromFile() { + + if (!getInfoFile().exists()) { + return; + } + XMLableReader reader = null; + try (InputStream in = new FileInputStream(getInfoFile())) { + // XMLableReader 还是应该考虑实现 Closable 接口的,这样就能使用 try-with 语句了 + reader = XMLReadHelper.createXMLableReader(in, XMLPrintWriter.XML_ENCODER); + if (reader == null) { + return; + } + reader.readXMLObject(this); + } catch (FileNotFoundException e) { + // do nothing + } catch (XMLStreamException | IOException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } finally { + try { + if (reader != null) { + reader.close(); + } + } catch (XMLStreamException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + } + } + + + private File getInfoFile() { + + File file = new File(StableUtils.pathJoin(ProductConstants.getEnvHome(), "component.info")); + try { + if (!file.exists()) { + file.createNewFile(); + } + } catch (Exception ex) { + FineLoggerFactory.getLogger().error(ex.getMessage(), ex); + } + return file; + } + + @Override + public void readXML(XMLableReader reader) { + + String tagName = reader.getTagName(); + if (tagName.equals(XML)) { + this.cmpBoardClick = reader.getAttrAsInt("cmpBoardClick", 0); + this.startTime = reader.getAttrAsString("startTime", StringUtils.EMPTY); + this.lastTime = reader.getAttrAsString("lastTime", StringUtils.EMPTY); + this.localCmpNumber = reader.getAttrAsInt("localCmpNumber", 0); + this.remoteCmpNumber = reader.getAttrAsInt("remoteCmpNumber", 0); + this.generateCmpNumber = reader.getAttrAsInt("generateCmpNumber", 0); + this.uploadCmpNumber = reader.getAttrAsInt("uploadCmpNumber", 0); + + String activateRecordStr = reader.getAttrAsString("activateRecord", StringUtils.EMPTY); + activateRecord = parseJSONArray(activateRecordStr); + String generateCmpRecordStr = reader.getAttrAsString("generateCmpRecord", StringUtils.EMPTY); + generateCmpRecord = parseJSONArray(generateCmpRecordStr); + + this.helpConfigInfo = parseJSONArray(reader.getAttrAsString(HELP_CONFIG_INFO, StringUtils.EMPTY)); + this.helpConfigUseInfo = parseJSONArray(reader.getAttrAsString(HELP_CONFIG_USE_INFO, StringUtils.EMPTY)); + this.searchContent = parseJSONArray(reader.getAttrAsString(SEARCH_CONTENT,StringUtils.EMPTY)); + this.filterContent = parseJSONArray(reader.getAttrAsString(FILTER_CONTENT, StringUtils.EMPTY)); + this.sortType = parseJSONArray(reader.getAttrAsString(SORT_TYPE, StringUtils.EMPTY)); + + } + } + + private JSONArray parseJSONArray(String value) { + JSONArray ja; + try { + ja = new JSONArray(value); + } catch (JSONException e) { + ja = JSONFactory.createJSON(JSON.ARRAY); + + } + return ja; + } + + + @Override + public void writeXML(XMLPrintWriter writer) { + + writer.startTAG(XML) + .attr("cmpBoardClick", cmpBoardClick) + .attr("startTime", startTime) + .attr("lastTime", lastTime) + .attr("localCmpNumber", localCmpNumber) + .attr("remoteCmpNumber", remoteCmpNumber) + .attr("uploadCmpNumber", uploadCmpNumber) + .attr("generateCmpNumber", generateCmpNumber) + .attr("activateRecord", activateRecord.toString()) + .attr("generateCmpRecord", generateCmpRecord.toString()) + .attr(HELP_CONFIG_INFO, helpConfigInfo.toString()) + .attr(HELP_CONFIG_USE_INFO, helpConfigUseInfo.toString()) + .attr(SEARCH_CONTENT, searchContent.toString()) + .attr(FILTER_CONTENT, filterContent.toString()) + .attr(SORT_TYPE, sortType.toString()) + .end(); + } + + /** + * 累计信息 + */ + public String generateTotalInfo() { + collectCmpNumber(); + JSONObject jo = JSONObject.create(); + jo.put("userId", MarketConfig.getInstance().getBBSAttr().getBbsUid()); + jo.put("uuid", uuid); + jo.put("cmpBoardClickDaily", cmpBoardClickDaily()); + jo.put("pluginVersion", PluginContexts.currentContext().getVersion()); + jo.put("localCmpNumber", localCmpNumber); + jo.put("remoteCmpNumber", remoteCmpNumber); + jo.put("uploadCmpNumber", uploadCmpNumber); + jo.put("generateCmpNumber", generateCmpNumber); + jo.put("activateRecord", getValidActivateRecord()); + jo.put("generateCmpRecord", generateCmpRecord.toString()); + jo.put(HELP_CONFIG_INFO, helpConfigInfo.toString()); + jo.put(GROUPING_DETAIL, getGroupingDetail().toString()); + jo.put(SEARCH_CONTENT, searchContent.toString()); + jo.put(FILTER_CONTENT, filterContent.toString()); + jo.put(SORT_TYPE, sortType.toString()); + return jo.toString(); + } + + public String getValidActivateRecord() { + JSONArray result = JSONFactory.createJSON(JSON.ARRAY); + String currentDate = DateTime.now().toString(SIMPLE_DATE_PATTERN); + for (Object o : activateRecord) { + JSONObject jo = (JSONObject) o; + if (!ComparatorUtils.equals(currentDate, jo.getString(ACTIVATE_DATE))) { + result.add(jo); + } + } + return result.toString(); + } + + @Override + public Object clone() throws CloneNotSupportedException { + + return null; + } + + public void setHelpConfigUseInfo(String templateId, String widgetId) { + for (int i = 0; i < helpConfigUseInfo.size(); i++) { + JSONObject jo = helpConfigUseInfo.getJSONObject(i); + if (ComparatorUtils.equals(templateId, jo.getString(TEMPLATE_ID))) { + JSONArray useInfo = jo.getJSONArray(HELP_CONFIG_USE_INFO); + if (!useInfo.contains(widgetId)) { + useInfo.add(widgetId); + } + jo.put(HELP_CONFIG_USE_INFO, useInfo); + return; + } + } + JSONObject jo = JSONFactory.createJSON(JSON.OBJECT); + JSONArray ja = JSONFactory.createJSON(JSON.ARRAY); + ja.add(widgetId); + jo.put(TEMPLATE_ID, templateId); + jo.put(HELP_CONFIG_USE_INFO, ja); + helpConfigUseInfo.add(jo); + saveInfo(); + } + + public JSONArray getHelpConfigUseInfoWithTemplate(String templateId) { + for (int i = 0; i < helpConfigUseInfo.size(); i++) { + JSONObject jo = helpConfigUseInfo.getJSONObject(i); + if (ComparatorUtils.equals(templateId, jo.getString(TEMPLATE_ID))) { + return jo.getJSONArray(HELP_CONFIG_USE_INFO); + } + } + return JSONFactory.createJSON(JSON.ARRAY); + } + + public void clear(){ + clearActiveRecord(); + clearGenerateCmpRecord(); + clearFilterContent(); + clearHelpConfigInfo(); + clearSearchContent(); + clearSortType(); + saveInfo(); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/collect/ComponentSender.java b/designer-form/src/main/java/com/fr/design/mainframe/share/collect/ComponentSender.java new file mode 100644 index 000000000..5043e5fb7 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/collect/ComponentSender.java @@ -0,0 +1,45 @@ +package com.fr.design.mainframe.share.collect; + +import com.fr.design.mainframe.SiteCenterToken; +import com.fr.general.ComparatorUtils; +import com.fr.general.http.HttpToolbox; +import com.fr.json.JSONObject; +import com.fr.log.FineLoggerFactory; + +import java.util.HashMap; +import java.util.Map; + +/** + * created by Harrison on 2020/03/25 + **/ +public class ComponentSender { + + private static final String CLOUD_REUSE_URL = "https://cloud.fanruan.com/api/monitor/record_of_reusePlugin/single"; + + public static boolean send() { + + long start = System.currentTimeMillis(); + + String content = ComponentCollector.getInstance().generateTotalInfo(); + + long end = System.currentTimeMillis(); + FineLoggerFactory.getLogger().error("cal time cost {} ms", end - start); + return sendInfo(CLOUD_REUSE_URL, content); + } + + private static boolean sendInfo(String url, String content) { + + Map para = new HashMap<>(); + para.put("token", SiteCenterToken.generateToken()); + para.put("content", content); + + try { + String res = HttpToolbox.post(url, para); + return ComparatorUtils.equals(new JSONObject(res).get("status"), "success"); + } catch (Throwable e) { + // 客户不需要关心,错误等级为 debug 就行了 + FineLoggerFactory.getLogger().debug(e.getMessage(), e); + } + return false; + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/constants/ComponentType.java b/designer-form/src/main/java/com/fr/design/mainframe/share/constants/ComponentType.java new file mode 100644 index 000000000..bb1f1976d --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/constants/ComponentType.java @@ -0,0 +1,18 @@ +package com.fr.design.mainframe.share.constants; + +import java.util.List; + +/** + * created by Harrison on 2020/04/20 + **/ +public interface ComponentType { + + List children(int device); + + /** + * 返回子类型所有 + * + * @return + */ + List types(); +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/constants/ComponentTypes.java b/designer-form/src/main/java/com/fr/design/mainframe/share/constants/ComponentTypes.java new file mode 100644 index 000000000..e7f30c7a2 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/constants/ComponentTypes.java @@ -0,0 +1,193 @@ +package com.fr.design.mainframe.share.constants; + +import com.fr.design.i18n.Toolkit; + +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +/** + * created by Harrison on 2020/04/20 + **/ +public enum ComponentTypes implements ComponentType { + + CHART("Fine-Design_Share_Type_Basic_Element") { + @Override + public List children(int device) { + + return ChartChildTypes.support(device); + } + + @Override + public List types() { + List list = new ArrayList<>(); + for (ChartChildTypes types : ChartChildTypes.values()) { + list.add(types.getLocText()); + } + return list; + } + }, + + REPORT("Fine-Design_Share_Type_Report") { + @Override + public List children(int device) { + + if (DisplayDevice.supportMobile(device)) { + return ReportChildTypes.support(DisplayDevice.MOBILE.getType()); + } + return ReportChildTypes.support(DisplayDevice.PC.getType()); + } + + @Override + public List types() { + List list = new ArrayList<>(); + for (ReportChildTypes types : ReportChildTypes.values()) { + list.add(types.getLocText()); + } + return list; + } + }; + + /** + * 所有类型 + * + * @return + */ + public static List allTypes() { + List allTypes = new ArrayList<>(); + Set set = new LinkedHashSet<>(); + for (ComponentTypes types : values()) { + set.addAll(types.children(DisplayDevice.MOBILE.getType())); + set.addAll(types.children(DisplayDevice.PC.getType())); + } + allTypes.addAll(set); + return allTypes; + } + + /** + * 根据终端返回所有类型 + * + * @param device + * @return + */ + public static List allTypesByDevice(int device) { + List allTypes = new ArrayList<>(); + for (ComponentTypes types : values()) { + allTypes.addAll(types.children(device)); + } + return allTypes; + } + + private enum ReportChildTypes { + + INDICATOR_CARD("Fine-Design_Share_Type_Indicator_Card"), + + TITLE("Fine-Design_Share_Type_Title"), + + DIMENSION_CHANGE("Fine-Design_Share_Type_Dimension_Change"), + + FILL("Fine-Design_Share_Type_Fill", DisplayDevice.MOBILE), + + Directory_Navigation("Fine-Design_Share_Type_Mobile_Directory_Navigation", DisplayDevice.MOBILE), + + + SPECIAL_CARD("Fine-Design_Share_Type_Special_Card"); + + private String locale; + + /** + * @see DisplayDevice + */ + private int support; + + ReportChildTypes(String locale) { + this(locale, DisplayDevice.buildAll()); + } + + ReportChildTypes(String locale, DisplayDevice device) { + this(locale, device.getType()); + } + + ReportChildTypes(String locale, int support) { + this.locale = locale; + this.support = support; + } + + public static List support(int device) { + + List list = new ArrayList<>(); + ReportChildTypes[] values = ReportChildTypes.values(); + for (ReportChildTypes value : values) { + //支持当前设备 + if (DisplayDevice.supportDevice(device, value.support)) { + list.add(value.getLocText()); + } + } + return list; + } + + public String getLocText() { + + return Toolkit.i18nText(this.locale); + } + } + + private enum ChartChildTypes { + + COLUMN_CHART("Fine-Design_Share_Type_Chart_Column"), + + PIE_CHART("Fine-Design_Share_Type_Chart_Pie"), + + FOLD_LINE_CHART("Fine-Design_Share_Type_Chart_Fold_Line"), + + COMBINE_CHART("Fine-Design_Share_Type_Chart_Combine"), + + METER_CHART("Fine-Design_Share_Type_Chart_Meter"), + + MAP_CHART("Fine-Design_Share_Type_Chart_Map"), + + OTHERS("Fine-Design_Share_Type_Chart_Other"), + + DETAIL_LIST("Fine-Design_Share_Type_Detail_List"), + + BASIC_WIDGET("Fine-Design_Share_Type_Basic_Widget"); + + private String locale; + + ChartChildTypes(String locale) { + this.locale = locale; + } + + public static List support(int device) { + + List list = new ArrayList<>(); + ChartChildTypes[] values = ChartChildTypes.values(); + for (ChartChildTypes value : values) { + list.add(value.getLocText()); + } + return list; + } + + public String getLocText() { + + return Toolkit.i18nText(this.locale); + } + } + + private String locale; + + ComponentTypes(String locale) { + this.locale = locale; + } + + public String getLocText() { + + return Toolkit.i18nText(this.locale); + } + + @Override + public String toString() { + return getLocText(); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/constants/DisplayDevice.java b/designer-form/src/main/java/com/fr/design/mainframe/share/constants/DisplayDevice.java new file mode 100644 index 000000000..87f77241c --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/constants/DisplayDevice.java @@ -0,0 +1,66 @@ +package com.fr.design.mainframe.share.constants; + +/** + * created by Harrison on 2020/04/21 + **/ +public enum DisplayDevice { + + NONE(0), + + MOBILE(1), + + PC(2); + + private int type; + + DisplayDevice(int type) { + this.type = type; + } + + public int getType() { + return type; + } + + public static int buildAll() { + + int support = 0; + DisplayDevice[] values = DisplayDevice.values(); + for (DisplayDevice value : values) { + support |= value.getType(); + } + return support; + } + + public static int buildDevice(Iterable devices) { + + int support = 0; + if (devices == null) { + return support; + } + for (DisplayDevice device : devices) { + support |= device.type; + } + return support; + } + + public static boolean supportDevice(int device, int support) { + + return device == buildAll() || (support & device) == device; + } + + public static boolean supportMobile(int device) { + + return (device & MOBILE.getType()) == MOBILE.getType(); + } + + public static boolean supportPC(int device) { + + return (device & PC.getType()) == PC.getType(); + } + + private static int calVal(DisplayDevice device) { + + return 1 << device.type; + } + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/constants/ShareEntryKey.java b/designer-form/src/main/java/com/fr/design/mainframe/share/constants/ShareEntryKey.java new file mode 100644 index 000000000..a873325f5 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/constants/ShareEntryKey.java @@ -0,0 +1,6 @@ +package com.fr.design.mainframe.share.constants; + +public class ShareEntryKey { + static public final String SHARE_GENERATE = "ShareGeneratePane"; + static public final String SHARE_CONFIG = "ShareConfigPane"; +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/constants/StyleTheme.java b/designer-form/src/main/java/com/fr/design/mainframe/share/constants/StyleTheme.java new file mode 100644 index 000000000..1738eb5cb --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/constants/StyleTheme.java @@ -0,0 +1,81 @@ +package com.fr.design.mainframe.share.constants; + +import com.fr.design.i18n.Toolkit; +import com.fr.form.share.bean.StyleThemeBean; +import com.fr.form.share.bean.WidgetFilterInfo; +import com.fr.form.share.bean.WidgetFilterTypeInfo; +import com.fr.form.share.constants.ShareComponentConstants; +import com.fr.form.share.utils.ShareUtils; +import com.fr.general.ComparatorUtils; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * Created by kerry on 2020-12-09 + */ +public enum StyleTheme { + + SIMPLE_FRESH("Fine-Design_Share_Style_Theme_Simple", "1"), + BUSINESS_STABLE("Fine-Design_Share_Style_Theme_Business", "2"), + LIVE_GORGEOUS("Fine-Design_Share_Style_Theme_Live", "3"), + COOL_TECHNOLOGY("Fine-Design_Share_Style_Theme_Cool", "4"), + OTHER_THEME("Fine-Design_Share_Style_Theme_Other", "5"); + + + private final String local; + private final String id; + + StyleTheme(String name, String id) { + this.local = name; + this.id = id; + } + + public String getLocText() { + return Toolkit.i18nText(this.local); + } + + public String getId() { + return this.id; + } + + private static List types() { + List list = new ArrayList<>(); + for (StyleTheme type : StyleTheme.values()) { + list.add(new StyleThemeBean(type.getId(), type.getLocText())); + } + return list; + } + + /** + * 获取样式风格属性list + * + * @return List + */ + public static List getStyleThemeTypeInfo() { + List widgetFilterTypeInfos = ShareUtils.getWidgetFilterTypeInfos(); + if (widgetFilterTypeInfos.isEmpty()) { + return types(); + } + WidgetFilterTypeInfo styleThemeFilterInfo = new WidgetFilterTypeInfo(); + for (WidgetFilterTypeInfo typeInfo : widgetFilterTypeInfos) { + if (ComparatorUtils.equals(ShareComponentConstants.STYLE_THEME_KEY, typeInfo.getKey())) { + styleThemeFilterInfo = typeInfo; + break; + } + } + List resultList = new ArrayList<>(); + List filterInfoList = styleThemeFilterInfo.getFilterItems(); + Iterator infoIterator = filterInfoList.iterator(); + while (infoIterator.hasNext()) { + WidgetFilterInfo filterInfo = infoIterator.next(); + if (!ComparatorUtils.equals(ShareComponentConstants.ALL_STYLE_THEME, filterInfo.getId())) { + resultList.add(new StyleThemeBean(filterInfo.getId(), filterInfo.getName())); + } + } + return resultList; + } + + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/exception/LackOfValueException.java b/designer-form/src/main/java/com/fr/design/mainframe/share/exception/LackOfValueException.java new file mode 100644 index 000000000..53d0b1258 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/exception/LackOfValueException.java @@ -0,0 +1,14 @@ +package com.fr.design.mainframe.share.exception; + +import com.fr.design.i18n.Toolkit; + +/** + * created by Harrison on 2020/04/21 + **/ +public class LackOfValueException extends RuntimeException{ + + public LackOfValueException() { + + super(Toolkit.i18nText("Fine-Design_Share_Lack_Val")); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/generate/AbstractComponentTask.java b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/AbstractComponentTask.java new file mode 100644 index 000000000..0e88a5bf9 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/AbstractComponentTask.java @@ -0,0 +1,9 @@ +package com.fr.design.mainframe.share.generate; + +/** + * created by Harrison on 2020/04/23 + **/ +public abstract class AbstractComponentTask implements ComponentTask { + + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/generate/ComponentBanner.java b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/ComponentBanner.java new file mode 100644 index 000000000..aa812b82a --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/ComponentBanner.java @@ -0,0 +1,14 @@ +package com.fr.design.mainframe.share.generate; + +/** + * created by Harrison on 2020/04/13 + **/ +public interface ComponentBanner { + + /** + * 加载文字 + * + * @return 加载 + */ + String getLoadingText(); +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/generate/ComponentCreatorProcessor.java b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/ComponentCreatorProcessor.java new file mode 100644 index 000000000..4d38dc98a --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/ComponentCreatorProcessor.java @@ -0,0 +1,20 @@ +package com.fr.design.mainframe.share.generate; + +import com.fr.design.mainframe.JTemplate; +import com.fr.form.share.DefaultSharableWidget; +import com.fr.form.share.bean.ComponentReuBean; +import com.fr.form.ui.Widget; +import com.fr.stable.fun.mark.Immutable; + +import java.util.Map; + +/** + * Created by kerry on 2020-07-30 + */ +public interface ComponentCreatorProcessor extends ComponentBanner, Immutable { + + String MARK_STRING = "ComponentCreatorProcessor"; + int CURRENT_LEVEL = 1; + + ComponentReuBean create(JTemplate jt, Map paraMap, Widget widget, DefaultSharableWidget info) throws Exception; +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/generate/ComponentGenerator.java b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/ComponentGenerator.java new file mode 100644 index 000000000..5728f8fee --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/ComponentGenerator.java @@ -0,0 +1,22 @@ +package com.fr.design.mainframe.share.generate; + +/** + * created by Harrison on 2020/04/16 + **/ +public interface ComponentGenerator { + + /** + * 生成组件 + * + * @return 组件 + */ + boolean generate() throws Throwable; + + /** + * 耗时/速率 + * + * @return 时间 + */ + int speed(); + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/generate/ComponentGeneratorCenter.java b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/ComponentGeneratorCenter.java new file mode 100644 index 000000000..739ad2390 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/ComponentGeneratorCenter.java @@ -0,0 +1,68 @@ +package com.fr.design.mainframe.share.generate; + +import com.fr.design.mainframe.share.Bean.ComponentGenerateInfo; +import com.fr.design.mainframe.share.generate.impl.ComponentPureGenerator; +import com.fr.design.mainframe.share.generate.impl.ComponentUploadGenerator; +import com.fr.design.mainframe.share.ui.base.ShareProgressBar; +import com.fr.log.FineLoggerFactory; + +import java.util.concurrent.Future; + +/** + * created by Harrison on 2020/04/13 + **/ +public class ComponentGeneratorCenter { + + private ComponentGenerateInfo info; + + public ComponentGeneratorCenter(ComponentGenerateInfo info) { + + this.info = info; + } + + public boolean generate() throws Exception { + + try { + + return generate0(); + } catch (RuntimeException e) { + throw e; + } catch (Throwable throwable) { + FineLoggerFactory.getLogger().error(throwable.getMessage(), throwable); + return false; + } finally { + ShareProgressBar.getInstance().completeNow(); + } + } + + private boolean generate0() throws Throwable{ + + ComponentGenerator generator = innerGenerator(); + + //ui + ShareProgressBar progressBar = ShareProgressBar.getInstance(); + progressBar.prepare(generator.speed()); + progressBar.monitor(); + + return generator.generate(); + } + + private void waitComplete(Future complete) { + + try { + complete.get(); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + } + + private ComponentGenerator innerGenerator() { + + if (info.isAutoUpload()) { + return ComponentUploadGenerator.create(info); + } else { + return ComponentPureGenerator.create(info); + } + } + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/generate/ComponentTask.java b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/ComponentTask.java new file mode 100644 index 000000000..3fb8521f7 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/ComponentTask.java @@ -0,0 +1,13 @@ +package com.fr.design.mainframe.share.generate; + +/** + * created by Harrison on 2020/04/23 + **/ +public interface ComponentTask { + + T execute() throws Exception; + + double indicator(); + + String getLoadingText(); +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/generate/ComponentTaskAdaptor.java b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/ComponentTaskAdaptor.java new file mode 100644 index 000000000..16b8f9774 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/ComponentTaskAdaptor.java @@ -0,0 +1,26 @@ +package com.fr.design.mainframe.share.generate; + +/** + * created by Harrison on 2020/04/23 + **/ +public abstract class ComponentTaskAdaptor extends AbstractComponentTask { + + private double indicator; + + private String loadingText; + + public ComponentTaskAdaptor(double indicator, String loadingText) { + this.indicator = indicator; + this.loadingText = loadingText; + } + + @Override + public double indicator() { + return this.indicator; + } + + @Override + public String getLoadingText() { + return this.loadingText; + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/generate/impl/AbstractComponentCreatorProcessor.java b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/impl/AbstractComponentCreatorProcessor.java new file mode 100644 index 000000000..e0d17bfed --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/impl/AbstractComponentCreatorProcessor.java @@ -0,0 +1,24 @@ +package com.fr.design.mainframe.share.generate.impl; + +import com.fr.design.mainframe.share.generate.ComponentCreatorProcessor; +import com.fr.stable.fun.mark.API; + +/** + * Created by kerry on 2020-07-30 + */ +@API(level = ComponentCreatorProcessor.CURRENT_LEVEL) +public abstract class AbstractComponentCreatorProcessor implements ComponentCreatorProcessor { + + + @Override + public int currentAPILevel() { + return CURRENT_LEVEL; + } + + @Override + public int layerIndex() { + return DEFAULT_LAYER_INDEX; + } + + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/generate/impl/AbstractComponentGenerator.java b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/impl/AbstractComponentGenerator.java new file mode 100644 index 000000000..6fb514117 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/impl/AbstractComponentGenerator.java @@ -0,0 +1,161 @@ +package com.fr.design.mainframe.share.generate.impl; + +import com.fr.design.mainframe.share.Bean.ComponentGenerateInfo; +import com.fr.design.mainframe.share.generate.ComponentBanner; +import com.fr.design.mainframe.share.generate.ComponentCreatorProcessor; +import com.fr.design.mainframe.share.generate.ComponentGenerator; +import com.fr.design.mainframe.share.generate.ComponentTask; +import com.fr.design.mainframe.share.generate.task.ComponentCreator; +import com.fr.design.mainframe.share.ui.base.ShareProgressBar; +import com.fr.design.mainframe.share.util.ShareUIUtils; +import com.fr.log.FineLoggerFactory; +import com.fr.report.ExtraReportClassManager; +import com.fr.third.org.apache.commons.lang3.time.StopWatch; + +import javax.swing.SwingWorker; +import java.util.concurrent.BrokenBarrierException; +import java.util.concurrent.Callable; +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.FutureTask; +import java.util.concurrent.TimeUnit; + +/** + * created by Harrison on 2020/04/16 + **/ +public abstract class AbstractComponentGenerator implements ComponentGenerator { + + /** + * 默认 40 ms + */ + private static final int DEFAULT_SPEED = 40; + + /** + * 进度 100 + */ + private static final int PROGRESS = 100; + + /** + * 每一个任务平均耗时 2000 ms + */ + private static final int PER_TIME = 2000; + + private final int speed; + + private ComponentGenerateInfo info; + + public AbstractComponentGenerator(ComponentGenerateInfo info, ComponentBanner... banners) { + this.info = info; + this.speed = calSpeed(banners); + } + + public ComponentGenerateInfo getInfo() { + return info; + } + + private int calSpeed(ComponentBanner... banners) { + + if (banners == null || banners.length == 0) { + return DEFAULT_SPEED; + } + return PER_TIME / (PROGRESS / banners.length); + } + + /** + * 进度条 100 + * 目前有 n 个任务 + * 每个任务至少 2000 ms + *

+ * 则平均速度为 2000 / (100/n) + */ + @Override + public int speed() { + + return this.speed; + } + + @Override + public boolean generate() throws Throwable { + + try { + return generate0(); + } catch (ExecutionException e) { + //抛出根本原因 + throw e.getCause(); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + return false; + } + } + + protected abstract boolean generate0() throws InterruptedException, ExecutionException; + + protected T execute(final ComponentTask componentTask) throws InterruptedException, ExecutionException { + + final CyclicBarrier barrier = new CyclicBarrier(2); + Thread UIThread = new Thread(new FutureTask(new Callable() { + @Override + public Void call() throws Exception { + SwingWorker worker = new SwingWorker() { + @Override + protected Void doInBackground() throws Exception { + + StopWatch stopWatch = new StopWatch(); + stopWatch.start(); + + //ui更新 + doUIUpdate(); + + stopWatch.stop(); + long time = stopWatch.getTime(TimeUnit.MILLISECONDS); + if (time < 2000L) { + //不到 2 s + ShareUIUtils.wait((int) (2000L - time)); + } + + //完成更新 + finishUpdate(); + return null; + } + + private int finishUpdate() throws InterruptedException, BrokenBarrierException { + return barrier.await(); + } + + private void doUIUpdate() throws Exception { + ShareProgressBar.getInstance().updateProgress(componentTask.indicator(), componentTask.getLoadingText()); + } + }; + worker.execute(); + return null; + } + })); + UIThread.setName("Component-UIThread"); + + FutureTask task = new FutureTask<>(new Callable() { + @Override + public T call() throws Exception { + T result = componentTask.execute(); + barrier.await(); + return result; + } + }); + Thread workThread = new Thread(task); + workThread.setName("Component-WorkThread"); + parallel(UIThread, workThread); + return task.get(); + } + + private void parallel(Thread UIThread, Thread workThread) { + + UIThread.start(); + workThread.start(); + } + + + public static ComponentCreatorProcessor getComponentCreator(){ + ComponentCreatorProcessor processor = ExtraReportClassManager.getInstance().getSingle(ComponentCreatorProcessor.MARK_STRING, ComponentCreator.class); + return processor; + } + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/generate/impl/ComponentPureGenerator.java b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/impl/ComponentPureGenerator.java new file mode 100644 index 000000000..d03f55240 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/impl/ComponentPureGenerator.java @@ -0,0 +1,57 @@ +package com.fr.design.mainframe.share.generate.impl; + +import com.fr.design.mainframe.share.Bean.ComponentGenerateInfo; +import com.fr.design.mainframe.share.generate.ComponentCreatorProcessor; +import com.fr.design.mainframe.share.generate.ComponentTaskAdaptor; +import com.fr.design.mainframe.share.generate.task.ComponentGenerateComplete; +import com.fr.form.share.bean.ComponentReuBean; + +import java.util.concurrent.ExecutionException; + +/** + * created by Harrison on 2020/04/16 + **/ +public class ComponentPureGenerator extends AbstractComponentGenerator { + + private ComponentCreatorProcessor creator; + + private ComponentGenerateComplete complete; + + private ComponentPureGenerator(ComponentGenerateInfo info, ComponentCreatorProcessor creator, ComponentGenerateComplete complete) { + + super(info, creator, complete); + this.creator = creator; + this.complete = complete; + } + + public static ComponentPureGenerator create(ComponentGenerateInfo info) { + + ComponentCreatorProcessor creator = getComponentCreator(); + ComponentGenerateComplete complete = new ComponentGenerateComplete(); + return new ComponentPureGenerator(info, creator, complete); + } + + @Override + protected boolean generate0() throws InterruptedException, ExecutionException { + + final ComponentGenerateInfo info = getInfo(); + ComponentTaskAdaptor createTest = new ComponentTaskAdaptor(1.0, creator.getLoadingText()) { + @Override + public ComponentReuBean execute() throws Exception { + return creator.create(info.getJt(), info.getParaMap(), info.getWidget(), info.getInfo()); + } + }; + ComponentReuBean bean = execute(createTest); + + ComponentTaskAdaptor completeTask = new ComponentTaskAdaptor(1.0, complete.getLoadingText()) { + @Override + public Void execute() throws Exception { + complete.execute(); + return null; + } + }; + Void result = execute(completeTask); + return true; + } + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/generate/impl/ComponentUploadGenerator.java b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/impl/ComponentUploadGenerator.java new file mode 100644 index 000000000..58084c344 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/impl/ComponentUploadGenerator.java @@ -0,0 +1,99 @@ +package com.fr.design.mainframe.share.generate.impl; + +import com.fr.design.mainframe.share.Bean.ComponentGenerateInfo; +import com.fr.design.mainframe.share.generate.ComponentCreatorProcessor; +import com.fr.design.mainframe.share.generate.ComponentTaskAdaptor; +import com.fr.design.mainframe.share.generate.task.ComponentDesensitize; +import com.fr.design.mainframe.share.generate.task.ComponentEncrypt; +import com.fr.design.mainframe.share.generate.task.ComponentUploadComplete; +import com.fr.design.mainframe.share.generate.task.ComponentUploader; +import com.fr.form.share.bean.ComponentReuBean; + +import java.util.concurrent.ExecutionException; + +/** + * created by Harrison on 2020/04/16 + **/ +public class ComponentUploadGenerator extends AbstractComponentGenerator { + + private ComponentCreatorProcessor creator; + + private ComponentEncrypt encrypt; + + private ComponentDesensitize desensitize; + + private ComponentUploader uploader; + + private ComponentUploadComplete complete; + + private ComponentUploadGenerator(ComponentGenerateInfo info, ComponentCreatorProcessor creator, ComponentEncrypt encrypt, ComponentDesensitize desensitize, ComponentUploader uploader, ComponentUploadComplete complete) { + + super(info, creator, desensitize, encrypt, uploader); + this.creator = creator; + this.encrypt = encrypt; + this.desensitize = desensitize; + this.uploader = uploader; + this.complete = complete; + } + + public static ComponentUploadGenerator create(ComponentGenerateInfo info) { + + ComponentCreatorProcessor creator = getComponentCreator(); + ComponentUploader uploader = new ComponentUploader(); + ComponentEncrypt encrypt = new ComponentEncrypt(); + ComponentDesensitize desensitize = new ComponentDesensitize(); + ComponentUploadComplete complete = new ComponentUploadComplete(); + return new ComponentUploadGenerator(info, creator, encrypt, desensitize, uploader, complete); + } + + @Override + protected boolean generate0() throws InterruptedException, ExecutionException { + final ComponentGenerateInfo info = getInfo(); + //创建 + ComponentTaskAdaptor createTask = new ComponentTaskAdaptor(0.20, creator.getLoadingText()) { + @Override + public ComponentReuBean execute() throws Exception { + return creator.create(info.getJt(), info.getParaMap(), info.getWidget(), info.getInfo()); + } + }; + final ComponentReuBean plainBean = execute(createTask); + + //脱敏 + ComponentTaskAdaptor desensitizeTask = new ComponentTaskAdaptor(0.60, desensitize.getLoadingText()) { + @Override + public Object execute() throws Exception { + desensitize.execute(); + return null; + } + }; + execute(desensitizeTask); + + //加密 + ComponentTaskAdaptor encryptTask = new ComponentTaskAdaptor(0.85, encrypt.getLoadingText()) { + @Override + public ComponentReuBean execute() throws Exception { + return encrypt.execute(plainBean); + } + }; + final ComponentReuBean encryptBean = execute(encryptTask); + + //上传 + ComponentTaskAdaptor uploadTask = new ComponentTaskAdaptor(1.0, uploader.getLoadingText()) { + @Override + public Boolean execute() throws Exception { + return uploader.upload(encryptBean.getPath()); + } + }; + Boolean success = execute(uploadTask); + + //完成 + final ComponentTaskAdaptor completeTask = new ComponentTaskAdaptor(1.0, complete.getLoadingText()) { + @Override + public Boolean execute() throws Exception { + return complete.execute(); + } + }; + return success && execute(completeTask); + } + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/generate/task/ComponentCreator.java b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/task/ComponentCreator.java new file mode 100644 index 000000000..f93e28426 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/task/ComponentCreator.java @@ -0,0 +1,114 @@ +package com.fr.design.mainframe.share.generate.task; + +import com.fr.base.iofile.attr.ExtendSharableAttrMark; +import com.fr.base.iofile.attr.SharableAttrMark; +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.JTemplate; +import com.fr.design.mainframe.share.generate.impl.AbstractComponentCreatorProcessor; +import com.fr.form.main.Form; +import com.fr.form.main.WidgetGatherAdapter; +import com.fr.form.share.DefaultSharableWidget; +import com.fr.form.share.ShareEmbeddedConverter; +import com.fr.form.share.bean.ComponentReuBean; +import com.fr.form.share.editor.DefaultSharableEditor; +import com.fr.form.share.editor.PlainSharableEditor; +import com.fr.form.share.utils.ShareUtils; +import com.fr.form.ui.AbstractBorderStyleWidget; +import com.fr.form.ui.Widget; +import com.fr.log.FineLoggerFactory; +import com.fr.stable.fun.IOFileAttrMark; +import com.fr.workspace.WorkContext; +import org.jetbrains.annotations.NotNull; + +import java.util.HashMap; +import java.util.Map; + +/** + * created by Harrison on 2020/04/13 + **/ +public class ComponentCreator extends AbstractComponentCreatorProcessor { + + /** + * 生成组件 + * 返回组件的路径 + * + * @return 路径 + */ + @Override + public ComponentReuBean create(JTemplate jt, Map paraMap, Widget widget, DefaultSharableWidget info) throws Exception { + + + // 遍历判断是否存在共享组件 + checkOriginStatus(widget, info); + + // 导出内置数据集 + Form form = embeddedForm(jt, paraMap); + + // 创建组件 + DefaultSharableEditor editor = createSharableEditor(form, paraMap, widget, info); + + // 生成组件 + String generatePath = generate(editor, info); + + + return new ComponentReuBean(generatePath, editor, info); + } + + protected void checkOriginStatus(Widget widget, final DefaultSharableWidget info) { + + Form.traversalWidget(widget, new WidgetGatherAdapter() { + @Override + public void dealWith(Widget widget) { + + AbstractBorderStyleWidget borderStyleWidget = (AbstractBorderStyleWidget) widget; + IOFileAttrMark attrMark = borderStyleWidget.getWidgetAttrMark(SharableAttrMark.XML_TAG); + if (attrMark != null) { + info.setTransform(); + } + } + }, AbstractBorderStyleWidget.class); + } + + @Override + public String getLoadingText() { + + return Toolkit.i18nText("Fine-Design_Share_Generate_Ing"); + } + + /** + * 内置数据集处理 + * + * @return 返回 + */ + protected Form embeddedForm(JTemplate jt, Map paraMap) throws Exception { + + jt.stopEditing(); + + Form tpl = null; + try { + tpl = (Form) jt.getTarget().clone(); + } catch (CloneNotSupportedException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + +// //内置数据集 + ShareEmbeddedConverter embeddedConverter = WorkContext.getCurrent().get(ShareEmbeddedConverter.class); + embeddedConverter.convertToEmbeddedTableData(tpl, paraMap); + + return tpl; + } + + @NotNull + protected DefaultSharableEditor createSharableEditor(Form form, Map paraMap, Widget widget, DefaultSharableWidget info) { + + String uuid = info.getId(); + ((AbstractBorderStyleWidget) widget).addWidgetAttrMark(new SharableAttrMark()); + ((AbstractBorderStyleWidget) widget).addWidgetAttrMark(new ExtendSharableAttrMark(uuid)); + return new PlainSharableEditor(uuid, widget, form, (HashMap) paraMap); + } + + protected String generate(Widget editor, DefaultSharableWidget info) throws Exception { + + return ShareUtils.generateModule(editor, info); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/generate/task/ComponentDesensitize.java b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/task/ComponentDesensitize.java new file mode 100644 index 000000000..5c12877ee --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/task/ComponentDesensitize.java @@ -0,0 +1,44 @@ +package com.fr.design.mainframe.share.generate.task; + +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.share.generate.ComponentBanner; +import com.fr.form.share.exception.NetWorkFailedException; +import com.fr.general.http.HttpRequest; +import com.fr.general.http.HttpToolbox; +import com.fr.log.FineLoggerFactory; +import com.fr.third.org.apache.http.HttpStatus; +import com.fr.third.org.apache.http.client.methods.CloseableHttpResponse; + +/** + * created by Harrison on 2020/04/22 + **/ +public class ComponentDesensitize implements ComponentBanner { + + private static final String TEST_URL = "http://www.baidu.com"; + + public void execute() { + + if (!testNet()) { + throw new NetWorkFailedException(); + } + } + + private boolean testNet() { + + try { + HttpRequest httpRequest = HttpRequest.custom().url(TEST_URL).build(); + CloseableHttpResponse response = HttpToolbox.execute(httpRequest); + if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { + return true; + } + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + return false; + } + + @Override + public String getLoadingText() { + return Toolkit.i18nText("Fine-Design_Share_Desensitize"); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/generate/task/ComponentEncrypt.java b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/task/ComponentEncrypt.java new file mode 100644 index 000000000..b0cd6ef57 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/task/ComponentEncrypt.java @@ -0,0 +1,28 @@ +package com.fr.design.mainframe.share.generate.task; + +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.share.generate.ComponentBanner; +import com.fr.form.share.bean.ComponentReuBean; +import com.fr.workspace.WorkContext; + +/** + * created by Harrison on 2020/04/22 + **/ +public class ComponentEncrypt implements ComponentBanner { + + public ComponentReuBean execute(ComponentReuBean bean) throws Exception { + + try { + return bean; + } catch (Exception e) { + String path = bean.getPath(); + WorkContext.getWorkResource().delete(path); + throw e; + } + } + + @Override + public String getLoadingText() { + return Toolkit.i18nText("Fine-Design_Share_Encrypt"); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/generate/task/ComponentGenerateComplete.java b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/task/ComponentGenerateComplete.java new file mode 100644 index 000000000..47909b849 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/task/ComponentGenerateComplete.java @@ -0,0 +1,19 @@ +package com.fr.design.mainframe.share.generate.task; + +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.share.generate.ComponentBanner; + +/** + * created by Harrison on 2020/04/13 + **/ +public class ComponentGenerateComplete implements ComponentBanner { + + public void execute() throws InterruptedException { + } + + @Override + public String getLoadingText() { + + return Toolkit.i18nText("Fine-Design_Share_Generate_Success"); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/generate/task/ComponentUploadComplete.java b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/task/ComponentUploadComplete.java new file mode 100644 index 000000000..289e2074c --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/task/ComponentUploadComplete.java @@ -0,0 +1,19 @@ +package com.fr.design.mainframe.share.generate.task; + +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.share.generate.ComponentBanner; + +/** + * created by Harrison on 2020/06/16 + **/ +public class ComponentUploadComplete implements ComponentBanner { + + public boolean execute() throws InterruptedException { + return true; + } + + @Override + public String getLoadingText() { + return Toolkit.i18nText("Fine-Design_Share_Upload_Success"); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/generate/task/ComponentUploader.java b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/task/ComponentUploader.java new file mode 100644 index 000000000..ef74d3420 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/task/ComponentUploader.java @@ -0,0 +1,153 @@ +package com.fr.design.mainframe.share.generate.task; + +import com.fr.config.MarketConfig; +import com.fr.design.i18n.Toolkit; +import com.fr.form.share.config.ComponentReuseConfigManager; +import com.fr.design.mainframe.share.generate.ComponentBanner; +import com.fr.io.utils.ResourceIOUtils; +import com.fr.log.FineLoggerFactory; +import com.fr.third.org.apache.http.HttpEntity; +import com.fr.third.org.apache.http.HttpStatus; +import com.fr.third.org.apache.http.client.config.CookieSpecs; +import com.fr.third.org.apache.http.client.config.RequestConfig; +import com.fr.third.org.apache.http.client.entity.UrlEncodedFormEntity; +import com.fr.third.org.apache.http.client.methods.CloseableHttpResponse; +import com.fr.third.org.apache.http.client.methods.HttpPost; +import com.fr.third.org.apache.http.conn.ssl.NoopHostnameVerifier; +import com.fr.third.org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import com.fr.third.org.apache.http.entity.mime.HttpMultipartMode; +import com.fr.third.org.apache.http.entity.mime.MultipartEntityBuilder; +import com.fr.third.org.apache.http.entity.mime.content.ByteArrayBody; +import com.fr.third.org.apache.http.impl.client.BasicCookieStore; +import com.fr.third.org.apache.http.impl.client.CloseableHttpClient; +import com.fr.third.org.apache.http.impl.client.HttpClients; +import com.fr.third.org.apache.http.message.BasicNameValuePair; +import com.fr.third.org.apache.http.ssl.SSLContextBuilder; +import com.fr.third.org.apache.http.ssl.TrustStrategy; +import com.fr.workspace.WorkContext; +import org.jetbrains.annotations.NotNull; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLContext; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.List; + +/** + * 组件上传 + *

+ * created by Harrison on 2020/04/13 + **/ +public class ComponentUploader implements ComponentBanner { + + //private static final String MARKET_LOGIN = CloudCenter.getInstance().acquireUrlByKind("market.login", "https://market.fanruan.com/ShopServer?pg=login&_=1590635085629"); + //private static final String MARKET_REU_FILE_UPLOAD = CloudCenter.getInstance().acquireUrlByKind("market.reuses.upload", "https://market.fanruan.com/reuses/upload"); + + /** + * 先用临时的。 暂时不上线 + */ + private static final String URL_MARKET_LOGIN = ComponentReuseConfigManager.getInstance().getMarketLoginUrl(); + private static final String URL_MARKET_REU_FILE_UPLOAD = ComponentReuseConfigManager.getInstance().getComponentUploadUrl(); + + private static final String KEY_USERNAME = "username"; + private static final String KEY_PASSWORD = "password"; + private static final String KEY_FILE = "file"; + + public boolean upload(String path) { + + boolean success = false; + try { + success = upload0(path); + } catch (Exception e) { + WorkContext.getWorkResource().delete(path); + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + return success; + } + + @Override + public String getLoadingText() { + + return Toolkit.i18nText("Fine-Design_Share_Encrypt"); + } + + private boolean upload0(String path) throws Exception { + + CloseableHttpClient client = createClient(); + if (login(client)) { + HttpPost uploadRequest = new HttpPost(URL_MARKET_REU_FILE_UPLOAD); + byte[] bytes = WorkContext.getWorkResource().readFully(path); + String fileName = ResourceIOUtils.getName(path); + HttpEntity reqEntity = MultipartEntityBuilder.create() + .setCharset(StandardCharsets.UTF_8) + .setMode(HttpMultipartMode.BROWSER_COMPATIBLE) + // 相当于 + .addPart(KEY_FILE, new ByteArrayBody(bytes, fileName)) + .build(); + uploadRequest.setEntity(reqEntity); + + // 发起请求 并返回请求的响应 + CloseableHttpResponse uploadResponse = client.execute(uploadRequest); + FineLoggerFactory.getLogger().info(uploadResponse.toString()); + return uploadResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK; + } + return false; + } + + private boolean login(CloseableHttpClient client) throws IOException { + + String bbsUsername = MarketConfig.getInstance().getBbsUsername(); + String bbsPassword = MarketConfig.getInstance().getBbsPassword(); + List pairs = new ArrayList<>(); + pairs.add(new BasicNameValuePair(KEY_USERNAME, bbsUsername)); + pairs.add(new BasicNameValuePair(KEY_PASSWORD, bbsPassword)); + + HttpPost login = new HttpPost(URL_MARKET_LOGIN); + login.setEntity(new UrlEncodedFormEntity(pairs, StandardCharsets.UTF_8)); + login.addHeader("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36"); + login.addHeader("Connection", "keep-alive"); + CloseableHttpResponse loginResponse = client.execute(login); + FineLoggerFactory.getLogger().info(loginResponse.toString()); + return loginResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK; + } + + private static CloseableHttpClient createClient() throws Exception { + + SSLConnectionSocketFactory connectionFactory = createSSL(); + + BasicCookieStore cookieStore = new BasicCookieStore(); + return HttpClients.custom() + .setDefaultRequestConfig(RequestConfig.custom() + .setCookieSpec(CookieSpecs.STANDARD) + .setSocketTimeout(2000) + .setConnectTimeout(5000) + .setConnectionRequestTimeout(5000) + .setAuthenticationEnabled(false) + .build()) + .setDefaultCookieStore(cookieStore) + .setSSLSocketFactory(connectionFactory) + .build(); + } + + @NotNull + private static SSLConnectionSocketFactory createSSL() throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException { + SSLContext sslContext = SSLContextBuilder + .create() + .loadTrustMaterial(new TrustStrategy() { + @Override + public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { + return true; + } + }) + .build(); + HostnameVerifier allowAllHosts = new NoopHostnameVerifier(); + return new SSLConnectionSocketFactory(sslContext, allowAllHosts); + } + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/group/ui/BaseGroupDialog.java b/designer-form/src/main/java/com/fr/design/mainframe/share/group/ui/BaseGroupDialog.java new file mode 100644 index 000000000..e9d5d490b --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/group/ui/BaseGroupDialog.java @@ -0,0 +1,59 @@ +package com.fr.design.mainframe.share.group.ui; + +import com.fr.base.BaseUtils; +import com.fr.design.dialog.UIDialog; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.i18n.Toolkit; +import com.fr.design.utils.gui.GUICoreUtils; + +import javax.swing.JDialog; +import java.awt.Dimension; +import java.awt.Frame; + +/** + * @Author: Yuan.Wang + * @Date: 2020/12/9 + */ +abstract public class BaseGroupDialog extends UIDialog { + public BaseGroupDialog(Frame parent) { + super(parent); + } + + protected UIButton createConfirmButton() { + UIButton confirmButton; + + confirmButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Confirm")); + confirmButton.setPreferredSize(new Dimension(60, 25)); + confirmButton.setEnabled(false); + confirmButton.addActionListener(e -> confirmClose()); + return confirmButton; + } + + protected UIButton createCancelButton() { + UIButton cancelButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Cancel")); + cancelButton.setPreferredSize(new Dimension(60, 25)); + + cancelButton.addActionListener(e -> dispose()); + return cancelButton; + } + + /** + * 点击确定后的处理方法 + */ + abstract protected void confirmClose(); + + protected void initStyle() { + this.setSize(340, 180); + this.setResizable(false); + this.setAlwaysOnTop(true); + this.setIconImage(BaseUtils.readImage("/com/fr/base/images/oem/logo.png")); + this.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); + GUICoreUtils.centerWindow(this); + this.setVisible(true); + } + + @Override + public void checkValid() throws Exception { + // do nothing + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/group/ui/GroupFileDialog.java b/designer-form/src/main/java/com/fr/design/mainframe/share/group/ui/GroupFileDialog.java new file mode 100644 index 000000000..f4b79944e --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/group/ui/GroupFileDialog.java @@ -0,0 +1,173 @@ +package com.fr.design.mainframe.share.group.ui; + +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.gui.itextfield.UITextField; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.TableLayout; +import com.fr.design.layout.TableLayoutHelper; +import com.fr.stable.StringUtils; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.SwingConstants; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; + +/** + * @Author: Yuan.Wang + * @Date: 2020/10/29 + */ +abstract public class GroupFileDialog extends BaseGroupDialog { + + private UITextField nameField; + + private UILabel warnLabel; + + private final UIButton confirmButton; + + public GroupFileDialog(Frame frame, String title) { + this(frame, title, StringUtils.EMPTY); + + } + + public GroupFileDialog(Frame frame, String title, String defaultName) { + super(frame); + this.setLayout(new BorderLayout()); + this.setModal(true); + + setTitle(title); + // 标签 + UILabel newNameLabel = creteNewNameLabel(); + // 输入框 + createNameField(defaultName); + // 重名提示 + createWarnLabel(); + // 确认按钮 + confirmButton = createConfirmButton(); + // 取消按钮 + UIButton cancelButton = createCancelButton(); + + JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 5)); + topPanel.setBorder(BorderFactory.createEmptyBorder(15, 15, 0, 15)); + topPanel.add(newNameLabel); + topPanel.add(nameField); + + JPanel midPanel = new JPanel(new BorderLayout()); + midPanel.setBorder(BorderFactory.createEmptyBorder(0, 15, 0, 15)); + midPanel.add(warnLabel, BorderLayout.WEST); + + JPanel bottomPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); + bottomPanel.setBorder(BorderFactory.createEmptyBorder(0, 15, 0, 15)); + bottomPanel.add(confirmButton); + bottomPanel.add(cancelButton); + + this.add( + TableLayoutHelper.createTableLayoutPane( + new Component[][]{ + new Component[]{topPanel}, + new Component[]{midPanel}, + new Component[]{bottomPanel} + }, + new double[]{TableLayout.FILL, TableLayout.FILL, TableLayout.FILL}, + new double[]{TableLayout.FILL} + ), BorderLayout.CENTER); + initStyle(); + } + + protected String getFileName() { + return nameField.getText().trim(); + } + + protected void validInput() { + //抽成模板方法 + String userInput = getFileName(); + + if (StringUtils.isEmpty(userInput)) { + confirmButton.setEnabled(false); + return; + } + String name = nameField.getText().trim(); + + if (isDuplicate(name)) { + nameField.selectAll(); + // 如果文件名已存在,则灰掉确认按钮 + warnLabel.setText(Toolkit.i18nText("Fine-Design_Share_Group_Repeat_Name_Info")); + warnLabel.setVisible(true); + confirmButton.setEnabled(false); + } else { + warnLabel.setVisible(false); + confirmButton.setEnabled(true); + } + } + + /** + * 点击确定后的处理方法 + */ + abstract protected void confirmClose(); + + /** + * 是否重名 + */ + abstract protected boolean isDuplicate(String fileName); + + + private UILabel creteNewNameLabel() { + // 输入框前提示 + UILabel newNameLabel = new UILabel(Toolkit.i18nText("Fine-Design_Share_Group_Enter_New_Folder_Name")); + newNameLabel.setHorizontalAlignment(SwingConstants.RIGHT); + newNameLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 10)); + newNameLabel.setPreferredSize(new Dimension(84, 16)); + return newNameLabel; + } + + private void createNameField(String name) { + // 文件名输入框 + nameField = new UITextField(name); + nameField.getDocument().addDocumentListener(new DocumentListener() { + + public void changedUpdate(DocumentEvent e) { + validInput(); + } + + public void insertUpdate(DocumentEvent e) { + validInput(); + } + + public void removeUpdate(DocumentEvent e) { + validInput(); + } + }); + nameField.selectAll(); + nameField.setPreferredSize(new Dimension(200, 20)); + // 增加enter以及esc快捷键的支持 + nameField.addKeyListener(new KeyAdapter() { + @Override + public void keyPressed(KeyEvent e) { + if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { + dispose(); + } else if (e.getKeyCode() == KeyEvent.VK_ENTER) { + if (confirmButton.isEnabled()) { + confirmClose(); + } + } + } + }); + } + + private void createWarnLabel() { + warnLabel = new UILabel(); + warnLabel.setPreferredSize(new Dimension(300, 30)); + warnLabel.setHorizontalAlignment(SwingConstants.LEFT); + warnLabel.setForeground(Color.RED); + warnLabel.setVisible(false); + } +} \ No newline at end of file diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/group/ui/GroupMoveDialog.java b/designer-form/src/main/java/com/fr/design/mainframe/share/group/ui/GroupMoveDialog.java new file mode 100644 index 000000000..c39f195a0 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/group/ui/GroupMoveDialog.java @@ -0,0 +1,79 @@ +package com.fr.design.mainframe.share.group.ui; + +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.icombobox.UIComboBox; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.form.share.group.DefaultShareGroupManager; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.SwingConstants; +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Frame; + +/** + * @Author: Yuan.Wang + * @Date: 2020/12/9 + */ +abstract public class GroupMoveDialog extends BaseGroupDialog { + private UIComboBox selectGroupBox; + + public GroupMoveDialog(Frame frame) { + super(frame); + this.setLayout(new BorderLayout()); + this.setModal(true); + + setTitle(Toolkit.i18nText("Fine-Design_Share_Group_Move")); + // 标签 + UILabel newNameLabel = creteNewNameLabel(); + // 输入框 + createSwitchGroupBox(); + + // 确认按钮 + UIButton confirmButton = createConfirmButton(); + confirmButton.setEnabled(true); + // 取消按钮 + UIButton cancelButton = createCancelButton(); + + JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 5)); + topPanel.setBorder(BorderFactory.createEmptyBorder(15, 15, 0, 15)); + topPanel.add(newNameLabel); + topPanel.add(selectGroupBox); + + JPanel bottomPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); + bottomPanel.setBorder(BorderFactory.createEmptyBorder(0, 15, 0, 15)); + bottomPanel.setPreferredSize(new Dimension(340, 45)); + bottomPanel.add(confirmButton); + bottomPanel.add(cancelButton); + this.add(topPanel, BorderLayout.CENTER); + this.add(bottomPanel, BorderLayout.SOUTH); + + initStyle(); + + + } + + private void createSwitchGroupBox() { + // 文件名输入框 + selectGroupBox = new UIComboBox(DefaultShareGroupManager.getInstance().getAllGroup()); + selectGroupBox.setPreferredSize(new Dimension(225, 20)); + } + + + private UILabel creteNewNameLabel() { + // 输入框前提示 + UILabel newNameLabel = new UILabel(Toolkit.i18nText("Fine-Design_Share_Group_Select")); + newNameLabel.setHorizontalAlignment(SwingConstants.RIGHT); + newNameLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 10)); + newNameLabel.setPreferredSize(new Dimension(60, 16)); + return newNameLabel; + } + + protected UIComboBox getSelectGroupBox() { + return selectGroupBox; + } + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/select/ComponentTransformer.java b/designer-form/src/main/java/com/fr/design/mainframe/share/select/ComponentTransformer.java new file mode 100644 index 000000000..de61f29d2 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/select/ComponentTransformer.java @@ -0,0 +1,25 @@ +package com.fr.design.mainframe.share.select; + +import com.fr.design.designer.creator.XCreator; +import com.fr.design.mainframe.FormSelection; +import com.fr.form.ui.Widget; +import com.fr.third.org.apache.commons.lang3.tuple.Triple; + +import java.awt.Rectangle; + +/** + * 组件选择器 + *

+ * created by Harrison on 2020/06/11 + **/ +public interface ComponentTransformer { + + /** + * 获取选择到组件 + * + * @return 组件相关信息 + */ + Triple transform(FormSelection selection); + +} + diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/select/ComponentTransformerFactory.java b/designer-form/src/main/java/com/fr/design/mainframe/share/select/ComponentTransformerFactory.java new file mode 100644 index 000000000..bf9e6ea61 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/select/ComponentTransformerFactory.java @@ -0,0 +1,53 @@ +package com.fr.design.mainframe.share.select; + +import com.fr.design.designer.creator.XCreator; +import com.fr.design.mainframe.FormSelection; +import com.fr.form.ui.Widget; +import com.fr.stable.AssistUtils; +import com.fr.third.org.apache.commons.lang3.tuple.Triple; +import org.jetbrains.annotations.Nullable; + +import java.awt.Rectangle; + +/** + * created by Harrison on 2020/06/11 + **/ +public class ComponentTransformerFactory { + + private TransformerKey lastKey; + private Triple lastCache; + + private ComponentTransformer transformer = new ComponentTransformerImpl(); + + private static class InstanceHolder { + + private static ComponentTransformerFactory INSTANCE = new ComponentTransformerFactory(); + } + + public static ComponentTransformerFactory getInstance() { + + return InstanceHolder.INSTANCE; + } + + @Nullable + public Triple transform(FormSelection selection) { + + if (selection == null) { + return null; + } + TransformerKey transformerKey = new TransformerKey(selection); + if (AssistUtils.equals(lastKey, transformerKey)) { + return lastCache; + } + Triple triple = transformer.transform(selection); + //缓存一下。 + cache(transformerKey, triple); + return triple; + } + + private void cache(TransformerKey transformerKey, Triple triple) { + + this.lastKey = transformerKey; + this.lastCache = triple; + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/select/ComponentTransformerImpl.java b/designer-form/src/main/java/com/fr/design/mainframe/share/select/ComponentTransformerImpl.java new file mode 100644 index 000000000..af8612608 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/select/ComponentTransformerImpl.java @@ -0,0 +1,156 @@ +package com.fr.design.mainframe.share.select; + +import com.fr.base.FRContext; +import com.fr.design.designer.beans.adapters.component.CompositeComponentAdapter; +import com.fr.design.designer.creator.XCreator; +import com.fr.design.designer.creator.XLayoutContainer; +import com.fr.design.designer.creator.XWAbsoluteLayout; +import com.fr.design.dialog.FineJOptionPane; +import com.fr.design.file.HistoryTemplateListCache; +import com.fr.design.mainframe.FormSelection; +import com.fr.design.mainframe.JTemplate; +import com.fr.design.mainframe.WidgetPropertyPane; +import com.fr.form.main.Form; +import com.fr.form.share.bean.ShareLayoutWidget; +import com.fr.form.ui.AbstractBorderStyleWidget; +import com.fr.form.ui.Widget; +import com.fr.form.ui.container.WAbsoluteBodyLayout; +import com.fr.form.ui.container.WAbsoluteLayout; +import com.fr.form.ui.container.WBorderLayout; +import com.fr.form.ui.container.WFitLayout; +import com.fr.form.ui.container.WLayout; +import com.fr.form.ui.container.WParameterLayout; +import com.fr.form.ui.widget.CRBoundsWidget; +import com.fr.general.Inter; +import com.fr.log.FineLoggerFactory; +import com.fr.third.org.apache.commons.lang3.tuple.ImmutableTriple; +import com.fr.third.org.apache.commons.lang3.tuple.Triple; +import com.fr.web.FormCompVisibleUtils; +import org.jetbrains.annotations.Nullable; + +import java.awt.Dimension; +import java.awt.Rectangle; +import java.awt.Toolkit; +import java.util.Comparator; +import java.util.Map; +import java.util.TreeMap; + +/** + * created by Harrison on 2020/06/11 + **/ +public class ComponentTransformerImpl implements ComponentTransformer { + + @Override + @Nullable + public Triple transform(FormSelection selection) { + + XCreator selectedCreator; + Widget selectedWidget; + if (selection == null) { + return null; + } + Rectangle selectionBounds = selection.getSelctionBounds(); + Rectangle selectedTriple = new Rectangle(0, 0, selectionBounds.width, selectionBounds.height); + XCreator[] xCreators = selection.getSelectedCreators(); + if (xCreators.length == 1) { + selectedCreator = xCreators[0]; + selectedWidget = selectedCreator.toData(); + } else { + + WAbsoluteLayout wAbsoluteLayout = new WAbsoluteLayout("absolute"); + wAbsoluteLayout.setCompState(WAbsoluteLayout.STATE_FIT); + Map widgetMap = new TreeMap<>( + new Comparator() { + @Override + public int compare(Integer o1, Integer o2) { + return o2.compareTo(o1); + } + } + ); + //控件上下层关系需要继承下来 + for (XCreator xCreator : xCreators) { + XLayoutContainer container = (XLayoutContainer) xCreator.getParent(); + int i = container.getComponentZOrder(xCreator); + widgetMap.put(i, xCreator.toData()); + } + JTemplate jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + Form form = (Form) jt.getTarget(); + for (Widget innerWidget : widgetMap.values()) { + WLayout parentWLayout = getParentLayout(form, innerWidget); + if (parentWLayout == null){ + continue; + } + try { + CRBoundsWidget boundsWidget = (CRBoundsWidget) parentWLayout.getBoundsWidget(innerWidget).clone(); + adaptBounds(boundsWidget, selectionBounds); + wAbsoluteLayout.addWidget(boundsWidget); + } catch (CloneNotSupportedException e1) { + FRContext.getLogger().error(e1.getMessage(), e1); + } + } + wAbsoluteLayout.setDesigningResolution(Toolkit.getDefaultToolkit().getScreenSize()); + + selectedCreator = new XWAbsoluteLayout(wAbsoluteLayout, new Dimension(selectedTriple.width, selectedTriple.height)); + selectedWidget = selectedCreator.toData(); + + //将选中的类型初始化一下。 + CompositeComponentAdapter adapter = new CompositeComponentAdapter(WidgetPropertyPane.getInstance().getEditingFormDesigner(), selectedCreator); + adapter.initialize(); + //并且初始化一次。缓存一下值。 + selectedCreator.repaint(); + } + try { + if (!supportShared(selectedWidget)) { + return null; + } + if (!(selectedWidget instanceof AbstractBorderStyleWidget)) { + selectedWidget = new ShareLayoutWidget(selectedWidget); + } + selectedWidget = (Widget) selectedWidget.clone(); + } catch (CloneNotSupportedException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + FineJOptionPane.showMessageDialog(null, Inter.getLocText("Fine-Design_Share_Module_Failed")); + } + return new ImmutableTriple<>(selectedWidget, selectedCreator, selectedTriple); + } + + //先从body中找,如果找不到再从参数面板中找 + @Nullable + private WLayout getParentLayout(Form form, Widget innerWidget) { + WLayout bodyLayout = (WLayout) ((WBorderLayout) form.getContainer()).getLayoutWidget(WBorderLayout.CENTER); + WLayout paraLayout = (WLayout) ((WBorderLayout) form.getContainer()).getLayoutWidget(WBorderLayout.NORTH); + WLayout parentLayout = FormCompVisibleUtils.findFitLayout(bodyLayout, innerWidget); + if (parentLayout == null && paraLayout != null) { + parentLayout = FormCompVisibleUtils.findFitLayout(paraLayout, innerWidget); + } + return parentLayout; + } + + //组件集合产生绝对布局的时候,子组件的bounds需要去掉主框架的xy值,保证边界和绝对布局对齐 + private static void adaptBounds(CRBoundsWidget cRBoundsWidget, Rectangle delRec) { + Rectangle rec = cRBoundsWidget.getBounds(); + int originX = rec.x; + int originY = rec.y; + int delX = delRec.x; + int delY = delRec.y; + cRBoundsWidget.setBounds(new Rectangle(originX - delX, originY - delY, rec.width, rec.height)); + } + + private static boolean supportShared(Widget widget) { + + return notBody(widget) && notForm(widget); + } + + private static boolean notBody(Widget widget) { + return !(widget instanceof WAbsoluteBodyLayout || widget instanceof WFitLayout || widget instanceof WParameterLayout); + } + + private static boolean notForm(Widget widget) { + if (!(widget instanceof WBorderLayout)) { + return true; + } + Widget centerWidget = ((WBorderLayout) widget).getLayoutWidget(WBorderLayout.CENTER); + return notBody(centerWidget); + + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/select/TransformerKey.java b/designer-form/src/main/java/com/fr/design/mainframe/share/select/TransformerKey.java new file mode 100644 index 000000000..221870272 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/select/TransformerKey.java @@ -0,0 +1,112 @@ +package com.fr.design.mainframe.share.select; + +import com.fr.design.designer.creator.XCreator; +import com.fr.design.mainframe.FormSelection; +import com.fr.form.ui.Widget; +import com.fr.general.ComparatorUtils; +import com.fr.log.FineLoggerFactory; +import com.fr.stable.AssistUtils; +import org.jetbrains.annotations.Nullable; + +import java.awt.Rectangle; +import java.util.Arrays; +import java.util.Objects; +import java.util.UUID; + +/** + * created by Harrison on 2020/06/11 + **/ +public class TransformerKey { + + private Rectangle selectionBounds; + + private Widget[] widgets; + + public TransformerKey(FormSelection selection) { + this.selectionBounds = selection.getSelctionBounds(); + this.widgets = deepData(selection.getSelectedCreators()); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + TransformerKey that = (TransformerKey) o; + return Objects.equals(selectionBounds, that.selectionBounds) && + Arrays.equals(widgets, that.widgets); + } + + @Override + public int hashCode() { + int result = Objects.hash(selectionBounds); + result = 31 * result + + Arrays.hashCode(widgets); + return result; + } + + private Widget[] deepData(XCreator[] xCreators) { + if (xCreators == null) { + return new UniqueWidgetWrapper[0]; + } + Widget[] widgets = new Widget[xCreators.length]; + int i = 0; + for (XCreator xCreator : xCreators) { + widgets[i++] = new UniqueWidgetWrapper(cloneWidget(xCreator)); + } + return widgets; + } + + @Nullable + private Widget cloneWidget(XCreator xCreator) { + + try { + return xCreator.toData() != null ? (Widget) xCreator.toData().clone() : null; + } catch (CloneNotSupportedException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + return null; + } + } + + private static class UniqueWidgetWrapper extends Widget { + private String uuid; + private Widget widget; + + public UniqueWidgetWrapper(Widget widget) { + this.widget = widget; + this.uuid = UUID.randomUUID().toString(); + } + + @Override + public String getXType() { + return "UniqueWidgetWrapper"; + } + + @Override + public boolean isEditor() { + return false; + } + + @Override + public String[] supportedEvents() { + return new String[0]; + } + + /** + * hash码 + * + * @return 返回int + */ + @Override + public int hashCode() { + return 31 * super.hashCode() + AssistUtils.hashCode(this.uuid, this.widget); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof UniqueWidgetWrapper + && super.equals(obj) + && ComparatorUtils.equals(((UniqueWidgetWrapper) obj).uuid, this.uuid) + && ComparatorUtils.equals(((UniqueWidgetWrapper) obj).widget, this.widget); + } + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/sort/OnlineWidgetSortType.java b/designer-form/src/main/java/com/fr/design/mainframe/share/sort/OnlineWidgetSortType.java new file mode 100644 index 000000000..437835662 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/sort/OnlineWidgetSortType.java @@ -0,0 +1,153 @@ +package com.fr.design.mainframe.share.sort; + +import com.fr.design.i18n.Toolkit; +import com.fr.form.share.bean.OnlineShareWidget; +import com.fr.form.share.bean.SortParameter; +import com.fr.form.share.utils.ShareUtils; +import com.fr.general.ComparatorUtils; +import com.fr.general.GeneralContext; + +import java.text.Collator; +import java.util.Arrays; +import java.util.Comparator; +import java.util.Date; +import java.util.Map; + + +/** + * Created by kerry on 2020-10-22 + */ +public enum OnlineWidgetSortType implements SortType { + COMPOSITE { + @Override + public void sort(OnlineShareWidget[] widgetProviders) { + Map parameterMap = ShareUtils.getCompositeSortPara(); + Arrays.sort(widgetProviders, new Comparator() { + @Override + public int compare(OnlineShareWidget o1, OnlineShareWidget o2) { + double t1 = getSortValue(o1, parameterMap); + double t2 = getSortValue(o2, parameterMap); + return ComparatorUtils.compareCommonType(t2, t1); + } + }); + } + + private double getSortValue(OnlineShareWidget o, Map parameterMap) { + double a1 = getParaValue("a1", parameterMap), + a2 = getParaValue("a2", parameterMap), + a3 = getParaValue("a3", parameterMap), + b1 = getParaValue("b1", parameterMap), + b2 = getParaValue("b2", parameterMap), + k = getParaValue("k", parameterMap), + q1 = getParaValue("q1", parameterMap), + q2 = getParaValue("q2", parameterMap); + String[] hot2 = new String[]{"report-1", "report-2"}; + String[] hot1 = new String[]{"chart-1", "chart-2", "chart-3", "chart-4", "chart-5", "chart-6"}; + int commentNumber = o.getCommentNumber(), weight = o.getWeight(), downloadTimes = o.getDownloadTimes(); + + double hotValue = a3; + String cid = o.getCid(); + for (String str2 : hot2) { + if (ComparatorUtils.equals(str2, cid)) { + hotValue = a2; + break; + } + } + for (String str1 : hot1) { + if (ComparatorUtils.equals(str1, cid)) { + hotValue = a1; + break; + } + } + + double t = (new Date().getTime() - o.getUploadTime().getTime()) / (3600 * 1000 * 24D); + return q1 * hotValue * Math.pow(2.718, (0 - k) * t) + q2 * (b1 * commentNumber + b2 * downloadTimes) * Math.pow(2.718, (0 - k) * t) + weight; + } + + private double getParaValue(String parameter, Map parameterMap) { + SortParameter sortParameter = parameterMap.get(parameter); + if (sortParameter == null) { + return 0.0D; + } + return sortParameter.getValue(); + } + + + @Override + public String getDisplayName() { + return Toolkit.i18nText("Fine-Design_Share_Composite"); + } + }, + + + SALES { + @Override + public void sort(OnlineShareWidget[] widgetProviders) { + Arrays.sort(widgetProviders, new Comparator() { + @Override + public int compare(OnlineShareWidget o1, OnlineShareWidget o2) { + int t1 = o1.getDownloadTimes(); + int t2 = o2.getDownloadTimes(); + int result = ComparatorUtils.compareCommonType(t2, t1); + if (result == 0) { + result = Collator.getInstance(GeneralContext.getLocale()).compare(o1.getName(), o2.getName()); + } + return result; + } + }); + } + + @Override + public String getDisplayName() { + return Toolkit.i18nText("Fine-Design_Share_Sale"); + } + }, + + NEW_PRODUCT { + @Override + public void sort(OnlineShareWidget[] widgetProviders) { + Arrays.sort(widgetProviders, new Comparator() { + @Override + public int compare(OnlineShareWidget o1, OnlineShareWidget o2) { + long t1 = o1.getUploadTime().getTime(); + long t2 = o2.getUploadTime().getTime(); + int result = ComparatorUtils.compareCommonType(t2, t1); + if (result == 0) { + result = Collator.getInstance(GeneralContext.getLocale()).compare(o1.getName(), o2.getName()); + } + return result; + } + }); + } + + @Override + public String getDisplayName() { + return Toolkit.i18nText("Fine-Design_Share_New_Product"); + } + } + //现在不用,以后可能会用,先注释掉 + /*, + PRICE { + @Override + public void sort(OnlineShareWidget[] widgetProviders) { + Arrays.sort(widgetProviders, new Comparator() { + @Override + public int compare(OnlineShareWidget o1, OnlineShareWidget o2) { + double t1 = o1.getPrice(); + double t2 = o2.getPrice(); + int result = ComparatorUtils.compareCommonType(t2, t1); + if (result == 0) { + result = Collator.getInstance(GeneralContext.getLocale()).compare(o1.getName(), o2.getName()); + } + return result; + } + }); + } + + @Override + public String getDisplayName() { + return Toolkit.i18nText("Fine-Design_Share_Price"); + } + };*/ + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/sort/SortType.java b/designer-form/src/main/java/com/fr/design/mainframe/share/sort/SortType.java new file mode 100644 index 000000000..316bb3c10 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/sort/SortType.java @@ -0,0 +1,12 @@ +package com.fr.design.mainframe.share.sort; + +/** + * @Author: Yuan.Wang + * @Date: 2020/11/19 + */ +public interface SortType { + + void sort(T[] widgetProviders); + + String getDisplayName(); +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/sort/WidgetSortType.java b/designer-form/src/main/java/com/fr/design/mainframe/share/sort/WidgetSortType.java new file mode 100644 index 000000000..a6b8d49b2 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/sort/WidgetSortType.java @@ -0,0 +1,55 @@ +package com.fr.design.mainframe.share.sort; + +import com.fr.design.i18n.Toolkit; +import com.fr.form.share.SharableWidgetProvider; +import com.fr.form.share.record.ShareWidgetInfoManager; +import com.fr.general.ComparatorUtils; +import com.fr.general.GeneralContext; + +import java.text.Collator; +import java.util.Arrays; +import java.util.Comparator; + +/** + * Created by kerry on 2020-07-01 + */ +public enum WidgetSortType implements SortType { + INSTALL_TIME { + @Override + public void sort(SharableWidgetProvider[] widgetProviders) { + Arrays.sort(widgetProviders, new Comparator() { + @Override + public int compare(SharableWidgetProvider o1, SharableWidgetProvider o2) { + long t1 = ShareWidgetInfoManager.getInstance().getCompInstallTime(o1.getName() + "." + o1.getId()); + long t2 = ShareWidgetInfoManager.getInstance().getCompInstallTime(o2.getName() + "." + o2.getId()); + int result = ComparatorUtils.compareCommonType(t2, t1); + if (result == 0) { + result = Collator.getInstance(GeneralContext.getLocale()).compare(o1.getName(), o2.getName()); + } + return result; + } + }); + } + + @Override + public String getDisplayName() { + return Toolkit.i18nText("Fine-Design_Share_Install_Time"); + } + }, + COMPONENT_NAME { + @Override + public void sort(SharableWidgetProvider[] widgetProviders) { + Arrays.sort(widgetProviders, new Comparator() { + @Override + public int compare(SharableWidgetProvider o1, SharableWidgetProvider o2) { + return Collator.getInstance(GeneralContext.getLocale()).compare(o1.getName(), o2.getName()); + } + }); + } + + @Override + public String getDisplayName() { + return Toolkit.i18nText("Fine-Design_Share_Sort_Name"); + } + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/ChartIcon.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/ChartIcon.java new file mode 100644 index 000000000..b52916f9c --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/ChartIcon.java @@ -0,0 +1,91 @@ +package com.fr.design.mainframe.share.ui.base; + +import com.fr.base.chart.BaseChartCollection; +import com.fr.base.chart.BaseChartPainter; +import com.fr.base.chart.chartdata.CallbackEvent; +import com.fr.base.chart.result.WebChartIDInfo; +import com.fr.script.Calculator; + +import javax.swing.Icon; +import java.awt.Color; +import java.awt.Component; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Paint; + +public class ChartIcon implements Icon { + private BaseChartCollection chartCollection; + private CallbackEvent callbackEvent; + + private int width; + private int height; + + /** + * 构造Chart的缩略图Icon + */ + public ChartIcon(BaseChartCollection chartCollection, int width, int height) { + try { + this.chartCollection = (BaseChartCollection) chartCollection.clone(); + } catch (CloneNotSupportedException e) { + this.chartCollection = chartCollection; + } + this.width = width; + this.height = height; + } + + public void registerCallBackEvent(CallbackEvent callbackEvent) { + this.callbackEvent = callbackEvent; + } + + /** + * 画出缩略图Icon + * + * @param g 图形的上下文 + * @param c 所在的Component + * @param x 缩略图的起始坐标x + * @param y 缩略图的起始坐标y + */ + @Override + public void paintIcon(Component c, Graphics g, int x, int y) { + + BaseChartPainter chartPainter = getChartPainter(); + + Graphics2D g2d = (Graphics2D) g; + Paint oldPaint = g2d.getPaint(); + g.translate(x, y); + g2d.setPaint(Color.white); + g2d.fillRect(0, 0, getIconWidth(), getIconHeight()); + + chartPainter.paint(g2d, getIconWidth(), getIconHeight(), 0, null, callbackEvent); + + g.translate(-x, -y); + g2d.setPaint(oldPaint); + } + + protected BaseChartPainter getChartPainter() { + BaseChartPainter painter = chartCollection.createResultChartPainterWithOutDealFormula(Calculator.createCalculator(), + WebChartIDInfo.createEmptyDesignerInfo(), getIconWidth(), getIconHeight()); + return painter; + } + + + /** + * 返回缩略图的宽度 + * + * @return int 缩略图宽度 + */ + @Override + public int getIconWidth() { + return width; + } + + /** + * 返回缩略图的高度 + * + * @return int 缩略图高度 + */ + @Override + public int getIconHeight() { + return height; + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/DictionaryComboCheckBox.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/DictionaryComboCheckBox.java new file mode 100644 index 000000000..2a4fedddb --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/DictionaryComboCheckBox.java @@ -0,0 +1,92 @@ +package com.fr.design.mainframe.share.ui.base; + +import com.fr.design.gui.icombocheckbox.UIComboCheckBox; +import com.fr.design.gui.itextfield.UITextField; +import com.fr.design.i18n.Toolkit; +import com.fr.stable.StringUtils; + +import java.awt.Component; +import java.util.ArrayList; +import java.util.List; + +/** + * created by Harrison on 2020/04/21 + **/ +public class DictionaryComboCheckBox extends UIComboCheckBox { + + private static final String DEFAULT_VALUE_SEPARATOR = ","; + + private static final String EDITOR_FIELD = "editor"; + + private Object[] values; + + private Object[] displays; + + private String locale; + + private UITextField newEditor = null; + + public DictionaryComboCheckBox(Object[] values, String[] displays, String locale) { + super(displays); + init(values, displays); + this.locale = locale; + + installUI(); + } + + private void init(Object[] keys, String[] displays) { + + this.displays = displays; + this.values = keys; + } + + /** + * 这里是有问题的, 这里本身直接获取比较好。 + */ + @Deprecated + private void installUI() { + + Component[] components = getComponents(); + UITextField editor = (UITextField) components[0]; + editor.setPlaceholder(Toolkit.i18nText(locale)); + } + + @Override + public String getText() { + + Object[] selectedValues = getSelectedValues(); + StringBuilder builder = new StringBuilder(); + if (selectedValues != null) { + for (Object value : selectedValues) { + builder.append(value); + builder.append(DEFAULT_VALUE_SEPARATOR); + } + } + //去掉末尾多余的逗号 + return builder.length() > 0 ? builder.substring(0, builder.length() - 1) : StringUtils.EMPTY; + } + + @Override + public Object[] getSelectedValues() { + + Object[] selectedValues = super.getSelectedValues(); + List realValues = new ArrayList<>(); + for (Object selectedValue : selectedValues) { + Object realValue = matchValue(selectedValue); + if (realValue != null) { + realValues.add(realValue); + } + } + return realValues.toArray(); + } + + protected Object matchValue(Object key) { + + for (int i = 0; i < displays.length; i++) { + if (displays[i].equals(key)) { + return values[i]; + } + } + return null; + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/DownloadProgressPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/DownloadProgressPane.java new file mode 100644 index 000000000..c7f09f453 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/DownloadProgressPane.java @@ -0,0 +1,129 @@ +package com.fr.design.mainframe.share.ui.base; + +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.gui.iprogressbar.ModernUIProgressBarUI; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.general.IOUtils; + +import javax.swing.BorderFactory; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JProgressBar; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; + +/** + * @Author: Yuan.Wang + * @Date: 2020/12/24 + * 下载组件包的时候用到的进度条 + */ +public class DownloadProgressPane extends JPanel { + private static final int MAX_NUM = 1000; + + private final UILabel tipLabel; + private final UILabel closeLabel; + private final JProgressBar processBar; + + public DownloadProgressPane(MouseClickListener listener) { + this.setLayout(new BorderLayout()); + this.setBorder(BorderFactory.createEmptyBorder(200, 25, 0, 25)); + + processBar = createProgressBar(); + tipLabel = createTipLabel(); + + JPanel panel = new JPanel(new BorderLayout()); + panel.setOpaque(false); + panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); + panel.setPreferredSize(new Dimension(240, 60)); + panel.add(processBar, BorderLayout.CENTER); + + closeLabel = new UILabel(IOUtils.readIcon("/com/fr/base/images/share/close_small.png")); + closeLabel.addMouseListener(listener); + + JPanel labelPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + labelPane.setOpaque(false); + labelPane.add(tipLabel, BorderLayout.CENTER); + labelPane.add(closeLabel, BorderLayout.EAST); + labelPane.setBorder(BorderFactory.createEmptyBorder(0, 20, 0, 7)); + + UILabel downloadTipLabel = new UILabel(Toolkit.i18nText("Fine-Design_Share_Package_Downloading_Tip")); + downloadTipLabel.setPreferredSize(new Dimension(240, 90)); + downloadTipLabel.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5)); + downloadTipLabel.setForeground(Color.WHITE); + downloadTipLabel.setHorizontalTextPosition(UILabel.CENTER); + + + JPanel centerPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + centerPane.setPreferredSize(new Dimension(240, 138)); + centerPane.add(labelPane, BorderLayout.NORTH); + centerPane.add(panel, BorderLayout.CENTER); + centerPane.add(downloadTipLabel, BorderLayout.SOUTH); + centerPane.setOpaque(false); + + this.add(centerPane, BorderLayout.NORTH); + this.setSize(new Dimension(240, 800)); + this.setBackground(new Color(0, 0, 0, 0)); + this.setOpaque(false); + } + + private UILabel createTipLabel() { + UILabel label = new UILabel(ProcessState.DOWNLOADING.tip); + label.setPreferredSize(new Dimension(200, 20)); + label.setHorizontalAlignment(UILabel.CENTER); + label.setOpaque(false); + label.setForeground(Color.WHITE); + return label; + } + + private JProgressBar createProgressBar() { + JProgressBar jProgressBar = new JProgressBar(); + jProgressBar.setUI(new ModernUIProgressBarUI()); + jProgressBar.setBorderPainted(false); + jProgressBar.setOpaque(false); + jProgressBar.setBorder(null); + jProgressBar.setMaximum(MAX_NUM); + return jProgressBar; + } + + public void changeState() { + tipLabel.setText(ProcessState.INSTALLING.tip); + closeLabel.setVisible(false); + this.validate(); + this.repaint(); + } + + public void updateProgress(double process) { + if (process < 0 || process > 1) { + throw new IllegalArgumentException(); + } + processBar.setValue((int) (process * MAX_NUM)); + } + + + private enum ProcessState { + DOWNLOADING(Toolkit.i18nText("Fine-Design_Share_Package_Downloading")), + INSTALLING(Toolkit.i18nText("Fine-Design_Share_Package_Installing")); + + private final String tip; + + ProcessState(String tip) { + this.tip = tip; + } + } + + public static void main(String[] args) { + JFrame frame = new JFrame(); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setBounds(600, 200, 240, 500); + + DownloadProgressPane pane = new DownloadProgressPane(null); + pane.updateProgress(0.5); + frame.add(pane); + frame.setVisible(true); + + } +} + + diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/FailureMessagePane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/FailureMessagePane.java new file mode 100644 index 000000000..52a57ed4b --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/FailureMessagePane.java @@ -0,0 +1,58 @@ +package com.fr.design.mainframe.share.ui.base; + +import com.fr.design.dialog.BasicPane; +import com.fr.design.gui.frpane.UITextPane; +import com.fr.design.gui.icontainer.UIScrollPane; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.general.IOUtils; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.text.Style; +import javax.swing.text.StyleConstants; +import javax.swing.text.StyleContext; +import java.awt.BorderLayout; +import java.awt.FlowLayout; + +/** + * @Author: Yuan.Wang + * @Date: 2020/9/14 + */ +public class FailureMessagePane extends BasicPane { + public FailureMessagePane(String str) { + UILabel imageLabel = new UILabel(IOUtils.readIcon("/com/fr/base/images/share/error_icon.png")); + UILabel label = new UILabel(Toolkit.i18nText("Fine-Design_Share_Share_Modules_Error")); + UITextPane textPane = new UITextPane(); + UIScrollPane jScrollPane = new UIScrollPane(textPane); + JPanel panel = new JPanel(); + + Style style = new StyleContext().new NamedStyle(); + StyleConstants.setLineSpacing(style, 0.1f); + StyleConstants.setFontSize(style, 12); + textPane.setLogicalStyle(style); + textPane.setText(str); + textPane.setCaretPosition(0); + textPane.setEditable(false); + textPane.setBorder(BorderFactory.createEmptyBorder(3, 5, 3, 5)); + + jScrollPane.setBorder(BorderFactory.createEmptyBorder()); + label.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0)); + + setLayout(new BorderLayout()); + setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 8)); + + panel.add(imageLabel); + panel.add(label); + panel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0)); + panel.setBorder(BorderFactory.createEmptyBorder(4, 0, 4, 0)); + add(panel, BorderLayout.NORTH); + add(jScrollPane, BorderLayout.CENTER); + } + + @Override + protected String title4PopupWindow() { + return Toolkit.i18nText("Fine-Design_Share_Dialog_Message"); + } + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/FlexSearchFieldPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/FlexSearchFieldPane.java new file mode 100644 index 000000000..91b2ce358 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/FlexSearchFieldPane.java @@ -0,0 +1,172 @@ +package com.fr.design.mainframe.share.ui.base; + +import com.fr.base.BaseUtils; +import com.fr.design.event.ChangeEvent; +import com.fr.design.event.ChangeListener; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.gui.itextfield.UITextField; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.general.IOUtils; +import com.fr.stable.StringUtils; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import java.awt.BorderLayout; +import java.awt.CardLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.util.ArrayList; +import java.util.List; + +/** + * Created by kerry on 2020-10-19 + */ +public class FlexSearchFieldPane extends JPanel { + private static final String SEARCH = "SEARCH"; + private static final String OTHER = "OTHER"; + + private static final Color SEARCH_BORDER_COLOR = Color.decode("#F5F5F7"); + private static final Color SEARCH_BORDER_INPUT_COLOR = Color.decode("#419BF9"); + private UITextField searchTextField; + private CardLayout cardLayout; + private JPanel centerPane; + private List changeListenerList = new ArrayList<>(); + private List focusListeners = new ArrayList<>(); + private List deleteIconMouseListener = new ArrayList<>(); + private List fieldDocumentListener = new ArrayList<>(); + + public FlexSearchFieldPane(JPanel otherPane) { + JPanel searchFieldPane = createSearchField(); + JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + jPanel.add(otherPane, BorderLayout.CENTER); + jPanel.add(createSearchLabel(), BorderLayout.EAST); + cardLayout = new CardLayout(); + centerPane = new JPanel(cardLayout); + centerPane.add(searchFieldPane, SEARCH); + centerPane.add(jPanel, OTHER); + cardLayout.show(centerPane, OTHER); + this.add(centerPane, BorderLayout.CENTER); + } + + + private JPanel createSearchLabel() { + JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + UILabel label = new UILabel(IOUtils.readIcon("/com/fr/base/images/share/search_icon.png")); + label.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); + jPanel.add(label, BorderLayout.EAST); + label.addMouseListener(new MouseClickListener() { + @Override + public void mouseClicked(MouseEvent e) { + cardLayout.show(centerPane, SEARCH); + searchTextField.requestFocus(); + } + }); + return jPanel; + } + + private JPanel createSearchField() { + final JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + jPanel.setPreferredSize(new Dimension(228, 20)); + jPanel.setBorder(BorderFactory.createLineBorder(SEARCH_BORDER_COLOR)); + jPanel.setBackground(Color.WHITE); + UILabel label = new UILabel(IOUtils.readIcon("/com/fr/base/images/share/search_icon.png")); + label.setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 0)); + jPanel.add(label, BorderLayout.WEST); + this.searchTextField = new UITextField(); + this.searchTextField.setBorderPainted(false); + this.searchTextField.setPlaceholder(Toolkit.i18nText("Fine-Design_Basic_Plugin_Search")); + this.searchTextField.addFocusListener(new FocusListener() { + @Override + public void focusGained(FocusEvent e) { + jPanel.setBorder(BorderFactory.createLineBorder(SEARCH_BORDER_INPUT_COLOR)); + jPanel.repaint(); + for (FocusListener focusListener : focusListeners) { + focusListener.focusGained(e); + } + } + + @Override + public void focusLost(FocusEvent e) { + jPanel.setBorder(BorderFactory.createLineBorder(SEARCH_BORDER_COLOR)); + jPanel.repaint(); + for (FocusListener focusListener : focusListeners) { + focusListener.focusLost(e); + } + } + }); + this.searchTextField.getDocument().addDocumentListener(new DocumentListener() { + @Override + public void insertUpdate(DocumentEvent e) { + filterByName(); + for (DocumentListener listener : fieldDocumentListener) { + listener.insertUpdate(e); + } + } + + @Override + public void removeUpdate(DocumentEvent e) { + filterByName(); + for (DocumentListener listener : fieldDocumentListener) { + listener.removeUpdate(e); + } + } + + @Override + public void changedUpdate(DocumentEvent e) { + filterByName(); + for (DocumentListener listener : fieldDocumentListener) { + listener.changedUpdate(e); + } + } + }); + jPanel.add(this.searchTextField, BorderLayout.CENTER); + UILabel xLabel = new UILabel(BaseUtils.readIcon("/com/fr/design/images/buttonicon/close_icon.png")); + xLabel.addMouseListener(new MouseClickListener() { + @Override + public void mouseClicked(MouseEvent e) { + searchTextField.setText(StringUtils.EMPTY); + cardLayout.show(centerPane, OTHER); + for (MouseListener listener : deleteIconMouseListener) { + listener.mouseClicked(e); + } + } + }); + xLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); + jPanel.add(xLabel, BorderLayout.EAST); + + + return jPanel; + } + + private void filterByName() { + String text = searchTextField.getText(); + for (ChangeListener listener : changeListenerList) { + listener.fireChanged(new ChangeEvent(text)); + } + } + + public void registerChangeListener(ChangeListener changeListener) { + changeListenerList.add(changeListener); + } + + public void registerSearchTextFieldFocusListener(FocusListener focusListener) { + focusListeners.add(focusListener); + } + + public void registerDeleteIconMouseListener(MouseListener mouseListener) { + deleteIconMouseListener.add(mouseListener); + } + + public void registerFieldDocumentListener(DocumentListener documentListener) { + fieldDocumentListener.add(documentListener); + } + + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/ImageBackgroundPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/ImageBackgroundPane.java new file mode 100644 index 000000000..073dee103 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/ImageBackgroundPane.java @@ -0,0 +1,226 @@ +package com.fr.design.mainframe.share.ui.base; + +import com.fr.base.Style; +import com.fr.base.background.ImageBackground; +import com.fr.base.background.ImageFileBackground; +import com.fr.design.gui.frpane.ImgChooseWrapper; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.ibutton.UIRadioButton; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.style.background.BackgroundDetailPane; +import com.fr.design.style.background.image.ImageFileChooser; +import com.fr.design.style.background.image.ImagePreviewPane; +import com.fr.general.Background; +import com.fr.stable.Constants; + +import javax.swing.BorderFactory; +import javax.swing.ButtonGroup; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import java.awt.BorderLayout; +import java.awt.GridLayout; +import java.awt.Image; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/** + * Image background pane. + */ +public class ImageBackgroundPane extends BackgroundDetailPane { + + protected ImagePreviewPane previewPane = null; + private Style imageStyle = null; + private ChangeListener changeListener = null; + private ImageFileChooser imageFileChooser = null; + protected UILabel imageSizeLabel = new UILabel(); + + protected UIRadioButton defaultRadioButton = null; + protected UIRadioButton tiledRadioButton = null; + private UIRadioButton extendRadioButton = null; + private UIRadioButton adjustRadioButton = null; + + public ImageBackgroundPane() { + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + + // preview pane + JPanel previewContainerPane = FRGUIPaneFactory.createBorderLayout_L_Pane(); + this.add(previewContainerPane, BorderLayout.CENTER); + + JPanel previewOwnerPane = FRGUIPaneFactory.createTitledBorderPane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Preview")); + previewOwnerPane.setLayout(new BorderLayout()); + previewContainerPane.add(previewOwnerPane, BorderLayout.CENTER); + previewContainerPane.add(initSelectFilePane(), BorderLayout.EAST); + previewPane = new ImagePreviewPane(); + previewOwnerPane.add(new JScrollPane(previewPane)); + previewPane.addChangeListener(imageSizeChangeListener); + + + // init image file chooser. + imageFileChooser = new ImageFileChooser(); + imageFileChooser.setMultiSelectionEnabled(false); + } + + public JPanel initSelectFilePane() { + JPanel selectFilePane = FRGUIPaneFactory.createBorderLayout_L_Pane(); + + selectFilePane.setBorder(BorderFactory.createEmptyBorder(8, 2, 4, 0)); + + UIButton selectPictureButton = new UIButton( + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Background_Image_Select")); + selectFilePane.add(selectPictureButton, BorderLayout.NORTH); + selectPictureButton.setMnemonic('S'); + selectPictureButton.addActionListener(selectPictureActionListener); + JPanel layoutPane = FRGUIPaneFactory.createMediumHGapHighTopFlowInnerContainer_M_Pane(); + selectFilePane.add(layoutPane, BorderLayout.CENTER); + + //布局 + defaultRadioButton = new UIRadioButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Layout_Default")); + tiledRadioButton = new UIRadioButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Layout_Image_Titled")); + extendRadioButton = new UIRadioButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Layout_Image_Extend")); + adjustRadioButton = new UIRadioButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Layout_Image_Adjust")); + + defaultRadioButton.addActionListener(layoutActionListener); + tiledRadioButton.addActionListener(layoutActionListener); + extendRadioButton.addActionListener(layoutActionListener); + adjustRadioButton.addActionListener(layoutActionListener); + + JPanel jp = new JPanel(new GridLayout(4, 1, 15, 15)); + for (UIRadioButton button : imageLayoutButtons()) { + jp.add(button); + } + layoutPane.add(jp); + + ButtonGroup layoutBG = new ButtonGroup(); + layoutBG.add(defaultRadioButton); + layoutBG.add(tiledRadioButton); + layoutBG.add(extendRadioButton); + layoutBG.add(adjustRadioButton); + + defaultRadioButton.setSelected(true); + return selectFilePane; + } + + protected UIRadioButton[] imageLayoutButtons() { + return new UIRadioButton[]{ + defaultRadioButton, + tiledRadioButton, + extendRadioButton, + adjustRadioButton + }; + } + + /** + * Select picture. + */ + ActionListener selectPictureActionListener = new ActionListener() { + + public void actionPerformed(ActionEvent evt) { + int returnVal = imageFileChooser.showOpenDialog(ImageBackgroundPane.this); + setImageStyle(); + ImgChooseWrapper.getInstance(previewPane, imageFileChooser, imageStyle, changeListener).dealWithImageFile(returnVal); + } + }; + + protected void setImageStyle() { + if (tiledRadioButton.isSelected()) { + imageStyle = Style.DEFAULT_STYLE.deriveImageLayout(Constants.IMAGE_TILED); + } else if (adjustRadioButton.isSelected()) { + imageStyle = Style.DEFAULT_STYLE.deriveImageLayout(Constants.IMAGE_ADJUST); + } else if (extendRadioButton.isSelected()) { + imageStyle = Style.DEFAULT_STYLE.deriveImageLayout(Constants.IMAGE_EXTEND); + } else { + imageStyle = Style.DEFAULT_STYLE.deriveImageLayout(Constants.IMAGE_CENTER); + } + } + + ActionListener layoutActionListener = new ActionListener() { + + @Override + public void actionPerformed(ActionEvent evt) { + setImageStyle(); + changeImageStyle(); + } + + private void changeImageStyle() { + previewPane.setImageStyle(ImageBackgroundPane.this.imageStyle); + previewPane.repaint(); + } + }; + + @Override + public void populate(Background background) { + + if (background instanceof ImageBackground) { + ImageBackground imageBackground = (ImageBackground) background; + + if (imageBackground.getLayout() == Constants.IMAGE_CENTER) { + defaultRadioButton.setSelected(true); + imageStyle = Style.DEFAULT_STYLE.deriveImageLayout(Constants.IMAGE_CENTER); + } else if (imageBackground.getLayout() == Constants.IMAGE_EXTEND) { + extendRadioButton.setSelected(true); + imageStyle = Style.DEFAULT_STYLE.deriveImageLayout(Constants.IMAGE_EXTEND); + } else if (imageBackground.getLayout() == Constants.IMAGE_ADJUST) { + adjustRadioButton.setSelected(true); + imageStyle = Style.DEFAULT_STYLE.deriveImageLayout(Constants.IMAGE_ADJUST); + } else { + tiledRadioButton.setSelected(true); + imageStyle = Style.DEFAULT_STYLE.deriveImageLayout(Constants.IMAGE_TILED); + } + + previewPane.setImageStyle(ImageBackgroundPane.this.imageStyle); + if (imageBackground.getImage() != null) { + previewPane.setImageWithSuffix(imageBackground.getImageWithSuffix()); + imageSizeLabel.setText(previewPane.getImage().getWidth(null) + + " X " + previewPane.getImage().getHeight(null)); + } + + if (imageBackground.getImage() != null) { + previewPane.setImage(imageBackground.getImage()); + } + } else { + previewPane.setImage(null); + tiledRadioButton.setSelected(true); + + imageSizeLabel.setText(""); + } + + fireChagneListener(); + } + + @Override + public Background update() throws Exception { + ImageBackground imageBackground = new ImageFileBackground(previewPane.getImageWithSuffix()); + setImageStyle(); + imageBackground.setLayout(imageStyle.getImageLayout()); + return imageBackground; + } + + @Override + public void addChangeListener(ChangeListener changeListener) { + this.changeListener = changeListener; + } + + private void fireChagneListener() { + if (this.changeListener != null) { + ChangeEvent evt = new ChangeEvent(this); + this.changeListener.stateChanged(evt); + } + } + + ChangeListener imageSizeChangeListener = new ChangeListener() { + + @Override + public void stateChanged(ChangeEvent evt) { + Image image = ((ImagePreviewPane) evt.getSource()).getImage(); + + if (image == null) { + imageSizeLabel.setText(""); + } else { + imageSizeLabel.setText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Size_Detail", image.getWidth(null) + "x" + image.getHeight(null))); + } + } + }; +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/ImagePanel.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/ImagePanel.java new file mode 100644 index 000000000..a9bc8b787 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/ImagePanel.java @@ -0,0 +1,28 @@ +package com.fr.design.mainframe.share.ui.base; + +import javax.swing.JPanel; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.Toolkit; + +/** + * Created by kerry on 2020-10-23 + */ +public class ImagePanel extends JPanel { + + + private Image image; + + public ImagePanel(String imagePath) { + image = Toolkit.getDefaultToolkit().createImage(ImagePanel.class + .getResource(imagePath)); + } + + @Override + public void paintComponent(Graphics g) { + super.paintComponent(g); + if (image != null) { + g.drawImage(image, 0, 0, 45, 45, this); + } + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/ImitationProgress.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/ImitationProgress.java new file mode 100644 index 000000000..062ca9293 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/ImitationProgress.java @@ -0,0 +1,129 @@ +package com.fr.design.mainframe.share.ui.base; + + +import java.util.concurrent.atomic.AtomicReference; + +/** + * @Author: Yuan.Wang + * @Date: 2020/12/23 + */ +public class ImitationProgress { + private final com.fr.design.extra.Process process; + private static final double TOTAL_NUM = 1000; + private static final double FIRST_STAGE_RATE = 0.8; + private static final int SLEEP_TIME = 600; + + private final AtomicReference state = new AtomicReference<>(ImitationState.NEW); + + private final int num; + private final double initSpeed; + private int currentProgressRate = 0; + + public ImitationProgress(com.fr.design.extra.Process process, int num) { + this.process = process; + this.num = num; + initSpeed = TOTAL_NUM * FIRST_STAGE_RATE / num; + } + + public void start() { + if (!state.compareAndSet(ImitationState.NEW, ImitationState.FIRST_STAGE)) { + return; + } + firstState(); + if (state.compareAndSet(ImitationState.FIRST_STAGE, ImitationState.SECOND_STATE)) { + secondState(); + } + if (state.get() == ImitationState.COMPLETE) { + thirdState(); + } + } + + /** + * 按照预先估计的速度跑完80% + */ + private void firstState() { + int i = 0; + for (; i < num; i++) { + try { + Thread.sleep(SLEEP_TIME); + currentProgressRate += initSpeed; + process.process(currentProgressRate / TOTAL_NUM); + if (state.get() != ImitationState.FIRST_STAGE) { + return; + } + } catch (InterruptedException ignore) { + } + } + } + + /** + * 第一阶段结束但是还没有下载完,则减慢速度跑第二阶段 + */ + private void secondState() { + double speed = TOTAL_NUM * 0.1 / 30; + //70%-90%,30s + int i = 0; + for (; i < 30; i++) { + try { + Thread.sleep(1000); + currentProgressRate += speed; + process.process(currentProgressRate / (TOTAL_NUM)); + if (state.get() != ImitationState.SECOND_STATE) { + return; + } + } catch (InterruptedException ignore) { + return; + } + } + //90%-95%,三分钟 + speed = TOTAL_NUM * 0.05 / 60; + for (i = 0; i < 60; i++) { + try { + Thread.sleep(3000); + currentProgressRate += speed; + process.process(currentProgressRate / (TOTAL_NUM)); + } catch (InterruptedException ignore) { + return; + } + } + //线程睡眠1h + try { + Thread.sleep(1000 * 3600); + } catch (InterruptedException ignore) { + } + } + + + /** + * 下载完,则跑第三阶段,即1s内跑完剩下所有进度 + */ + private void thirdState() { + int localSpeed = (int) (TOTAL_NUM - currentProgressRate) / 10; + for (int i = 0; i < 10; i++) { + try { + Thread.sleep(100); + currentProgressRate += localSpeed; + process.process((currentProgressRate) / TOTAL_NUM); + } catch (InterruptedException ignore) { + return; + } + } + + } + + public void completed() { + state.set(ImitationState.COMPLETE); + } + + public void stop() { + state.set(ImitationState.STOP); + } + + private enum ImitationState { + NEW, + FIRST_STAGE, + SECOND_STATE, + COMPLETE, + STOP + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/LeftWordsTextArea.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/LeftWordsTextArea.java new file mode 100644 index 000000000..df9dd8aac --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/LeftWordsTextArea.java @@ -0,0 +1,44 @@ +package com.fr.design.mainframe.share.ui.base; + +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.RenderingHints; + +/** + * created by Harrison on 2020/04/21 + **/ +public class LeftWordsTextArea extends PlaceholderTextArea { + + /** + * 默认值 200 + */ + private int limitedLen = 200; + + public LeftWordsTextArea() { + } + + public LeftWordsTextArea(String s, String placeholder) { + super(s, placeholder); + } + + public void setLimitedLen(int len) { + this.limitedLen = len; + } + + @Override + protected void paintComponent(Graphics pG) { + super.paintComponent(pG); + + char[] text = getText().toCharArray(); + int currentLen = text.length; + int leftLen = limitedLen - currentLen; + String leftWordsLen = String.valueOf(leftLen); + + final Graphics2D g = (Graphics2D) pG; + g.setRenderingHint( + RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + g.setColor(getDisabledTextColor()); + g.drawString(leftWordsLen, getWidth() - getInsets().right - leftWordsLen.length() * 8 - 5, getHeight() - getInsets().bottom - 5); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/LoadingPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/LoadingPane.java new file mode 100644 index 000000000..ee0f37774 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/LoadingPane.java @@ -0,0 +1,49 @@ +package com.fr.design.mainframe.share.ui.base; + +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.SwingConstants; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; + +/** + * Created by kerry on 2020-10-23 + */ +public class LoadingPane extends JPanel { + + public LoadingPane() { + this(Toolkit.i18nText("Fine-Design_Share_Online_Loading")); + } + + public LoadingPane(String message) { + JPanel panel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + JPanel borderPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + borderPane.setPreferredSize(new Dimension(120, 120)); + ImagePanel imagePanel = new ImagePanel("/com/fr/base/images/share/loading.gif"); + imagePanel.setPreferredSize(new Dimension(45, 45)); + borderPane.setBorder(BorderFactory.createEmptyBorder(150, 95, 5, 75)); + borderPane.add(imagePanel); + + panel.add(borderPane, BorderLayout.CENTER); + + JPanel labelPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + UILabel topLabel = new UILabel(Toolkit.i18nText(message), SwingConstants.CENTER); + topLabel.setForeground(Color.GRAY); + labelPanel.add(topLabel, BorderLayout.CENTER); + labelPanel.setPreferredSize(new Dimension(240, 20)); + panel.add(labelPanel, BorderLayout.SOUTH); + + panel.setPreferredSize(new Dimension(240, 230)); + + + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + this.setBorder(BorderFactory.createEmptyBorder(100, 0, 0, 0)); + this.add(panel, BorderLayout.NORTH); + } + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/MouseClickListener.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/MouseClickListener.java new file mode 100644 index 000000000..ae5247d21 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/MouseClickListener.java @@ -0,0 +1,34 @@ +package com.fr.design.mainframe.share.ui.base; + +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; + +/** + * Created by kerry on 2020-10-22 + */ +public abstract class MouseClickListener implements MouseListener { + @Override + public void mouseClicked(MouseEvent e) { + + } + + @Override + public void mousePressed(MouseEvent e) { + + } + + @Override + public void mouseReleased(MouseEvent e) { + + } + + @Override + public void mouseEntered(MouseEvent e) { + + } + + @Override + public void mouseExited(MouseEvent e) { + + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/NoMatchPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/NoMatchPane.java new file mode 100644 index 000000000..856bfd299 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/NoMatchPane.java @@ -0,0 +1,41 @@ +package com.fr.design.mainframe.share.ui.base; + +import com.fr.base.BaseUtils; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.layout.FRGUIPaneFactory; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.SwingConstants; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.FlowLayout; + +/** + * @Author: Yuan.Wang + * @Date: 2021/1/14 + */ +public class NoMatchPane extends JPanel { + public NoMatchPane() { + init(); + } + + private void init() { + JPanel panel = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, FlowLayout.LEADING, 0, 5); + UILabel picLabel = new UILabel(); + picLabel.setIcon(BaseUtils.readIcon("com/fr/base/images/share/no_match_icon.png")); + picLabel.setHorizontalAlignment(SwingConstants.CENTER); + picLabel.setPreferredSize(new Dimension(240, 100)); + UILabel label = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Share_No_Match_Result"), SwingConstants.CENTER); + label.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0)); + label.setForeground(Color.gray); + label.setPreferredSize(new Dimension(240, 20)); + label.setHorizontalAlignment(SwingConstants.CENTER); + panel.add(picLabel); + panel.add(label); + panel.setBorder(BorderFactory.createEmptyBorder(250, 0, 0, 0)); + this.setLayout(new BorderLayout()); + this.add(panel, BorderLayout.CENTER); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/PageableButton.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/PageableButton.java new file mode 100644 index 000000000..781797e07 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/PageableButton.java @@ -0,0 +1,128 @@ +package com.fr.design.mainframe.share.ui.base; + +import javax.swing.SwingConstants; +import javax.swing.plaf.ColorUIResource; +import javax.swing.plaf.basic.BasicArrowButton; +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Shape; +import java.awt.geom.Path2D; +import java.awt.geom.RoundRectangle2D; + +public class PageableButton extends BasicArrowButton { + + static final private Color BORDER_COLOR = new ColorUIResource(198, 198, 198); + static final private Color ARROW_DISABLED_COLOR = new ColorUIResource(193, 193, 193); + static final private Color ARROW_COLOR = new ColorUIResource(112, 112, 112); + static final private Color BUTTON_COLOR = new ColorUIResource(255, 255, 255); + static final private Color BUTTON_DISABLED_COLOR = new ColorUIResource(242, 242, 242); + static final private Color BUTTON_PRESS_COLOR = new ColorUIResource(96, 189, 246); + static final private Color BUTTON_ROLLOVER_COLOR = new ColorUIResource(0xd2d2d2); + static final private int CONNER = 2; + + + public PageableButton(int direction) { + super(direction); + } + + public void paint(Graphics g) { + paintButton(g); + paintArrow(g); + paintButtonBorder(g); + } + + private void paintButton(Graphics g) { + + int width = this.getWidth(); + int height = this.getHeight(); + if (!isEnabled()) { + g.setColor(PageableButton.BUTTON_DISABLED_COLOR); + } else if (getModel().isPressed()) { + g.setColor(PageableButton.BUTTON_PRESS_COLOR); + } else if (getModel().isRollover()){ + g.setColor(PageableButton.BUTTON_ROLLOVER_COLOR); + } else { + g.setColor(PageableButton.BUTTON_COLOR); + } + + g.fillRoundRect(1, 1, width -2, height - 2, PageableButton.CONNER, PageableButton.CONNER); + } + + private void paintArrow(Graphics g) { + if (!this.isEnabled()) { + g.setColor(PageableButton.ARROW_DISABLED_COLOR); + } else { + g.setColor(PageableButton.ARROW_COLOR); + } + switch (direction) { + case SwingConstants.NORTH: + g.drawLine(8, 5, 8, 5); + g.drawLine(7, 6, 9, 6); + g.drawLine(6, 7, 10, 7); + g.drawLine(5, 8, 7, 8); + g.drawLine(9, 8, 11, 8); + g.drawLine(4, 9, 6, 9); + g.drawLine(10, 9, 12, 9); + g.drawLine(5, 10, 5, 10); + g.drawLine(11, 10, 11, 10); + break; + case SwingConstants.SOUTH: + g.drawLine(5, 6, 5, 6); + g.drawLine(11, 6, 11, 6); + g.drawLine(4, 7, 6, 7); + g.drawLine(10, 7, 12, 7); + g.drawLine(5, 8, 7, 8); + g.drawLine(9, 8, 11, 8); + g.drawLine(6, 9, 10, 9); + g.drawLine(7, 10, 9, 10); + g.drawLine(8, 11, 8, 11); + break; + case SwingConstants.EAST: + g.drawLine(6, 5, 6, 5); + g.drawLine(6, 11, 6, 11); + g.drawLine(7, 4, 7, 6); + g.drawLine(7, 10, 7, 12); + g.drawLine(8, 5, 8, 7); + g.drawLine(8, 9, 8, 11); + g.drawLine(9, 6, 9, 10); + g.drawLine(10, 7, 10, 9); + g.drawLine(11, 8, 11, 8); + break; + case SwingConstants.WEST: + g.drawLine(4, 8, 4, 8); + g.drawLine(5, 7, 5, 9); + g.drawLine(6, 6, 6, 10); + g.drawLine(7, 5, 7, 7); + g.drawLine(7, 9, 7, 11); + g.drawLine(8, 4, 8, 6); + g.drawLine(8, 10, 8, 12); + g.drawLine(9, 5, 9, 5); + g.drawLine(9, 11, 9, 11); + break; + } + } + + private void paintButtonBorder(Graphics g) { + int offs = 1; + int width = this.getWidth(); + int height = this.getHeight(); + + Graphics2D g2d = (Graphics2D) g; + Color oldColor = g2d.getColor(); + g2d.setColor(PageableButton.BORDER_COLOR); + + Shape outer; + Shape inner; + int size = offs + offs; + + outer = new RoundRectangle2D.Float(0, 0, width, height, offs, offs); + inner = new RoundRectangle2D.Float(offs, offs, width - size, height - size, PageableButton.CONNER, PageableButton.CONNER); + + Path2D path = new Path2D.Float(Path2D.WIND_EVEN_ODD); + path.append(outer, false); + path.append(inner, false); + g2d.fill(path); + g2d.setColor(oldColor); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/PagingFiledPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/PagingFiledPane.java new file mode 100644 index 000000000..b5cfcd53a --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/PagingFiledPane.java @@ -0,0 +1,213 @@ +package com.fr.design.mainframe.share.ui.base; + +import com.fr.base.BaseUtils; +import com.fr.design.event.ChangeEvent; +import com.fr.design.event.ChangeListener; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.gui.itextfield.UINumberField; +import com.fr.stable.ArrayUtils; + +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JSeparator; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Insets; +import java.awt.Toolkit; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; + +/** + * Created by kerry on 2020-10-20 + */ +public class PagingFiledPane extends JPanel { + private static final Dimension PAGING_BTN_SIZE = new Dimension(20, 20); + private int currentPageNum = 1; + private int totalPageNum; + private int numPerPage; + + private ChangeListener changeListener; + + private UIButton lastPageBtn; + private UIButton nextPageBtn; + private UINumberField pagingEditField; + + public PagingFiledPane(int totalItems, int numPerPage) { + this.setOpaque(false); + this.numPerPage = numPerPage; + this.totalPageNum = totalItems / numPerPage + ((totalItems % numPerPage) == 0 ? 0 : 1); + this.totalPageNum = this.totalPageNum > 0 ? this.totalPageNum : 1; + initPane(totalPageNum); + } + + private void initPane(int totalPageNum) { + + this.setLayout(new FlowLayout(FlowLayout.RIGHT, 5, 15)); + initLastPageBtn(); + + JSeparator jSeparator1 = new JSeparator(); + + pagingEditField = new UINumberField(); + registerPagingEditFieldListener(); + pagingEditField.canFillNegativeNumber(false); + pagingEditField.setMinValue(1); + pagingEditField.setMaxValue(totalPageNum); + pagingEditField.setPreferredSize(new Dimension(50, 20)); + + UILabel totalPageLabel = new UILabel("/" + totalPageNum); + + JSeparator jSeparator2 = new JSeparator(); + + initNextPageBtn(); + + checkPageStatus(); + + this.add(lastPageBtn); + this.add(jSeparator1); + this.add(pagingEditField); + this.add(totalPageLabel); + this.add(jSeparator2); + this.add(nextPageBtn); + } + + public void setEnable(boolean enable) { + lastPageBtn.setEnabled(enable); + nextPageBtn.setEnabled(enable); + pagingEditField.setEnabled(enable); + } + + private void initLastPageBtn() { + lastPageBtn = new UIButton(BaseUtils.readIcon("/com/fr/base/images/share/left_page_normal.png")); + lastPageBtn.setRolloverEnabled(true); + lastPageBtn.setFocusPainted(false); + lastPageBtn.setContentAreaFilled(true); + lastPageBtn.setMargin(new Insets(0, 0, 0, 0)); + lastPageBtn.setPressedIcon(BaseUtils.readIcon("/com/fr/base/images/share/left_page_click.png")); + lastPageBtn.setRolloverIcon(BaseUtils.readIcon("/com/fr/base/images/share/left_page_hover.png")); + lastPageBtn.setDisabledIcon(BaseUtils.readIcon("/com/fr/base/images/share/left_page_disable.png")); + lastPageBtn.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + clickLastPage(); + } + }); + lastPageBtn.setPreferredSize(PAGING_BTN_SIZE); + + } + + private void initNextPageBtn() { + nextPageBtn = new UIButton(BaseUtils.readIcon("/com/fr/base/images/share/right_page_normal.png")); + nextPageBtn.setRolloverEnabled(true); + nextPageBtn.setFocusPainted(false); + nextPageBtn.setContentAreaFilled(true); + nextPageBtn.setMargin(new Insets(0, 0, 0, 0)); + nextPageBtn.setPressedIcon(BaseUtils.readIcon("/com/fr/base/images/share/right_page_click.png")); + nextPageBtn.setRolloverIcon(BaseUtils.readIcon("/com/fr/base/images/share/right_page_hover.png")); + nextPageBtn.setDisabledIcon(BaseUtils.readIcon("/com/fr/base/images/share/right_page_disable.png")); + nextPageBtn.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + clickNextPage(); + } + }); + nextPageBtn.setPreferredSize(PAGING_BTN_SIZE); + + } + + private void registerPagingEditFieldListener() { + pagingEditField.addKeyListener(new KeyListener() { + @Override + public void keyTyped(KeyEvent e) { + + } + + @Override + public void keyPressed(KeyEvent e) { + + } + + @Override + public void keyReleased(KeyEvent evt) { + int code = evt.getKeyCode(); + if (code == KeyEvent.VK_ENTER) { + jumpPage((int) pagingEditField.getValue()); + } + } + }); + pagingEditField.addFocusListener(new FocusListener() { + @Override + public void focusGained(FocusEvent e) { + + } + + @Override + public void focusLost(FocusEvent e) { + jumpPage((int) pagingEditField.getValue()); + } + }); + } + + public int getCurrentPageNum() { + return currentPageNum; + } + + public void registerChangeListener(ChangeListener changeListener) { + this.changeListener = changeListener; + } + + private void checkPageStatus() { + lastPageBtn.setEnabled(currentPageNum > 1); + nextPageBtn.setEnabled(currentPageNum < totalPageNum); + pagingEditField.setText(String.valueOf(currentPageNum)); + if (changeListener != null) { + changeListener.fireChanged(new ChangeEvent(currentPageNum)); + } + } + + private void clickNextPage() { + if (currentPageNum < totalPageNum) { + currentPageNum++; + checkPageStatus(); + } + } + + private void clickLastPage() { + if (currentPageNum > 1) { + currentPageNum--; + checkPageStatus(); + } + } + + private void jumpPage(int pageNum) { + if (pageNum > 0 && pageNum <= totalPageNum) { + currentPageNum = pageNum; + checkPageStatus(); + } + } + + public T[] getShowItems(T[] items) { + int startIndex = Math.max(0, currentPageNum - 1); + T[] resultArr = ArrayUtils.subarray(items, startIndex * this.numPerPage, this.currentPageNum * this.numPerPage); + return resultArr; + } + + + /** + * 测试程序 + */ + public static void main(String[] args) { + JFrame frame = new JFrame(""); + frame.setSize(400, 320); + Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); + frame.setLocation((d.width - frame.getSize().width) / 2, (d.height - frame.getSize().height) / 2); + PagingFiledPane tt = new PagingFiledPane(10, 3); + frame.getContentPane().add(tt); + frame.setVisible(true); + } + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/PlaceholderTextArea.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/PlaceholderTextArea.java new file mode 100644 index 000000000..c463a4903 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/PlaceholderTextArea.java @@ -0,0 +1,42 @@ +package com.fr.design.mainframe.share.ui.base; + +import com.fr.design.gui.itextarea.UITextArea; + +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.RenderingHints; + +/** + * created by Harrison on 2020/04/21 + **/ +public class PlaceholderTextArea extends UITextArea { + + private String placeholder; + + public PlaceholderTextArea() { + } + + public PlaceholderTextArea(String s, String placeholder) { + super(s); + this.placeholder = placeholder; + } + + public void setPlaceholder(String placeholder) { + + this.placeholder = placeholder; + } + + @Override + protected void paintComponent(final Graphics pG) { + super.paintComponent(pG); + if (placeholder.length() == 0 || getText().length() > 0) { + return; + } + final Graphics2D g = (Graphics2D) pG; + g.setRenderingHint( + RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + g.setColor(getDisabledTextColor()); + g.drawString(placeholder, getInsets().left, pG.getFontMetrics() + .getMaxAscent() + getInsets().top + 1); + }} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/PopupMenuItem.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/PopupMenuItem.java new file mode 100644 index 000000000..4ef1cffc6 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/PopupMenuItem.java @@ -0,0 +1,31 @@ +package com.fr.design.mainframe.share.ui.base; + +import com.fr.design.constants.UIConstants; +import com.fr.design.mainframe.share.ui.base.ui.SharePopupMenuItemUI; +import com.fr.stable.StringUtils; + +import javax.swing.Action; +import javax.swing.JMenuItem; +import java.awt.Dimension; + +/** + * @Author: Yuan.Wang + * @Date: 2020/10/30 + * 弹窗菜单项 + */ +public class PopupMenuItem extends JMenuItem { + + public PopupMenuItem(Action action) { + super(StringUtils.EMPTY, null); + setBackground(UIConstants.DEFAULT_BG_RULER); + setAction(action); + setUI(new SharePopupMenuItemUI()); + this.setPreferredSize(new Dimension(60, 21)); + } + + @Override + public String getText() { + return StringUtils.EMPTY + super.getText(); + } + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/PopupPreviewPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/PopupPreviewPane.java new file mode 100644 index 000000000..91b1eae89 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/PopupPreviewPane.java @@ -0,0 +1,83 @@ +package com.fr.design.mainframe.share.ui.base; + +import com.fr.design.constants.UIConstants; +import com.fr.general.IOUtils; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.JPopupMenu; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.Toolkit; + +/** + * Created by kerry on 2020-06-23 + */ +public class PopupPreviewPane extends JPopupMenu { + private Container contentPane; + private Image compImage; + private static final int WIDTH = 400; + private static final int STANDARD_DPI = 128; + private static final int MAX_HEIGHT = 400; + private static final int HEIGHT = 210; + + public PopupPreviewPane() { + setFocusable(false); + contentPane = new JPanel(); + contentPane.setBackground(Color.white); + this.setLayout(new BorderLayout()); + this.add(contentPane, BorderLayout.CENTER); + this.setOpaque(false); + setPreferredSize(new Dimension(WIDTH, MAX_HEIGHT)); + setBorder(BorderFactory.createLineBorder(UIConstants.LINE_COLOR)); + } + + public void setComp(Image compImage) { + try { + this.compImage = compImage; + this.updateSize(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Override + public void paint(Graphics g) { + super.paint(g); + if (compImage != null) { + g.drawImage(compImage, 0, 0, getWidth(), getHeight(), null); + } + } + + @Override + public void setVisible(boolean visible) { + super.setVisible(visible); + } + + public void menuSelectionChanged(boolean isIncluded) { + } + + + // 根据控件内容,更新弹出框大小 + private void updateSize() { + int dpi = Toolkit.getDefaultToolkit().getScreenResolution(); + int width; + int height; + if (compImage == null) { + compImage = IOUtils.readImage("com/fr/base/images/share/component_error.png"); + width = WIDTH; + height = HEIGHT; + } else { + width = compImage.getWidth(null); + height = compImage.getHeight(null); + } + double aspectRatio = (double) width / height; + width = (WIDTH * dpi) / STANDARD_DPI; + height = (int) (width / aspectRatio); + this.setPreferredSize(new Dimension(width, height)); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/ShareProgressBar.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/ShareProgressBar.java new file mode 100644 index 000000000..49fd3173b --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/ShareProgressBar.java @@ -0,0 +1,231 @@ +package com.fr.design.mainframe.share.ui.base; + +import com.fr.concurrent.NamedThreadFactory; +import com.fr.design.gui.iprogressbar.ProgressDialog; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.ui.util.UIUtil; +import com.fr.stable.StringUtils; + +import java.util.concurrent.Callable; +import java.util.concurrent.Executors; +import java.util.concurrent.FutureTask; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +public class ShareProgressBar { + + private static final int STEP = 20; + + private ProgressDialog progressBar = null; + + private LimitProgress loadingProgress = new LimitProgress(); + + /** + * 默认 40 ms更新进度 + */ + private int stepHeartbeat = 40; + + private volatile int progress = 0; + + private final AtomicBoolean TERMINATE = new AtomicBoolean(false); + + private final AtomicBoolean RUNNING = new AtomicBoolean(false); + + private ShareProgressBar() { + } + + private static class InstanceHolder { + + private static final ShareProgressBar INSTANCE = new ShareProgressBar(); + } + + public static ShareProgressBar getInstance() { + + return InstanceHolder.INSTANCE; + } + + public void prepare(int stepHeartbeat) { + + this.progressBar = createNewBar(); + this.stepHeartbeat = stepHeartbeat; + } + + public void updateProgress(double rate, String loadingText) throws Exception { + int maximum = progressBar.getProgressMaximum(); + double progress = maximum * rate; + int maxProgress = (int) Math.floor(progress); + loadingProgress.lock(maxProgress, loadingText); + + RUNNING.compareAndSet(false, true); + //终止条件 + TERMINATE.compareAndSet(true, false); + + loadingProgress.get(); + + } + + public void monitor() { + + final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1, + new NamedThreadFactory("ShareProgressMonitor", true)); + scheduler.scheduleAtFixedRate(new Runnable() { + @Override + public void run() { + if (!isRunning()) { + return; + } + if (isComplete()) { + shutdown(scheduler); + return; + } + updateUI(); + } + }, 0, stepHeartbeat, TimeUnit.MILLISECONDS); + } + + + /** + * 延迟关闭 + */ + public void complete(String loadingText) throws Exception { + + updateProgress(1.0, loadingText); + } + + /** + * 立刻关闭 + */ + public void completeNow() { + + if (RUNNING.get()) { + this.progress = progressBar.getProgressMaximum(); + this.TERMINATE.compareAndSet(false, true); + } + } + + /** + * 完成条件。不只是达到目标值,还要确保当前已经可以终止了。 + * + * @return 是否终止了。 + */ + public boolean isComplete() { + + return this.progress >= progressBar.getProgressMaximum() && this.TERMINATE.get(); + } + + private ProgressDialog createNewBar() { + return new ProgressDialog(DesignerContext.getDesignerFrame()); + } + + /** + * 小于当前最大时, 每次递增 1 + * 大于等于时, 停止 + * + * @return 当前最大值 + */ + private int incrementProgress() { + if (progress >= loadingProgress.getLimitKey()) { + progress = loadingProgress.getLimitKey(); + loadingProgress.release(); + return progress; + } else { + progress += STEP; + return progress; + } + } + + private String getLoadingText() { + + return loadingProgress.getLimitText(); + } + + + private boolean isRunning() { + + return RUNNING.get(); + } + + + private void shutdown(ScheduledExecutorService scheduler) { + + //停止运行 + RUNNING.compareAndSet(true, false); + reset(); + scheduler.shutdown(); + } + + private void reset() { + + this.progress = 0; + this.loadingProgress.reset(); + this.progressBar.setVisible(false); + this.progressBar.dispose(); + this.progressBar = null; + } + + private void updateUI() { + String text = getLoadingText(); + int value = incrementProgress(); + UIUtil.invokeLaterIfNeeded(new Runnable() { + @Override + public void run() { + if (!progressBar.isVisible()) { + progressBar.setVisible(true); + } + progressBar.updateLoadingText(text); + progressBar.setProgressValue(value); + } + }); + } + + private static class LimitProgress { + + private int limitKey = 0; + + private String limitText = StringUtils.EMPTY; + + private FutureTask lock; + + public void lock(int key, String loadingText) { + + this.limitKey = key; + this.limitText = loadingText; + this.lock = new FutureTask<>(new Callable() { + @Override + public Void call() throws Exception { + return null; + } + }); + } + + public void release() { + + this.lock.run(); + } + + public void get() throws Exception { + + this.lock.get(); + } + + public void reset() { + + this.limitKey = 0; + this.limitText = StringUtils.EMPTY; + //防止卡住。 + this.lock.run(); + } + + public int getLimitKey() { + return limitKey; + } + + public String getLimitText() { + return limitText; + } + + + } + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/SortPopupMenuItem.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/SortPopupMenuItem.java new file mode 100644 index 000000000..2b3c5703c --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/SortPopupMenuItem.java @@ -0,0 +1,104 @@ +package com.fr.design.mainframe.share.ui.base; + +import com.fr.design.constants.UIConstants; +import com.fr.design.utils.gui.GUIPaintUtils; +import com.fr.stable.Constants; +import com.fr.stable.StringUtils; +import sun.swing.SwingUtilities2; + +import javax.swing.Action; +import javax.swing.ButtonModel; +import javax.swing.JMenu; +import javax.swing.JMenuItem; +import javax.swing.UIManager; +import javax.swing.plaf.basic.BasicMenuItemUI; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Rectangle; + +/** + * Created by kerry on 2020-06-30 + */ +public class SortPopupMenuItem extends JMenuItem { + + + public SortPopupMenuItem(Action action) { + super(StringUtils.EMPTY, null); + setBackground(UIConstants.DEFAULT_BG_RULER); + setAction(action); + setUI(new SortPopupMenuItemUI()); + this.setPreferredSize(new Dimension(60, 21)); + } + + @Override + public String getText() { + return StringUtils.EMPTY + super.getText(); + } + + + private class SortPopupMenuItemUI extends BasicMenuItemUI { + + @Override + protected void paintBackground(Graphics g, JMenuItem menuItem, Color bgColor) { + if (menuItem.getIcon() == null) { + super.paintBackground(g, menuItem, bgColor); + return; + } + ButtonModel model = menuItem.getModel(); + Color oldColor = g.getColor(); + int menuWidth = menuItem.getWidth(); + int menuHeight = menuItem.getHeight(); + + g.setColor(UIConstants.DEFAULT_BG_RULER); + g.fillRect(0, 0, menuWidth, menuHeight); + if (menuItem.isOpaque()) { + if (model.isArmed() || (menuItem instanceof JMenu && model.isSelected())) { + GUIPaintUtils.fillPaint((Graphics2D) g, 0, 0, menuWidth, menuHeight, true, Constants.NULL, UIConstants.FLESH_BLUE, 7); + } else { + GUIPaintUtils.fillPaint((Graphics2D) g, 0, 0, menuWidth, menuHeight, true, Constants.NULL, menuItem.getBackground(), 7); + } + g.setColor(oldColor); + } else if (model.isArmed() || (menuItem instanceof JMenu && + model.isSelected())) { + GUIPaintUtils.fillPaint((Graphics2D) g, 0, 0, menuWidth, menuHeight, true, Constants.NULL, UIConstants.FLESH_BLUE, 7); + g.setColor(oldColor); + } + } + + protected void paintText(Graphics g, JMenuItem menuItem, Rectangle textRect, String text) { + ButtonModel model = menuItem.getModel(); + FontMetrics fm = SwingUtilities2.getFontMetrics(menuItem, g); + int mnemIndex = menuItem.getDisplayedMnemonicIndex(); + + if (!model.isEnabled()) { + // *** paint the text disabled + if (UIManager.get("MenuItem.disabledForeground") instanceof Color) { + g.setColor(UIManager.getColor("MenuItem.disabledForeground")); + SwingUtilities2.drawStringUnderlineCharAt(menuItem, g, text, + -1, textRect.x, textRect.y + fm.getAscent()); + } else { + g.setColor(menuItem.getBackground().brighter()); + SwingUtilities2.drawStringUnderlineCharAt(menuItem, g, text, + -1, textRect.x, textRect.y + fm.getAscent()); + g.setColor(menuItem.getBackground().darker()); + SwingUtilities2.drawStringUnderlineCharAt(menuItem, g, text, + -1, textRect.x - 1, textRect.y + + fm.getAscent() - 1); + } + } else { + // *** paint the text normally + if (model.isArmed() || (menuItem instanceof JMenu && model.isSelected())) { + g.setColor(Color.WHITE); // Uses protected field. + } + SwingUtilities2.drawStringUnderlineCharAt(menuItem, g, text, + -1, textRect.x, textRect.y + fm.getAscent()); + } + } + + } + + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/ui/PlaceHolderUI.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/ui/PlaceHolderUI.java new file mode 100644 index 000000000..5c4c39eae --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/ui/PlaceHolderUI.java @@ -0,0 +1,48 @@ +package com.fr.design.mainframe.share.ui.base.ui; + +import javax.swing.JComponent; +import javax.swing.plaf.ComponentUI; +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.RenderingHints; + +/** + * created by Harrison on 2020/04/22 + **/ +public abstract class PlaceHolderUI extends ComponentUI { + + private static final Color DEFAULT_COLOR = new Color(143, 142, 139); + + private String placeholder; + + + public PlaceHolderUI(String placeholder) { + this.placeholder = placeholder; + } + + @Override + public void paint(Graphics pG, JComponent c) { + @SuppressWarnings("unchecked") T realType = (T) c; + if (placeholder.length() == 0 || validate(realType)) { + return; + } + final Graphics2D g = (Graphics2D) pG; + g.setRenderingHint( + RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + g.setColor(getDisabledTextColor()); + g.drawString(placeholder, c.getInsets().left + 10, pG.getFontMetrics() + .getMaxAscent() + c.getInsets().top + 3); + + } + + + protected abstract boolean validate(T t); + + protected Color getDisabledTextColor() { + + return DEFAULT_COLOR; + }; + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/ui/SharePopupMenuItemUI.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/ui/SharePopupMenuItemUI.java new file mode 100644 index 000000000..16a5a58bd --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/ui/SharePopupMenuItemUI.java @@ -0,0 +1,82 @@ +package com.fr.design.mainframe.share.ui.base.ui; + +import com.fr.design.constants.UIConstants; +import com.fr.design.utils.gui.GUIPaintUtils; +import com.fr.stable.Constants; +import sun.swing.SwingUtilities2; + +import javax.swing.ButtonModel; +import javax.swing.JMenu; +import javax.swing.JMenuItem; +import javax.swing.UIManager; +import javax.swing.plaf.basic.BasicMenuItemUI; +import java.awt.Color; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Rectangle; + +/** + * @Author: Yuan.Wang + * @Date: 2020/10/30 + */ +public class SharePopupMenuItemUI extends BasicMenuItemUI { + + @Override + protected void paintBackground(Graphics g, JMenuItem menuItem, Color bgColor) { + if (menuItem.getIcon() == null) { + super.paintBackground(g, menuItem, bgColor); + return; + } + ButtonModel model = menuItem.getModel(); + Color oldColor = g.getColor(); + int menuWidth = menuItem.getWidth(); + int menuHeight = menuItem.getHeight(); + + g.setColor(UIConstants.DEFAULT_BG_RULER); + g.fillRect(0, 0, menuWidth, menuHeight); + if (menuItem.isOpaque()) { + if (model.isArmed() || (menuItem instanceof JMenu && model.isSelected())) { + GUIPaintUtils.fillPaint((Graphics2D) g, 0, 0, menuWidth, menuHeight, true, Constants.NULL, UIConstants.FLESH_BLUE, 7); + } else { + GUIPaintUtils.fillPaint((Graphics2D) g, 0, 0, menuWidth, menuHeight, true, Constants.NULL, menuItem.getBackground(), 7); + } + g.setColor(oldColor); + } else if (model.isArmed() || (menuItem instanceof JMenu && + model.isSelected())) { + GUIPaintUtils.fillPaint((Graphics2D) g, 0, 0, menuWidth, menuHeight, true, Constants.NULL, UIConstants.FLESH_BLUE, 7); + g.setColor(oldColor); + } + } + + protected void paintText(Graphics g, JMenuItem menuItem, Rectangle textRect, String text) { + ButtonModel model = menuItem.getModel(); + FontMetrics fm = SwingUtilities2.getFontMetrics(menuItem, g); + + if (!model.isEnabled()) { + // *** paint the text disabled + if (UIManager.get("MenuItem.disabledForeground") instanceof Color) { + g.setColor(UIManager.getColor("MenuItem.disabledForeground")); + SwingUtilities2.drawStringUnderlineCharAt(menuItem, g, text, + -1, textRect.x, textRect.y + fm.getAscent()); + } else { + g.setColor(menuItem.getBackground().brighter()); + SwingUtilities2.drawStringUnderlineCharAt(menuItem, g, text, + -1, textRect.x, textRect.y + fm.getAscent()); + g.setColor(menuItem.getBackground().darker()); + SwingUtilities2.drawStringUnderlineCharAt(menuItem, g, text, + -1, textRect.x - 1, textRect.y + + fm.getAscent() - 1); + } + } else { + g.setColor(Color.BLACK); + // *** paint the text normally + if (model.isArmed() || (menuItem instanceof JMenu && model.isSelected())) { + g.setColor(Color.WHITE); // Uses protected field. + } + + SwingUtilities2.drawStringUnderlineCharAt(menuItem, g, text, + -1, textRect.x, textRect.y + fm.getAscent()); + } + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/AbstractOnlineWidgetBlock.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/AbstractOnlineWidgetBlock.java new file mode 100644 index 000000000..06e513b80 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/AbstractOnlineWidgetBlock.java @@ -0,0 +1,94 @@ +package com.fr.design.mainframe.share.ui.block; + +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.mainframe.share.ui.online.OnlineResourceManager; +import com.fr.design.mainframe.share.ui.online.OnlineWidgetSelectPane; +import com.fr.design.mainframe.share.ui.online.ResourceLoader; +import com.fr.form.share.bean.OnlineShareWidget; +import com.fr.form.share.constants.ShareComponentConstants; +import com.fr.log.FineLoggerFactory; +import com.fr.stable.EncodeConstants; +import com.fr.third.springframework.web.util.UriUtils; +import org.jetbrains.annotations.NotNull; + +import javax.imageio.ImageIO; +import javax.swing.ImageIcon; +import java.awt.Dimension; +import java.awt.Image; +import java.io.IOException; +import java.net.URL; + +/** + * Created by kerry on 2020-11-22 + */ +public abstract class AbstractOnlineWidgetBlock extends PreviewWidgetBlock implements ResourceLoader { + + private final OnlineWidgetSelectPane parentPane; + private UILabel coverLabel; + + public AbstractOnlineWidgetBlock(OnlineShareWidget widget, OnlineWidgetSelectPane parentPane) { + super(widget); + this.parentPane = parentPane; + } + + protected UILabel initCoverLabel(Image image) { + coverLabel = new UILabel(new ImageIcon(image)); + return coverLabel; + } + + @Override + protected String getWidgetUuid() { + return widget.getUuid(); + } + + protected void showPreview(OnlineShareWidget widget) { + parentPane.showPreviewPane(this, widget.getId()); + } + + protected void hidePreview() { + parentPane.hidePreviewPane(); + } + + @Override + @NotNull + protected Image getCoverImage() { + OnlineResourceManager.getInstance().addLoader(this); + return getDefaultDisplayImage(); + } + + public Image getPreviewImage() { + try { + return ImageIO.read(new URL(UriUtils.encodePath(widget.getPicPath(), EncodeConstants.ENCODING_UTF_8))); + } catch (IOException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + return getDefaultDisplayImage(); + } + } + + public void load() { + Image image; + try { + + Dimension coverDimension = getCoverDimension(); + String previewURI = UriUtils.encodePath(widget.getPicPath(), EncodeConstants.ENCODING_UTF_8) + "?x-oss-process=image/resize,m_fixed," + "w_" + coverDimension.width + + ",h_" + coverDimension.height; + image = ImageIO.read(new URL(previewURI)); + } catch (IOException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + image = getDefaultDisplayImage(); + } + resetCover(image); + } + + private Image getDefaultDisplayImage(){ + return ShareComponentConstants.DEFAULT_COVER; + } + + + public void resetCover(Image image) { + coverLabel.setIcon(new ImageIcon(image)); + this.parentPane.validate(); + this.parentPane.repaint(); + } + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/DragAndDropDragGestureListener.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/DragAndDropDragGestureListener.java new file mode 100644 index 000000000..3fe0fc388 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/DragAndDropDragGestureListener.java @@ -0,0 +1,72 @@ +package com.fr.design.mainframe.share.ui.block; + +import com.fr.form.share.utils.ShareUtils; +import com.fr.form.ui.Widget; +import com.fr.general.ComparatorUtils; +import org.jetbrains.annotations.NotNull; + +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.dnd.DragGestureEvent; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragSource; +import java.awt.dnd.DragSourceAdapter; +import java.awt.dnd.DragSourceDragEvent; + +/** + * @Author: Yuan.Wang + * @Date: 2021/1/15 + */ +public class DragAndDropDragGestureListener extends DragSourceAdapter implements DragGestureListener { + private final PreviewWidgetBlock block; + + public DragAndDropDragGestureListener(PreviewWidgetBlock tt, int actions) { + block = tt; + DragSource source = new DragSource(); + source.createDefaultDragGestureRecognizer(tt, actions, this); + } + + public void dragGestureRecognized(DragGestureEvent dge) { + PreviewWidgetBlock onlineWidgetBlock = (PreviewWidgetBlock) dge.getComponent(); + if (onlineWidgetBlock != null) { + String uuid = block.getWidgetUuid(); + Widget widget = ShareUtils.getElCaseEditorById(uuid); + if (widget != null) { + DragAndDropTransferable dragAndDropTransferable = new DragAndDropTransferable(widget); + dge.startDrag(DragSource.DefaultCopyDrop, dragAndDropTransferable, this); + } + } + } + + @Override + public void dragEnter(DragSourceDragEvent dragSourceDragEvent) { + + } + + private static class DragAndDropTransferable implements Transferable { + private final Widget widget; + + public DragAndDropTransferable(Widget widget) { + this.widget = widget; + } + + DataFlavor[] flavors = {new DataFlavor(Widget.class, "Widget")}; + + public DataFlavor[] getTransferDataFlavors() { + return flavors; + } + + public boolean isDataFlavorSupported(DataFlavor flavor) { + for (DataFlavor df : flavors) { + if (ComparatorUtils.equals(df, flavor)) { + return true; + } + } + return false; + } + @NotNull + public Object getTransferData(DataFlavor df) { + return widget; + } + } +} \ No newline at end of file diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/LocalWidgetBlock.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/LocalWidgetBlock.java new file mode 100644 index 000000000..862616fa4 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/LocalWidgetBlock.java @@ -0,0 +1,313 @@ +package com.fr.design.mainframe.share.ui.block; + +import com.fr.base.GraphHelper; +import com.fr.base.iofile.attr.SharableAttrMark; +import com.fr.design.actions.UpdateAction; +import com.fr.design.base.mode.DesignModeContext; +import com.fr.design.constants.UIConstants; +import com.fr.design.designer.creator.XCreator; +import com.fr.design.dialog.FineJOptionPane; +import com.fr.design.form.util.XCreatorConstants; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.gui.imenu.UIPopupMenu; +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.WidgetToolBarPane; +import com.fr.design.mainframe.share.group.ui.GroupMoveDialog; +import com.fr.design.mainframe.share.ui.base.PopupMenuItem; +import com.fr.design.mainframe.share.ui.local.LocalWidgetRepoPane; +import com.fr.design.mainframe.share.ui.local.LocalWidgetSelectPane; +import com.fr.design.mainframe.share.ui.local.WidgetSelectedManager; +import com.fr.design.mainframe.share.util.ShareComponentUtils; +import com.fr.design.mainframe.share.util.ShareUIUtils; +import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.form.share.DefaultSharableWidget; +import com.fr.form.share.SharableWidgetProvider; +import com.fr.form.share.constants.ShareComponentConstants; +import com.fr.form.share.Group; +import com.fr.form.share.record.ShareWidgetInfoManager; +import com.fr.form.ui.AbstractBorderStyleWidget; +import com.fr.form.ui.Widget; +import com.fr.general.ComparatorUtils; +import com.fr.general.IOUtils; +import com.fr.stable.Constants; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.Action; +import javax.swing.Icon; +import javax.swing.JPanel; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Cursor; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.Rectangle; +import java.awt.dnd.DnDConstants; +import java.awt.event.ActionEvent; +import java.awt.event.MouseEvent; +import java.util.UUID; + +/** + * created by Harrison on 2020/06/12 + * 本地组件块 + **/ +public class LocalWidgetBlock extends PreviewWidgetBlock { + private static final int MARK_START_X = 83; + + private boolean mouseHover = false; + private final LocalWidgetSelectPane parentPane; + + private MouseEvent lastPressEvent; + private boolean isEdit; + private boolean isMarked; + private boolean pressed; + private boolean hover; + private final Icon markedMode = IOUtils.readIcon("/com/fr/base/images/share/marked.png"); + private final Icon unMarkedMode = IOUtils.readIcon("/com/fr/base/images/share/unmarked.png"); + + public LocalWidgetBlock(DefaultSharableWidget provider, LocalWidgetSelectPane parentPane) { + super(provider); + this.parentPane = parentPane; + new DragAndDropDragGestureListener(this, DnDConstants.ACTION_COPY_OR_MOVE); + initUI(); + } + + + private void initUI() { + JPanel labelPane = new JPanel(new BorderLayout()); + UILabel label = new UILabel(this.getBindInfo().getName(), UILabel.CENTER); + label.setPreferredSize(new Dimension(ShareComponentConstants.SHARE_THUMB_WIDTH, ShareComponentConstants.SHARE_BLOCK_LABEL_HEIGHT)); + labelPane.setBackground(Color.WHITE); + labelPane.add(label, BorderLayout.CENTER); + this.add(labelPane, BorderLayout.SOUTH); + } + + public void setElementCaseEdit(boolean isEdit) { + this.isEdit = isEdit; + if (isEdit) { + isMarked = WidgetSelectedManager.getInstance().isSelected(getGroup().getGroupName(), this.getWidget().getId()); + } + repaint(); + } + + public String getFileName() { + //插件里面, 所有的值都是插件值。可以强转的。 + DefaultSharableWidget provider = (DefaultSharableWidget) getBindInfo(); + return provider.getFileName(); + } + + public SharableWidgetProvider getBindInfo() { + return this.getWidget(); + } + + @Override + protected void showPreview(DefaultSharableWidget widget) { + this.parentPane.showPreviewPane(this, widget.getId()); + } + + @Override + protected void hidePreview() { + this.parentPane.hidePreviewPane(); + } + + @Override + @NotNull + public Image getCoverImage() { + return this.getWidget().getCover(); + } + + @Override + protected String getWidgetUuid() { + return widget.getId(); + } + + @Nullable + public Image getPreviewImage() { + String id = this.getWidget().getId(); + return getGroup().getPreviewImage(id); + } + + @Override + public void mouseClicked(MouseEvent e) { + super.mouseClicked(e); + if (e.getButton() == MouseEvent.BUTTON3 && !isEdit) { + this.parentPane.hidePreviewPane(); + UIPopupMenu popupMenu = new UIPopupMenu(); + popupMenu.setOnlyText(true); + popupMenu.setBackground(UIConstants.DEFAULT_BG_RULER); + popupMenu.add(new PopupMenuItem(new MoveGroupAction())); + popupMenu.add(new PopupMenuItem(new RemoveAction())); + GUICoreUtils.showPopupMenu(popupMenu, this, e.getX(), e.getY()); + } + + } + + @Override + public void mousePressed(MouseEvent e) { + super.mousePressed(e); + lastPressEvent = e; + pressed = true; + } + + @Override + public void mouseReleased(MouseEvent e) { + super.mouseReleased(e); + if (pressed && hover) { + dealClickAction(e); + } + pressed = false; + } + + @Override + public void mouseMoved(MouseEvent e) { + super.mouseMoved(e); + this.mouseHover = true; + if (!isEdit) { + setCursor(new Cursor(Cursor.MOVE_CURSOR)); + } + this.repaint(); + } + + @Override + public void mouseEntered(MouseEvent e) { + super.mouseEntered(e); + hover = true; + } + + @Override + public void mouseExited(MouseEvent e) { + super.mouseExited(e); + this.mouseHover = false; + setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); + hover = false; + this.repaint(); + } + + + @Override + public void mouseDragged(MouseEvent e) { + if (DesignModeContext.isAuthorityEditing() || lastPressEvent == null || isEdit) { + return; + } + hidePreview(); + Object source = e.getSource(); + Widget creatorSource; + String shareId; + if (source instanceof LocalWidgetBlock) { + LocalWidgetBlock no = (LocalWidgetBlock) e.getSource(); + if (no == null) { + return; + } + shareId = no.getBindInfo().getId(); + creatorSource = getGroup().getElCaseEditorById(shareId); + if (creatorSource == null) { + ShareUIUtils.showErrorMessageDialog(Toolkit.i18nText("Fine-Design_Share_Drag_Error_Info")); + return; + } + creatorSource.setWidgetID(UUID.randomUUID().toString()); + ((AbstractBorderStyleWidget) creatorSource).addWidgetAttrMark(new SharableAttrMark(true)); + //tab布局WCardMainBorderLayout通过反射出来的大小是960*480 + XCreator xCreator = ShareComponentUtils.createXCreator(creatorSource, shareId, no.getBindInfo()); + WidgetToolBarPane.getTarget().startDraggingBean(xCreator); + lastPressEvent = null; + this.setBorder(null); + } + } + + @Override + public void paint(Graphics g) { + super.paint(g); + //绘制删除标志 + if (isEdit) { + Icon icon = isMarked ? markedMode : unMarkedMode; + icon.paintIcon(this, g, MARK_START_X, 0); + } + if (ComparatorUtils.equals(this, this.parentPane.getSelectedBlock()) || this.mouseHover) { + g.setColor(XCreatorConstants.FORM_BORDER_COLOR); + Rectangle rectangle = new Rectangle(); + rectangle.width = this.getWidth(); + rectangle.height = this.getHeight(); + GraphHelper.draw(g, rectangle, Constants.LINE_LARGE); + } + } + + /** + * 由鼠标释放时调用该方法来触发左键点击事件 + */ + private void dealClickAction(MouseEvent e) { + this.parentPane.setSelectBlock(this); + if (e.getButton() == MouseEvent.BUTTON1) { + if (isEdit) { + if (isMarked) { + WidgetSelectedManager.getInstance().removeSelect(getGroup().getGroupName(), this.getWidget().getId()); + isMarked = false; + } else { + WidgetSelectedManager.getInstance().addSelect(getGroup().getGroupName(), this.getWidget().getId()); + isMarked = true; + } + } + //没有组件被选择则禁用按钮 + LocalWidgetRepoPane.getInstance().setManageButtonEnable(hasComponentSelected()); + repaint(); + } + } + + private Group getGroup() { + return parentPane.getGroup(); + } + + private boolean hasComponentSelected() { + return !WidgetSelectedManager.getInstance().isSelectEmpty(); + } + + private class MoveGroupAction extends UpdateAction { + public MoveGroupAction() { + this.putValue(Action.SMALL_ICON, null); + this.setName(Toolkit.i18nText("Fine-Design_Share_Group_Move")); + } + + @Override + public void actionPerformed(ActionEvent e) { + new GroupMoveDialog(DesignerContext.getDesignerFrame()) { + @Override + protected void confirmClose() { + this.dispose(); + Group group = (Group) getSelectGroupBox().getSelectedItem(); + assert group != null; + if (WidgetSelectedManager.getInstance().moveSelect(getGroup().getGroupName(), group.getGroupName(), getWidget().getId())) { + ShareWidgetInfoManager.getInstance().saveXmlInfo(); + LocalWidgetRepoPane.getInstance().refreshShowPanel(false); + } else { + ShareUIUtils.showErrorMessageDialog(Toolkit.i18nText("Fine-Design_Share_Group_Move_Fail_Message")); + } + } + + }; + } + } + + private class RemoveAction extends UpdateAction { + public RemoveAction() { + this.putValue(Action.SMALL_ICON, null); + this.setName(Toolkit.i18nText("Fine-Design_Share_Remove")); + } + + @Override + public void actionPerformed(ActionEvent e) { + int rv = FineJOptionPane.showConfirmDialog(DesignerContext.getDesignerFrame(), + Toolkit.i18nText("Fine-Design_Share_Remove_Info"), + Toolkit.i18nText("Fine-Design_Share_Group_Confirm"), + FineJOptionPane.YES_NO_OPTION + ); + if (rv == FineJOptionPane.YES_OPTION) { + if (!WidgetSelectedManager.getInstance().unInstallSelect(getGroup().getGroupName(), getWidget().getId())) { + FineJOptionPane.showMessageDialog(null, Toolkit.i18nText("Fine-Design_Share_Remove_Failure")); + } + LocalWidgetRepoPane.getInstance().refreshShowPanel(getGroup()); + } + } + } + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/OnlineWidgetBlock.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/OnlineWidgetBlock.java new file mode 100644 index 000000000..15ebebd6d --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/OnlineWidgetBlock.java @@ -0,0 +1,303 @@ +package com.fr.design.mainframe.share.ui.block; + +import com.fr.base.iofile.attr.SharableAttrMark; +import com.fr.config.MarketConfig; +import com.fr.design.base.mode.DesignModeContext; +import com.fr.design.designer.creator.XCreator; +import com.fr.design.extra.WebViewDlgHelper; +import com.fr.design.form.util.XCreatorConstants; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.WidgetToolBarPane; +import com.fr.design.mainframe.share.collect.ComponentCollector; +import com.fr.form.share.group.DefaultShareGroup; +import com.fr.design.mainframe.share.ui.local.LocalWidgetRepoPane; +import com.fr.design.mainframe.share.ui.online.OnlineWidgetRepoPane; +import com.fr.design.mainframe.share.ui.online.OnlineWidgetSelectPane; +import com.fr.design.mainframe.share.util.DownloadUtils; +import com.fr.design.mainframe.share.util.ShareComponentUtils; +import com.fr.design.mainframe.share.util.ShareUIUtils; +import com.fr.design.ui.util.UIUtil; +import com.fr.form.share.SharableWidgetProvider; +import com.fr.form.share.bean.OnlineShareWidget; +import com.fr.form.share.constants.ShareComponentConstants; +import com.fr.form.share.group.DefaultShareGroupManager; +import com.fr.form.share.Group; +import com.fr.form.share.utils.ShareUtils; +import com.fr.form.ui.AbstractBorderStyleWidget; +import com.fr.form.ui.Widget; +import com.fr.general.IOUtils; +import com.fr.log.FineLoggerFactory; +import com.fr.stable.StableUtils; +import com.fr.stable.StringUtils; + +import javax.swing.JPanel; +import javax.swing.SwingConstants; +import javax.swing.SwingWorker; +import java.awt.AlphaComposite; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Composite; +import java.awt.Cursor; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.RenderingHints; +import java.awt.Stroke; +import java.awt.dnd.DnDConstants; +import java.awt.event.MouseEvent; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.util.UUID; +import java.util.concurrent.ExecutionException; + +/** + * Created by kerry on 2020-10-19 + * 商城组件块 + */ +public class OnlineWidgetBlock extends AbstractOnlineWidgetBlock { + private boolean isMouseEnter = false; + private boolean downloading = false; + private static final Color COVER_COLOR = Color.decode("#333334"); + protected MouseEvent lastPressEvent; + private double process = 0D; + private static final BufferedImage WIDGET_INSTALLED_ICON = IOUtils.readImage("/com/fr/base/images/share/widget_installed.png"); + private static final BufferedImage WIDGET_DOWNLOAD_ICON = IOUtils.readImage("/com/fr/base/images/share/download.png"); + private static final BufferedImage WIDGET_DOWNLOADING_ICON = IOUtils.readImage("/com/fr/base/images/share/downloading.png"); + + public OnlineWidgetBlock(OnlineShareWidget widget, OnlineWidgetSelectPane parentPane) { + super(widget, parentPane); + this.add(createSouthPane(widget), BorderLayout.SOUTH); + new DragAndDropDragGestureListener(this, DnDConstants.ACTION_COPY_OR_MOVE); + } + + protected JPanel createSouthPane(OnlineShareWidget widget) { + JPanel southPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + UILabel label = new UILabel(widget.getName(), UILabel.CENTER); + label.setToolTipText(widget.getName()); + label.setHorizontalTextPosition(SwingConstants.LEFT); + southPane.add(label, BorderLayout.CENTER); + UILabel emptyLabel = new UILabel(); + emptyLabel.setPreferredSize(new Dimension(25, 20)); + southPane.add(emptyLabel, BorderLayout.EAST); + southPane.setBackground(Color.WHITE); + return southPane; + } + + @Override + public void mouseEntered(MouseEvent e) { + super.mouseEntered(e); + this.isMouseEnter = true; + this.repaint(); + } + + @Override + public void mouseExited(MouseEvent e) { + super.mouseExited(e); + this.isMouseEnter = false; + this.repaint(); + } + + @Override + public void mousePressed(MouseEvent e) { + super.mousePressed(e); + this.lastPressEvent = e; + } + + @Override + public void mouseClicked(MouseEvent e) { + super.mouseClicked(e); + if (!checkWidgetInstalled() && getDownloadIconRec().contains(e.getX(), e.getY())) { + downLoadWidget(); + } + } + + @Override + public void mouseDragged(MouseEvent e) { + if (DesignModeContext.isAuthorityEditing() || !checkWidgetInstalled()) { + return; + } + if (lastPressEvent == null) { + return; + } + Object source = e.getSource(); + Widget creatorSource; + String shareId; + if (source instanceof OnlineWidgetBlock) { + OnlineWidgetBlock no = (OnlineWidgetBlock) e.getSource(); + if (no == null) { + return; + } + shareId = widget.getUuid(); + creatorSource = ShareUtils.getElCaseEditorById(shareId); + if (creatorSource == null) { + ShareUIUtils.showErrorMessageDialog(Toolkit.i18nText("Fine-Design_Share_Drag_Error_Info")); + return; + } + creatorSource.setWidgetID(UUID.randomUUID().toString()); + ((AbstractBorderStyleWidget) creatorSource).addWidgetAttrMark(new SharableAttrMark(true)); + SharableWidgetProvider bindInfo = ShareUtils.getElCaseBindInfoById(shareId); + //tab布局WCardMainBorderLayout通过反射出来的大小是960*480 + XCreator xCreator = ShareComponentUtils.createXCreator(creatorSource, shareId, bindInfo); + WidgetToolBarPane.getTarget().startDraggingBean(xCreator); + lastPressEvent = null; + this.setBorder(null); + } + } + + private void downLoadWidget() { + if (OnlineWidgetRepoPane.getInstance().isShowPackagePanel()) { + ComponentCollector.getInstance().collectDownloadPktNum(); + } + final WidgetDownloadProcess process = new WidgetDownloadProcess(); + downloading = true; + process.process(0.0D); + String userName = MarketConfig.getInstance().getBbsUsername(); + if (StringUtils.isEmpty(userName)) { + WebViewDlgHelper.createLoginDialog(); + downloading = false; + return; + } + + new SwingWorker() { + + @Override + protected Boolean doInBackground() { + String filePath; + try { + filePath = DownloadUtils.download(widget.getId(), widget.getName() + "." + widget.getUuid(), process); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + return false; + } + ShareComponentUtils.checkReadMe(); + //安装 + File file = new File(filePath); + try { + if (file.exists() && getDefaultGroup().installModule(file)) { + ShareUtils.recordInstallTime(file.getName(), System.currentTimeMillis()); + ComponentCollector.getInstance().collectCmpDownLoad(widget.getUuid()); + } + } catch (IOException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } finally { + //删掉下载组件的目录 + StableUtils.deleteFile(file); + } + return true; + + } + + @Override + protected void done() { + downloading = false; + OnlineWidgetBlock.this.process = 0.0D; + try { + if (get()) { + LocalWidgetRepoPane.getInstance().refreshShowPanel(); + } else { + ShareUIUtils.showErrorMessageDialog(Toolkit.i18nText("Fine-Design_Share_Download_Failed")); + } + } catch (InterruptedException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + Thread.currentThread().interrupt(); + } catch (ExecutionException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + } + }.execute(); + + + } + + + @Override + public void mouseMoved(MouseEvent e) { + super.mouseMoved(e); + if (checkWidgetInstalled()) { + this.setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR)); + } else if (getDownloadIconRec().contains(e.getX(), e.getY())) { + this.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + } else { + this.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + } + } + + private Rectangle getDownloadIconRec() { + return new Rectangle(ShareComponentConstants.SHARE_THUMB_WIDTH / 2 - 12, ShareComponentConstants.SHARE_BLOCK_HEIGHT / 2 - 16, 24, 24); + } + + private boolean checkWidgetInstalled() { + return ShareUtils.getElCaseBindInfoById(widget.getUuid()) != null; + } + + private Group getDefaultGroup() { + return DefaultShareGroupManager.getInstance().getGroup(DefaultShareGroup.GROUP_NAME); + } + + public void paint(Graphics g) { + super.paint(g); + ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB); + int x = 0; + int y = 0; + int w = getWidth(); + int h = getHeight(); + if (process == 1 || checkWidgetInstalled()) { + Graphics2D g2d = (Graphics2D) g; + g2d.drawImage( + WIDGET_INSTALLED_ICON, + w - 20, + h - 20, + WIDGET_INSTALLED_ICON.getWidth(), + WIDGET_INSTALLED_ICON.getHeight(), + null, + this + ); + return; + } + //如果鼠标移动到布局内且布局不可编辑,画出编辑蒙层 + if (isMouseEnter || downloading) { + Graphics2D g2d = (Graphics2D) g; + Composite oldComposite = g2d.getComposite(); + //画白色的编辑层 + g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 20 / 100.0F)); + g2d.setColor(COVER_COLOR); + g2d.fillRect(x, y, w, h); + g2d.setComposite(oldComposite); + //画编辑按钮图标 + BufferedImage image = (process > 0 || downloading) ? WIDGET_DOWNLOADING_ICON : WIDGET_DOWNLOAD_ICON; + g2d.drawImage( + image, + (x + w / 2 - 12), + (y + h / 2 - 16), + image.getWidth(), + image.getHeight(), + null, + this + ); + Stroke oldStroke = g2d.getStroke(); + g2d.setStroke(XCreatorConstants.STROKE); + g2d.setColor(Color.decode("#419BF9")); + double arcAngle = downloading ? (36 + 360 * 0.9 * process) : 0.0; + g2d.drawArc(x + w / 2 - 12, y + h / 2 - 16, 24, 24, 90, -(int) arcAngle); + g2d.setColor(Color.WHITE); + g2d.setStroke(oldStroke); + } + } + + + class WidgetDownloadProcess implements com.fr.design.extra.Process { + + @Override + public void process(Double aDouble) { + OnlineWidgetBlock.this.process = aDouble; + final Dimension dimension = OnlineWidgetBlock.this.getSize(); + UIUtil.invokeAndWaitIfNeeded(() -> OnlineWidgetBlock.this.paintImmediately(0, 0, dimension.width, dimension.height)); + } + } + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/OnlineWidgetPackageBlock.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/OnlineWidgetPackageBlock.java new file mode 100644 index 000000000..4b8458594 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/OnlineWidgetPackageBlock.java @@ -0,0 +1,57 @@ +package com.fr.design.mainframe.share.ui.block; + +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.share.ui.base.MouseClickListener; +import com.fr.design.mainframe.share.ui.online.widgetpackage.OnlineWidgetPackageSelectPane; +import com.fr.form.share.bean.OnlineShareWidget; +import com.fr.form.share.constants.ShareComponentConstants; + +import javax.swing.JPanel; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Cursor; +import java.awt.Dimension; +import java.awt.event.MouseEvent; + +/** + * Created by kerry on 2020-10-21 + * 商城组件包块 + */ +public class OnlineWidgetPackageBlock extends AbstractOnlineWidgetBlock { + private static final int IMAGE_HEIGHT = 167; + private static final Color TEXT_COLOR = Color.decode("#419BF9"); + + protected JPanel createSouthPane(final OnlineShareWidget widget, final OnlineWidgetPackageSelectPane parentPane) { + JPanel southPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + southPane.setBackground(Color.WHITE); + UILabel label = new UILabel(widget.getName(), UILabel.CENTER); + label.setToolTipText(widget.getName()); + southPane.add(label, BorderLayout.CENTER); + UILabel detailLabel = new UILabel(Toolkit.i18nText("Fine-Design_Share_Online_Package_Detail")); + detailLabel.setForeground(TEXT_COLOR); + detailLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + detailLabel.addMouseListener(new MouseClickListener() { + @Override + public void mouseClicked(MouseEvent e) { + parentPane.showWidgetDetailPane(widget.getId()); + } + }); + southPane.add(detailLabel, BorderLayout.EAST); + return southPane; + } + + protected Dimension getCoverDimension() { + return new Dimension(ShareComponentConstants.SHARE_PACKAGE_BLOCK_WIDTH, IMAGE_HEIGHT); + } + + public OnlineWidgetPackageBlock(OnlineShareWidget widget, OnlineWidgetPackageSelectPane parentPane) { + super(widget, parentPane); + this.setPreferredSize(new Dimension(ShareComponentConstants.SHARE_PACKAGE_BLOCK_WIDTH, ShareComponentConstants.SHARE_PACKAGE_BLOCK_HEIGHT)); + this.add(createSouthPane(widget, parentPane), BorderLayout.SOUTH); + } + +} + + diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/PreviewWidgetBlock.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/PreviewWidgetBlock.java new file mode 100644 index 000000000..8ad9e2b11 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/PreviewWidgetBlock.java @@ -0,0 +1,138 @@ +package com.fr.design.mainframe.share.ui.block; + +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.form.share.constants.ShareComponentConstants; +import org.jetbrains.annotations.NotNull; + +import javax.swing.ImageIcon; +import javax.swing.JPanel; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.Rectangle; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; +import java.io.Serializable; + +/** + * Created by kerry on 2020-10-21 + */ +public abstract class PreviewWidgetBlock extends JPanel implements MouseListener, MouseMotionListener, Serializable { + protected T widget; + private boolean showing = false; + + public PreviewWidgetBlock(T widget) { + this.widget = widget; + initPane(); + this.addMouseListener(this); + this.addMouseMotionListener(this); + } + + protected void initPane() { + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + this.setPreferredSize(new Dimension(ShareComponentConstants.SHARE_THUMB_WIDTH, ShareComponentConstants.SHARE_BLOCK_HEIGHT)); + JPanel labelPane = new JPanel(new BorderLayout()); + Image image = getCoverImage(); + labelPane.add(initCoverLabel(image)); + labelPane.setBackground(Color.WHITE); + this.add(labelPane, BorderLayout.CENTER); + } + + protected UILabel initCoverLabel(Image image) { + return new UILabel(new ImageIcon(image)); + } + + public T getWidget() { + return widget; + } + + + @NotNull + protected abstract Image getCoverImage(); + + protected Dimension getCoverDimension() { + return new Dimension(ShareComponentConstants.SHARE_THUMB_WIDTH, ShareComponentConstants.SHARE_THUMB_HEIGHT); + } + + private void showPreviewPane() { + synchronized (this) { + if (!showing) { + showPreview(widget); + showing = true; + } + } + } + protected abstract String getWidgetUuid(); + + protected abstract void showPreview(T widget); + + protected abstract void hidePreview(); + + private void hidePreviewPane() { + if (showing) { + hidePreview(); + showing = false; + } + } + + public abstract Image getPreviewImage(); + + @Override + public void mouseClicked(MouseEvent e) { + this.hidePreviewPane(); + } + + @Override + public void mousePressed(MouseEvent e) { + + } + + @Override + public void mouseReleased(MouseEvent e) { + + } + + @Override + public void mouseEntered(MouseEvent e) { + + } + + @Override + public void mouseExited(MouseEvent e) { + this.hidePreviewPane(); + } + + @Override + public void mouseDragged(MouseEvent e) { + + } + + @Override + public void mouseMoved(MouseEvent e) { + Dimension dimension = getCoverDimension(); + Rectangle containerRec = new Rectangle(0, 0, dimension.width, dimension.height); + if (containerRec.contains(e.getX(), e.getY())) { + this.showPreviewPane(); + } else { + this.hidePreviewPane(); + } + } + + @Override + public void paint(Graphics g) { + Graphics2D g2d = (Graphics2D) g; + g2d.setColor(Color.WHITE); + g2d.fillRect(0, 0, getWidth(), getHeight()); + super.paint(g); + } + + protected void removeListener() { + this.removeMouseListener(this); + this.removeMouseMotionListener(this); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/SimpleWidgetBlock.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/SimpleWidgetBlock.java new file mode 100644 index 000000000..cf5e948de --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/SimpleWidgetBlock.java @@ -0,0 +1,17 @@ +package com.fr.design.mainframe.share.ui.block; + +import com.fr.design.mainframe.share.ui.online.OnlineWidgetSelectPane; +import com.fr.form.share.bean.OnlineShareWidget; + +/** + * @Author: Yuan.Wang + * @Date: 2020/12/22 + * 只能显示,无其他功能的组件块 + */ +public class SimpleWidgetBlock extends OnlineWidgetBlock { + public SimpleWidgetBlock(OnlineShareWidget widget, OnlineWidgetSelectPane parentPane) { + super(widget, parentPane); + this.removeListener(); + this.setFocusable(false); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/GroupPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/GroupPane.java new file mode 100644 index 000000000..94d24a3d5 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/GroupPane.java @@ -0,0 +1,380 @@ +package com.fr.design.mainframe.share.ui.local; + +import com.fr.design.actions.UpdateAction; +import com.fr.design.constants.UIConstants; +import com.fr.design.dialog.FineJOptionPane; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.gui.imenu.UIPopupMenu; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.share.group.ui.GroupFileDialog; +import com.fr.design.mainframe.share.sort.WidgetSortType; +import com.fr.design.mainframe.share.ui.base.PopupMenuItem; +import com.fr.design.mainframe.share.ui.widgetfilter.LocalWidgetFilter; +import com.fr.design.mainframe.share.util.ShareUIUtils; +import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.form.share.SharableWidgetProvider; +import com.fr.form.share.group.DefaultShareGroupManager; +import com.fr.form.share.Group; +import com.fr.general.IOUtils; +import com.fr.stable.StringUtils; + +import javax.swing.Action; +import javax.swing.BorderFactory; +import javax.swing.Icon; +import javax.swing.JPanel; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.event.ActionEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.ArrayList; +import java.util.List; + +/** + * @Author: Yuan.Wang + * @Date: 2020/11/5 + */ +class GroupPane extends JPanel { + private static final Icon downIcon = IOUtils.readIcon("/com/fr/base/images/share/arrow_down.png"); + private static final Icon rightIcon = IOUtils.readIcon("/com/fr/base/images/share/arrow_right.png"); + private static final int DEFAULT_HEIGHT = 24; + private final Group group; + private LocalWidgetSelectPane contentPanel; + private UIHeaderPane headerPanel; + private final int headHeight; + //是否展开 + private boolean expendStatus; + private SharableWidgetProvider[] elCaseBindInfoList; + + private GroupPane(Group group) { + this(group, DEFAULT_HEIGHT, group.isDefaultExpend()); + } + + private GroupPane(Group group, boolean expendStatus) { + this(group, DEFAULT_HEIGHT, expendStatus); + } + + private GroupPane(Group group, int headHeight, boolean expendStatus) { + this.group = group; + this.headHeight = headHeight; + this.expendStatus = expendStatus; + initComponents(); + } + + public boolean isComponentEditable() { + return LocalWidgetRepoPane.getInstance().isEditable(); + } + + private void initComponents() { + this.setLayout(new BorderLayout()); + this.setOpaque(false); + + headerPanel = new UIHeaderPane(group.getGroupName(), headHeight); + JPanel head = new JPanel(new BorderLayout()); + head.add(headerPanel, BorderLayout.NORTH); + head.setPreferredSize(new Dimension(240, 24)); + this.add(head, BorderLayout.NORTH); + refreshShowPanel(); + } + + public void refreshShowPanel() { + this.setVisible(true); + refreshBindInfoList(); + + //按照筛选条件进行过滤 + elCaseBindInfoList = LocalWidgetFilter.getInstance().filter(elCaseBindInfoList); + boolean needExpendGroup = expendStatus || (isFiltering() && elCaseBindInfoList.length > 0); + if (elCaseBindInfoList.length == 0 && isFiltering()) { + this.setVisible(false); + } + + //刷新面板的时候可能还有查询条件,如果有的话走一遍查询的逻辑 + String keyWord = LocalWidgetRepoPane.getInstance().getKeyWord4Searching(); + if (StringUtils.isNotEmpty(keyWord)) { + searchByKeyword(keyWord); + return; + } + reCreateShowPane(elCaseBindInfoList); + expendGroup(needExpendGroup); + } + + public void reCreateShowPane(SharableWidgetProvider[] widgets) { + if (contentPanel != null) { + contentPanel.hidePreviewPane(); + GroupPane.this.remove(contentPanel); + } + contentPanel = new LocalWidgetSelectPane(group, widgets, isComponentEditable()); + GroupPane.this.add(contentPanel, BorderLayout.CENTER); + headerPanel.setMenuItemVisible(!isComponentEditable()); + validate(); + repaint(); + revalidate(); + } + + private void expendGroup(boolean expendStatus) { + headerPanel.showExpand(expendStatus); + contentPanel.setVisible(expendStatus); + } + + protected void setExpendStatus(boolean expendStatus) { + //在筛选或者搜索状态,调用这个方法直接返回 + if (isFiltering() || isSearching()) { + return; + } + this.expendStatus = expendStatus; + } + + public SharableWidgetProvider[] getAllBindInfoList() { + SharableWidgetProvider[] widgetProviders = group.getAllBindInfoList(); + if (widgetProviders == null) { + widgetProviders = new SharableWidgetProvider[0]; + } + WidgetSortType.INSTALL_TIME.sort(widgetProviders); + return widgetProviders; + } + + public void sortWidget(WidgetSortType sortType) { + sortType.sort(elCaseBindInfoList); + reCreateShowPane(elCaseBindInfoList); + } + + public void searchByKeyword(String text) { + this.setVisible(true); + SharableWidgetProvider[] sharableWidgetArr = elCaseBindInfoList; + List widgets = new ArrayList<>(); + if (StringUtils.isNotEmpty(text)) { + for (SharableWidgetProvider provider : elCaseBindInfoList) { + if (provider.getName().toLowerCase().contains(text)) { + widgets.add(provider); + } + } + sharableWidgetArr = widgets.toArray(new SharableWidgetProvider[widgets.size()]); + } + + boolean needExpendGroup = expendStatus || (isSearching() && sharableWidgetArr.length > 0); + if (isSearching() && sharableWidgetArr.length == 0) { + setVisible(false); + } + reCreateShowPane(sharableWidgetArr); + expendGroup(needExpendGroup); + } + + public void refreshBindInfoList() { + elCaseBindInfoList = getAllBindInfoList(); + } + + private boolean isFiltering() { + return LocalWidgetRepoPane.getInstance().isFiltering(); + } + + private boolean isSearching() { + return LocalWidgetRepoPane.getInstance().isSearching(); + } + + private class UIHeaderPane extends JPanel { + private static final long serialVersionUID = 1L; + + private final UILabel arrow; + private final UILabel menuItem; + private final UILabel titleLabel; + private final int headHeight; + private boolean pressed; + private boolean hover; + + private final MouseAdapter mouseAdapter = new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + if (e.getButton() == MouseEvent.BUTTON3 && group.isEditable() && !GroupPane.this.isComponentEditable()) { + UIPopupMenu popupMenu = new UIPopupMenu(); + popupMenu.setOnlyText(true); + popupMenu.setBackground(UIConstants.DEFAULT_BG_RULER); + popupMenu.add(new PopupMenuItem(new RenameAction())); + popupMenu.add(new PopupMenuItem(new RemoveAction())); + + GUICoreUtils.showPopupMenu(popupMenu, UIHeaderPane.this, e.getX(), e.getY()); + } + } + + @Override + public void mousePressed(MouseEvent e) { + pressed = true; + } + + @Override + public void mouseReleased(MouseEvent e) { + if (pressed && hover) { + dealClickAction(e); + } + pressed = false; + } + + @Override + public void mouseEntered(MouseEvent e) { + hover = true; + } + + @Override + public void mouseExited(MouseEvent e) { + hover = false; + } + }; + + public UIHeaderPane(String title, int headHeight) { + this.setLayout(new BorderLayout()); + this.setBorder(BorderFactory.createEmptyBorder(0, 10, 1, 2)); + JPanel panel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + panel.setBackground(Color.decode("#EDEDEE")); + this.headHeight = headHeight; + arrow = new UILabel(downIcon); + arrow.setOpaque(false); + menuItem = createMenuItem(); + titleLabel = new UILabel(title); + titleLabel.setOpaque(false); + + JPanel leftPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); + leftPanel.add(arrow); + leftPanel.add(titleLabel); + leftPanel.setOpaque(false); + + panel.add(leftPanel, BorderLayout.CENTER); + + if (group.isEditable()) { + panel.add(menuItem, BorderLayout.EAST); + } + add(panel, BorderLayout.CENTER); + addListener(); + } + + public void showExpand(boolean expend) { + Icon showIcon = expend ? downIcon : rightIcon; + arrow.setIcon(showIcon); + } + + @Override + public Dimension getPreferredSize() { + return new Dimension(this.getWidth(), headHeight); + } + + @Override + public Dimension getSize() { + return new Dimension(this.getWidth(), headHeight); + } + + public UILabel createMenuItem() { + UILabel label = new UILabel(IOUtils.readIcon("/com/fr/base/images/share/menu_item.png")); + label.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + UIPopupMenu popupMenu = new UIPopupMenu(); + popupMenu.setOnlyText(true); + popupMenu.setBackground(UIConstants.DEFAULT_BG_RULER); + popupMenu.add(new PopupMenuItem(new RenameAction())); + popupMenu.add(new PopupMenuItem(new RemoveAction())); + + GUICoreUtils.showPopupMenu(popupMenu, menuItem, 0, menuItem.getSize().height); + } + }); + label.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5)); + label.setOpaque(false); + return label; + } + + protected void setMenuItemVisible(boolean visible) { + menuItem.setVisible(visible); + } + + private void addListener() { + this.addMouseListener(mouseAdapter); + } + + /** + * 由鼠标释放时调用该方法来触发左键点击事件 + */ + private void dealClickAction(MouseEvent e) { + if (e.getButton() == MouseEvent.BUTTON1) { + boolean isShow = contentPanel.isShowing(); + contentPanel.setVisible(!isShow); + GroupPane.this.setExpendStatus(!isShow); + showExpand(!isShow); + + getParent().validate(); + getParent().repaint(); + } + } + + private class RenameAction extends UpdateAction { + public RenameAction() { + this.putValue(Action.SMALL_ICON, null); + this.setName(Toolkit.i18nText("Fine-Design_Share_Group_Rename")); + } + + @Override + public void actionPerformed(ActionEvent e) { + new GroupFileDialog(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Design_Share_Group_Rename", group.getGroupName())) { + @Override + protected void confirmClose() { + this.dispose(); + String groupName = getFileName().replaceAll("[\\\\/:*?\"<>|]", StringUtils.EMPTY); + if (DefaultShareGroupManager.getInstance().renameGroup(group, groupName)) { + titleLabel.setText(groupName); + repaint(); + } else { + ShareUIUtils.showErrorMessageDialog(Toolkit.i18nText("Fine-Design_Share_Group_Rename_Failure")); + } + } + + @Override + protected boolean isDuplicate(String fileName) { + return DefaultShareGroupManager.getInstance().exist(fileName); + } + }; + + } + } + + private class RemoveAction extends UpdateAction { + public RemoveAction() { + this.putValue(Action.SMALL_ICON, null); + this.setName(Toolkit.i18nText("Fine-Design_Share_Group_Remove")); + } + + @Override + public void actionPerformed(ActionEvent e) { + int rv = FineJOptionPane.showConfirmDialog( + DesignerContext.getDesignerFrame(), + Toolkit.i18nText("Fine-Design_Share_Group_Remove_Info"), + Toolkit.i18nText("Fine-Design_Share_Group_Confirm"), + FineJOptionPane.YES_NO_OPTION + ); + if (rv == FineJOptionPane.YES_OPTION) { + if (DefaultShareGroupManager.getInstance().removeGroup(group)) { + LocalWidgetRepoPane.getInstance().removeGroup(group.getGroupName()); + } else { + ShareUIUtils.showErrorMessageDialog(Toolkit.i18nText("Fine-Design_Share_Group_Remove_Failure")); + } + } + } + } + } + + public enum GroupCreateStrategy { + DEFAULT { + @Override + public GroupPane creteGroupPane(Group group) { + return new GroupPane(group); + } + }, + CLOSURE { + @Override + public GroupPane creteGroupPane(Group group) { + return new GroupPane(group, false); + } + }; + + abstract public GroupPane creteGroupPane(Group group); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/LocalPaneStatus.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/LocalPaneStatus.java new file mode 100644 index 000000000..d56807245 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/LocalPaneStatus.java @@ -0,0 +1,87 @@ +package com.fr.design.mainframe.share.ui.local; + +import com.fr.base.BaseUtils; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.share.ui.base.LoadingPane; +import com.fr.design.mainframe.share.ui.base.NoMatchPane; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.SwingConstants; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; + +/** + * @Author: Yuan.Wang + * @Date: 2020/12/1 + */ +enum LocalPaneStatus { + + //无匹配 + NO_MATCH { + @Override + public JPanel getPanel() { + return new NoMatchPane(); + } + }, + + //正常 + NORMAL { + @Override + public JPanel getPanel() { + return new JPanel(); + } + }, + + //空 + EMPTY { + @Override + public JPanel getPanel() { + JPanel panel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + UILabel picLabel = new UILabel(); + picLabel.setIcon(BaseUtils.readIcon("com/fr/base/images/share/empty.png")); + picLabel.setHorizontalAlignment(SwingConstants.CENTER); + + panel.add(picLabel, BorderLayout.CENTER); + + JPanel labelPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + UILabel topLabel = new UILabel(Toolkit.i18nText("Fine-Design_Share_Empty_First"), SwingConstants.CENTER); + topLabel.setForeground(Color.GRAY); + UILabel bottomLabel = new UILabel(Toolkit.i18nText("Fine-Design_Share_Empty_Second"), SwingConstants.CENTER); + bottomLabel.setForeground(Color.GRAY); + labelPanel.add(topLabel, BorderLayout.CENTER); + labelPanel.add(bottomLabel, BorderLayout.SOUTH); + labelPanel.setPreferredSize(new Dimension(240, 40)); + panel.add(labelPanel, BorderLayout.SOUTH); + + panel.setPreferredSize(new Dimension(240, 180)); + + + JPanel emptyPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + emptyPanel.setBorder(BorderFactory.createEmptyBorder(100, 0, 0, 0)); + emptyPanel.add(panel, BorderLayout.NORTH); + return emptyPanel; + } + }, + + //加载 + LOADING { + @Override + public JPanel getPanel() { + return new LoadingPane(); + } + }, + + //安装 + INSTALLING { + @Override + public JPanel getPanel() { + return new LoadingPane(Toolkit.i18nText("Fine-Design_Share_installing")); + } + }; + + public abstract JPanel getPanel(); +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/LocalWidgetRepoPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/LocalWidgetRepoPane.java new file mode 100644 index 000000000..487a414e5 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/LocalWidgetRepoPane.java @@ -0,0 +1,266 @@ +package com.fr.design.mainframe.share.ui.local; + +import com.fr.design.dialog.BasicPane; +import com.fr.design.gui.icontainer.UIScrollPane; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.layout.VerticalFlowLayout; +import com.fr.design.mainframe.share.sort.WidgetSortType; +import com.fr.design.mainframe.share.ui.widgetfilter.LocalWidgetFilter; +import com.fr.design.mainframe.share.util.InstallComponentHelper; +import com.fr.design.mainframe.share.util.ShareComponentUtils; +import com.fr.form.share.group.DefaultShareGroupManager; +import com.fr.form.share.Group; +import com.fr.log.FineLoggerFactory; +import com.fr.stable.StringUtils; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.SwingWorker; +import java.awt.BorderLayout; +import java.awt.CardLayout; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * Created by kerry on 2020-10-16 + */ +public class LocalWidgetRepoPane extends BasicPane { + + private JPanel centerPane; + private UIScrollPane groupsScrollPane; + private JPanel groupsPane; + private ManagePane managePane; + + private final Map groupPaneMap = new HashMap<>(); + private final AtomicBoolean isRefreshing = new AtomicBoolean(false); + private boolean editable; + private CardLayout cardLayout; + private String keyWord4Searching = StringUtils.EMPTY; + + private LocalWidgetRepoPane() { + setLayout(FRGUIPaneFactory.createBorderLayout()); + initPane(); + } + + public static LocalWidgetRepoPane getInstance() { + return HOLDER.singleton; + } + + private static class HOLDER { + private static final LocalWidgetRepoPane singleton = new LocalWidgetRepoPane(); + } + + public boolean isEditable() { + return editable; + } + + public String getKeyWord4Searching() { + return keyWord4Searching; + } + + /** + * 初始化 + */ + public void initPane() { + //新用户预装组件 + InstallComponentHelper.installPreComponent(); + JPanel componentLibPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + componentLibPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 15, 0)); + + ToolbarPane toolbarPane = new ToolbarPane(); + managePane = new ManagePane(); + + JPanel northPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + northPane.add(toolbarPane, BorderLayout.NORTH); + northPane.add(managePane, BorderLayout.CENTER); + + cardLayout = new CardLayout(); + centerPane = new JPanel(cardLayout); + centerPane.add(LocalPaneStatus.NO_MATCH.getPanel(), LocalPaneStatus.NO_MATCH.name()); + centerPane.add(LocalPaneStatus.EMPTY.getPanel(), LocalPaneStatus.EMPTY.name()); + centerPane.add(LocalPaneStatus.LOADING.getPanel(), LocalPaneStatus.LOADING.name()); + centerPane.add(LocalPaneStatus.INSTALLING.getPanel(), LocalPaneStatus.INSTALLING.name()); + + componentLibPanel.add(northPane, BorderLayout.NORTH); + componentLibPanel.add(centerPane, BorderLayout.CENTER); + add(componentLibPanel, BorderLayout.CENTER); + cardLayout.show(centerPane, LocalPaneStatus.LOADING.name()); + toolbarPane.addFilterPopupStateChangeListener(state -> setWidgetPaneScrollEnable(!state)); + + doRefresh(); + } + + public void refreshAllGroupPane() { + refreshAllGroupPane(GroupPane.GroupCreateStrategy.DEFAULT); + } + + public void refreshAllGroupPane(GroupPane.GroupCreateStrategy createStrategy) { + editable = false; + groupPaneMap.clear(); + if (groupsScrollPane != null) { + centerPane.remove(groupsScrollPane); + } + groupsPane = FRGUIPaneFactory.createVerticalFlowLayout_Pane(false, VerticalFlowLayout.TOP, 0, 5); + + Group[] groups = DefaultShareGroupManager.getInstance().getAllGroup(); + for (Group group : groups) { + GroupPane groupPane = createStrategy.creteGroupPane(group); + groupPaneMap.put(group.getGroupName(), groupPane); + groupsPane.add(groupPane, BorderLayout.NORTH); + } + groupsScrollPane = new UIScrollPane(groupsPane); + groupsScrollPane.setBorder(null); + groupsScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); + + centerPane.add(groupsScrollPane, LocalPaneStatus.NORMAL.name()); + switchPane(); + } + + public void refreshPane() { + managePane.switchPanel(false); + switchPane(LocalPaneStatus.LOADING); + doRefresh(); + } + + public void switch2InstallingPane() { + switchPane(LocalPaneStatus.INSTALLING); + } + + public void refreshShowPanel(boolean isEdit) { + this.editable = isEdit; + refreshShowPanel(); + } + + public void refreshShowPanel() { + for (GroupPane groupPane : groupPaneMap.values()) { + groupPane.refreshShowPanel(); + } + switchPane(); + } + + public void refreshShowPanel(Group group) { + if (groupPaneMap.containsKey(group.getGroupName())) { + groupPaneMap.get(group.getGroupName()).refreshShowPanel(); + } + switchPane(); + } + + public void setWidgetPaneScrollEnable(boolean enable) { + groupsScrollPane.setWheelScrollingEnabled(enable); + } + + public void setManageButtonEnable(boolean enable) { + managePane.setButtonEnable(enable); + } + + public void removeGroup(String groupName) { + JPanel jPanel = groupPaneMap.remove(groupName); + groupsPane.remove(jPanel); + switchPane(); + } + + public void addGroup(Group group) { + GroupPane groupPane = GroupPane.GroupCreateStrategy.DEFAULT.creteGroupPane(group); + groupPaneMap.put(group.getGroupName(), groupPane); + groupsPane.add(groupPane); + switchPane(); + } + + public void searchByKeyword(String text) { + keyWord4Searching = text; + for (GroupPane groupPane : groupPaneMap.values()) { + groupPane.searchByKeyword(text); + } + switchPane(); + } + + public void sortWidget(WidgetSortType sortType) { + for (GroupPane groupPane : groupPaneMap.values()) { + groupPane.sortWidget(sortType); + } + } + + + private void doRefresh() { + if (isRefreshing.get()) { + return; + } + new SwingWorker() { + @Override + protected Boolean doInBackground() throws Exception { + if (isRefreshing.compareAndSet(false, true)) { + boolean isRefresh = DefaultShareGroupManager.getInstance().refresh(); + if (isRefresh) { + ShareComponentUtils.checkReadMe(); + } + return isRefresh; + } + return false; + } + + @Override + public void done() { + try { + if (get()) { + refreshAllGroupPane(); + } + } catch (InterruptedException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + Thread.currentThread().interrupt(); + } catch (ExecutionException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } finally { + isRefreshing.set(false); + } + } + }.execute(); + } + + /** + * 切换为要显示的面板 + */ + private void switchPane() { + switchPane(getStatus()); + } + + private void switchPane(LocalPaneStatus status) { + cardLayout.show(centerPane, status.name()); + centerPane.validate(); + centerPane.repaint(); + } + + private LocalPaneStatus getStatus() { + return isEmpty() ? LocalPaneStatus.EMPTY : isNoMatch() ? LocalPaneStatus.NO_MATCH : LocalPaneStatus.NORMAL; + } + + public boolean isFiltering() { + return LocalWidgetFilter.getInstance().hasFilter(); + } + + public boolean isSearching() { + return StringUtils.isNotEmpty(keyWord4Searching); + } + + private boolean isNoMatch() { + for (GroupPane groupPane : groupPaneMap.values()) { + if (groupPane.isVisible()) { + return false; + } + } + return true; + } + + private boolean isEmpty() { + Group[] groups = DefaultShareGroupManager.getInstance().getAllGroup(); + return groups.length == 1 && groups[0].getAllBindInfoList().length == 0; + } + + @Override + protected String title4PopupWindow() { + return Toolkit.i18nText("Fine-Design_Share_Local_Widget"); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/LocalWidgetSelectPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/LocalWidgetSelectPane.java new file mode 100644 index 000000000..8c6a9a6c3 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/LocalWidgetSelectPane.java @@ -0,0 +1,113 @@ +package com.fr.design.mainframe.share.ui.local; + +import com.fr.design.mainframe.share.AbstractWidgetSelectPane; +import com.fr.design.mainframe.share.ui.block.LocalWidgetBlock; +import com.fr.form.share.DefaultSharableWidget; +import com.fr.form.share.SharableWidgetProvider; +import com.fr.form.share.constants.ShareComponentConstants; +import com.fr.form.share.Group; +import com.fr.form.share.record.ShareWidgetInfoManager; +import com.fr.general.ComparatorUtils; +import com.fr.stable.ArrayUtils; + +import javax.swing.BorderFactory; +import java.awt.AWTEvent; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Point; +import java.awt.event.AWTEventListener; +import java.awt.event.MouseEvent; + +/** + * created by Harrison on 2020/03/23 + **/ +public class LocalWidgetSelectPane extends AbstractWidgetSelectPane { + private LocalWidgetBlock selectedBlock; + private final Group group; + + public LocalWidgetSelectPane(Group group, SharableWidgetProvider[] providers, boolean isEdit) { + this.group = group; + // 表示Popup弹窗是否能被点击到 + AWTEventListener awtEventListener = new AWTEventListener() { + @Override + public void eventDispatched(AWTEvent event) { + if (event instanceof MouseEvent) { + MouseEvent mv = (MouseEvent) event; + if (isCanCancelSelect(mv, selectedBlock)) { + LocalWidgetSelectPane.this.selectedBlock = null; + LocalWidgetSelectPane.this.repaint(); + } + } + + } + + private boolean isCanCancelSelect(MouseEvent mv, LocalWidgetBlock selectedBlock) { + if (mv.getClickCount() < 1) { + return false; + } + // 表示Popup弹窗是否能被点击到 + boolean clickFlag = false; + if (selectedBlock != null) { + if (!selectedBlock.isShowing()) { + return false; + } + Point p = selectedBlock.getLocationOnScreen(); + Point clickPoint = mv.getLocationOnScreen(); + clickFlag = clickPoint.getX() >= p.getX() + && clickPoint.getY() >= p.getY() + && clickPoint.getX() <= selectedBlock.getWidth() + p.getX() + && clickPoint.getY() <= p.getY() + selectedBlock.getHeight(); + + } + return selectedBlock != null && !clickFlag && !ComparatorUtils.equals(mv.getSource(), selectedBlock); + } + }; + + java.awt.Toolkit.getDefaultToolkit().addAWTEventListener(awtEventListener, AWTEvent.MOUSE_EVENT_MASK); + + // 设置面板的边框 ,距离上、左、下、右 的距离 + this.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0)); + if (ArrayUtils.isNotEmpty(providers)) { + showComponent(providers, isEdit); + } else { + showEmpty(); + } + ShareWidgetInfoManager.getInstance().checkInstallCompInfo(providers); + } + + public Group getGroup() { + return group; + } + + private void showComponent(SharableWidgetProvider[] providers, boolean isEdit) { + + int rowCount = (providers.length + 1) / 2; + int vgap = 10; + this.setLayout(new FlowLayout(FlowLayout.LEFT, 5, vgap)); + for (SharableWidgetProvider provider : providers) { + LocalWidgetBlock widgetButton = new LocalWidgetBlock((DefaultSharableWidget) provider, this); + widgetButton.setElementCaseEdit(isEdit); + this.add(widgetButton); + } + this.setPreferredSize(new Dimension(240, rowCount * (ShareComponentConstants.SHARE_BLOCK_HEIGHT + vgap))); + } + + private void showEmpty() { + this.setPreferredSize(new Dimension(240, 0)); + } + + public void setSelectBlock(LocalWidgetBlock block) { + this.selectedBlock = block; + this.repaint(); + } + + public LocalWidgetBlock getSelectedBlock() { + return selectedBlock; + } + + @Override + protected Container getParentContainer() { + return this.getParent().getParent(); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/ManagePane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/ManagePane.java new file mode 100644 index 000000000..67e2efe3f --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/ManagePane.java @@ -0,0 +1,245 @@ +package com.fr.design.mainframe.share.ui.local; + +import com.fr.design.constants.UIConstants; +import com.fr.design.dialog.FineJOptionPane; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.imenu.UIPopupMenu; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.share.action.CreateComponentAction; +import com.fr.design.mainframe.share.action.InstallComponentAction; +import com.fr.design.mainframe.share.action.ShareUIAspect; +import com.fr.design.mainframe.share.group.ui.GroupFileDialog; +import com.fr.design.mainframe.share.group.ui.GroupMoveDialog; +import com.fr.design.mainframe.share.ui.base.PopupMenuItem; +import com.fr.design.mainframe.share.util.ShareUIUtils; +import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.form.share.group.DefaultShareGroupManager; +import com.fr.form.share.Group; +import com.fr.general.IOUtils; +import com.fr.stable.StringUtils; + +import javax.swing.BorderFactory; +import javax.swing.Icon; +import javax.swing.JPanel; +import javax.swing.SwingConstants; +import java.awt.BorderLayout; +import java.awt.CardLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.event.ActionListener; + +/** + * @Author: Yuan.Wang + * @Date: 2020/10/29 + */ +class ManagePane extends JPanel implements ShareUIAspect { + private static final String NORMAL = "NORMAL"; + private static final String MANAGE = "MANAGE"; + private final UIButton addComponentButton; + + UIButton deleteSelectedButton; + UIButton moveGroupButton; + CardLayout cardLayout; + + public ManagePane() { + //添加组件 + addComponentButton = createAddComponentButton(); + //管理组件 + UIButton manageButton = createManageButton(); + //添加分组 + UIButton addGroupButton = createAddGroupButton(); + //删除选中 + deleteSelectedButton = createDeleteSelectedButton(); + //移动分组 + moveGroupButton = createMoveGroupButton(); + //取消 + UIButton cancelButton = createCancelButton(); + + deleteSelectedButton.setEnabled(false); + moveGroupButton.setEnabled(false); + + JPanel leftPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); + leftPanel.add(addComponentButton); + + JPanel rightPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); + rightPanel.add(manageButton); + rightPanel.add(addGroupButton); + + JPanel normalPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + normalPanel.add(leftPanel, BorderLayout.CENTER); + normalPanel.add(rightPanel, BorderLayout.EAST); + + JPanel managePanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 10, 5)); + managePanel.add(deleteSelectedButton); + managePanel.add(moveGroupButton); + managePanel.add(cancelButton); + + cardLayout = new CardLayout(); + this.setLayout(cardLayout); + this.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5)); + this.add(normalPanel, NORMAL); + this.add(managePanel, MANAGE); + } + + public void setButtonEnable(boolean enable) { + if (moveGroupButton.isEnabled() != enable) { + deleteSelectedButton.setEnabled(enable); + moveGroupButton.setEnabled(enable); + } + } + + /** + * 添加组件按钮 + */ + private UIButton createAddComponentButton() { + return createManageButton( + Toolkit.i18nText("Fine-Design_Share_Add"), + IOUtils.readIcon("/com/fr/base/images/share/filter_combo.png"), + e -> { + //创建组件和安装组件的弹窗 + UIPopupMenu popupMenu = new UIPopupMenu(); + popupMenu.setPreferredSize(new Dimension(74, 42)); + popupMenu.setOnlyText(true); + popupMenu.setBackground(UIConstants.DEFAULT_BG_RULER); + popupMenu.add(new PopupMenuItem(new CreateComponentAction(this))); + popupMenu.add(new PopupMenuItem(new InstallComponentAction())); + GUICoreUtils.showPopupMenu(popupMenu, addComponentButton, 0, addComponentButton.getSize().height); + } + ); + } + + /** + * 管理组件面板 + */ + private UIButton createManageButton() { + return createManageButton( + Toolkit.i18nText("Fine-Design_Share_Manage"), + e -> replacePanel(true) + ); + } + + /** + * 添加分组面板 + */ + private UIButton createAddGroupButton() { + return createManageButton( + Toolkit.i18nText("Fine-Design_Share_Group_Add"), + e -> new GroupFileDialog(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Design_Share_Group_Add")) { + @Override + protected void confirmClose() { + this.dispose(); + // 处理不合法的文件夹名称 + String userInput = getFileName().replaceAll("[\\\\/:*?\"<>|]", StringUtils.EMPTY); + //新建分组,刷新显示 + if (DefaultShareGroupManager.getInstance().createGroup(userInput)) { + LocalWidgetRepoPane.getInstance().refreshAllGroupPane(GroupPane.GroupCreateStrategy.CLOSURE); + } else { + ShareUIUtils.showErrorMessageDialog(Toolkit.i18nText("Fine-Design_Basic_Make_Failure")); + } + } + + @Override + protected boolean isDuplicate(String fileName) { + return DefaultShareGroupManager.getInstance().exist(fileName); + } + } + ); + } + + private UIButton createCancelButton() { + return createManageButton( + Toolkit.i18nText("Fine-Design_Share_Group_Cancel"), + e -> replacePanel(false) + ); + } + + /** + * 切换面板并刷新 + */ + public void replacePanel(boolean isEditing) { + switchPanel(isEditing); + LocalWidgetRepoPane.getInstance().refreshShowPanel(isEditing); + } + + /** + * 切换面板 + * + * @param isEditing 是否编辑 + */ + public void switchPanel(boolean isEditing) { + setButtonEnable(false); + WidgetSelectedManager.getInstance().clearSelect(); + cardLayout.show(this, isEditing ? MANAGE : NORMAL); + } + + private UIButton createDeleteSelectedButton() { + return createManageButton( + Toolkit.i18nText("Fine-Design_Share_Select_Remove"), + new Color(0xeb1d1f), + e -> { + int rv = FineJOptionPane.showConfirmDialog( + DesignerContext.getDesignerFrame(), + Toolkit.i18nText("Fine-Design_Share_Remove_Info"), + Toolkit.i18nText("Fine-Design_Share_Group_Confirm"), + FineJOptionPane.YES_NO_OPTION + ); + if (rv == FineJOptionPane.YES_OPTION) { + if (WidgetSelectedManager.getInstance().unInstallSelect()) { + //刷新界面的缓存 + FineJOptionPane.showMessageDialog(null, Toolkit.i18nText("Fine-Design_Form_Share_Module_Removed_Successful")); + replacePanel(false); + } else { + ShareUIUtils.showErrorMessageDialog(Toolkit.i18nText("Fine-Design_Form_Share_Module_Removed_Failed")); + } + } + }); + } + + private UIButton createMoveGroupButton() { + return createManageButton( + Toolkit.i18nText("Fine-Design_Share_Group_Move"), + e -> new GroupMoveDialog(DesignerContext.getDesignerFrame()) { + @Override + protected void confirmClose() { + this.dispose(); + Group group = (Group) getSelectGroupBox().getSelectedItem(); + assert group != null; + if (WidgetSelectedManager.getInstance().moveSelect(group.getGroupName())) { + replacePanel(false); + } else { + LocalWidgetRepoPane.getInstance().refreshShowPanel(); + ShareUIUtils.showErrorMessageDialog(Toolkit.i18nText("Fine-Design_Share_Group_Move_Fail_Message")); + } + } + + } + ); + } + + private UIButton createManageButton(String title, Icon icon, ActionListener actionListener) { + UIButton button = createManageButton(title, actionListener); + button.setIcon(icon); + button.setHorizontalTextPosition(SwingConstants.LEFT); + return button; + } + + private UIButton createManageButton(String title, ActionListener actionListener) { + return createManageButton(title, new Color(0x333334), actionListener); + } + + private UIButton createManageButton(String title, Color foregroundColor, ActionListener actionListener) { + UIButton button = new UIButton(title); + button.setBackground(Color.white); + button.setForeground(foregroundColor); + button.addActionListener(actionListener); + return button; + } + + @Override + public void afterOk() { + LocalWidgetRepoPane.getInstance().refreshShowPanel(false); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/ToolbarPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/ToolbarPane.java new file mode 100644 index 000000000..4a32b149e --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/ToolbarPane.java @@ -0,0 +1,226 @@ +package com.fr.design.mainframe.share.ui.local; + +import com.fr.base.BaseUtils; +import com.fr.design.actions.UpdateAction; +import com.fr.design.constants.UIConstants; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.gui.imenu.UIPopupMenu; +import com.fr.design.gui.itextfield.UITextField; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.share.sort.WidgetSortType; +import com.fr.design.mainframe.share.ui.base.MouseClickListener; +import com.fr.design.mainframe.share.ui.base.SortPopupMenuItem; +import com.fr.design.mainframe.share.ui.widgetfilter.FilterPane; +import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.general.IOUtils; +import com.fr.stable.StringUtils; + +import javax.swing.Action; +import javax.swing.BorderFactory; +import javax.swing.Icon; +import javax.swing.JPanel; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import java.awt.BorderLayout; +import java.awt.CardLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.MouseEvent; + +/** + * @Author: Yuan.Wang + * @Date: 2020/10/29 + */ +class ToolbarPane extends JPanel { + private static final Color SEARCH_BORDER_COLOR = Color.decode("#F5F5F7"); + private static final Color SEARCH_BORDER_INPUT_COLOR = Color.decode("#419BF9"); + + private static final String NORMAL = "NORMAL"; + private static final String SEARCH = "SEARCH"; + + private UITextField searchTextField; + private final JPanel centerPane; + + //查询按钮 + private final UIButton searchButton; + //排序按钮 + private final UIButton sortButton; + //刷新按钮 + private final UIButton refreshButton; + + private final CardLayout cardLayout; + + private FilterPane filterPanel; + + public ToolbarPane() { + cardLayout = new CardLayout(); + centerPane = new JPanel(cardLayout); + + searchButton = createSearchButton(); + sortButton = createSortButton(); + refreshButton = createRefreshButton(); + filterPanel = createFilterPane(); + JPanel normalPanel = createNormalPanel(); + JPanel searchPanel = createSearchField(); + centerPane.add(normalPanel, NORMAL); + centerPane.add(searchPanel, SEARCH); + this.add(centerPane, BorderLayout.CENTER); + } + + public void addFilterPopupStateChangeListener(FilterPane.PopStateChangeListener listener) { + filterPanel.addPopupStateChangeListener(listener); + } + + private UIButton createSearchButton() { + return createToolButton( + IOUtils.readIcon("/com/fr/base/images/share/search_icon.png"), + Toolkit.i18nText("Fine-Design_Share_Search"), + e -> { + cardLayout.show(centerPane, SEARCH); + searchTextField.requestFocus(); + } + ); + } + + private UIButton createSortButton() { + return createToolButton( + IOUtils.readIcon("/com/fr/base/images/share/sort_icon.png"), + Toolkit.i18nText("Fine-Design_Share_Sort"), + e -> { + UIPopupMenu popupMenu = new UIPopupMenu(); + popupMenu.setOnlyText(true); + popupMenu.setBackground(UIConstants.DEFAULT_BG_RULER); + popupMenu.add(new SortPopupMenuItem(new SortAction(WidgetSortType.INSTALL_TIME))); + popupMenu.add(new SortPopupMenuItem(new SortAction(WidgetSortType.COMPONENT_NAME))); + + GUICoreUtils.showPopupMenu(popupMenu, sortButton, 0, sortButton.getSize().height); + } + ); + } + + private UIButton createRefreshButton() { + return createToolButton( + IOUtils.readIcon("/com/fr/base/images/share/refresh.png"), + Toolkit.i18nText("Fine-Design_Basic_Refresh"), + e -> { + filterPanel.reset(); + LocalWidgetRepoPane.getInstance().refreshPane(); + } + ); + } + + private FilterPane createFilterPane() { + filterPanel = FilterPane.createLocalFilterPane(); + filterPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 10)); + filterPanel.registerChangeListerner(e -> LocalWidgetRepoPane.getInstance().refreshShowPanel()); + return filterPanel; + } + + private JPanel createNormalPanel() { + JPanel panel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + JPanel buttonPane = new JPanel(new FlowLayout(FlowLayout.RIGHT, 0, 0)); + buttonPane.add(searchButton); + buttonPane.add(sortButton); + buttonPane.add(refreshButton); + panel.add(filterPanel, BorderLayout.CENTER); + panel.add(buttonPane, BorderLayout.EAST); + return panel; + } + + private JPanel createSearchField() { + final JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + jPanel.setPreferredSize(new Dimension(228, 10)); + jPanel.setBorder(BorderFactory.createLineBorder(SEARCH_BORDER_COLOR)); + jPanel.setBackground(Color.WHITE); + UILabel label = new UILabel(IOUtils.readIcon("/com/fr/base/images/share/search_icon.png")); + label.setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 0)); + jPanel.add(label, BorderLayout.WEST); + this.searchTextField = new UITextField(); + this.searchTextField.setBorderPainted(false); + this.searchTextField.setPlaceholder(Toolkit.i18nText("Fine-Design_Basic_Plugin_Search")); + this.searchTextField.addFocusListener(new FocusListener() { + @Override + public void focusGained(FocusEvent e) { + jPanel.setBorder(BorderFactory.createLineBorder(SEARCH_BORDER_INPUT_COLOR)); + jPanel.repaint(); + } + + @Override + public void focusLost(FocusEvent e) { + jPanel.setBorder(BorderFactory.createLineBorder(SEARCH_BORDER_COLOR)); + jPanel.repaint(); + } + }); + this.searchTextField.getDocument().addDocumentListener(new DocumentListener() { + @Override + public void insertUpdate(DocumentEvent e) { + filterByName(); + } + + @Override + public void removeUpdate(DocumentEvent e) { + filterByName(); + } + + @Override + public void changedUpdate(DocumentEvent e) { + filterByName(); + } + }); + jPanel.add(this.searchTextField, BorderLayout.CENTER); + UILabel xLabel = new UILabel(BaseUtils.readIcon("/com/fr/design/images/buttonicon/close_icon.png")); + xLabel.addMouseListener(new MouseClickListener() { + @Override + public void mouseClicked(MouseEvent e) { + searchTextField.setText(StringUtils.EMPTY); + cardLayout.show(centerPane, NORMAL); + } + }); + xLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); + jPanel.add(xLabel, BorderLayout.EAST); + + return jPanel; + } + + private void filterByName() { + String text = searchTextField.getText(); + boolean searchStatus = !StringUtils.isEmpty(text); + sortButton.setEnabled(!searchStatus); + LocalWidgetRepoPane.getInstance().searchByKeyword(text); + } + + private static class SortAction extends UpdateAction { + private final WidgetSortType sortType; + + public SortAction(WidgetSortType sortType) { + this.putValue(Action.SMALL_ICON, null); + this.setName(sortType.getDisplayName()); + this.sortType = sortType; + } + + @Override + public void actionPerformed(ActionEvent e) { + LocalWidgetRepoPane.getInstance().sortWidget(sortType); + } + } + + /** + * 创建工具条按钮 + */ + private UIButton createToolButton(Icon icon, String toolTip, ActionListener actionListener) { + UIButton toolButton = new UIButton(); + toolButton.setIcon(icon); + toolButton.setToolTipText(toolTip); + toolButton.set4ToolbarButton(); + toolButton.addActionListener(actionListener); + return toolButton; + } + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/WidgetSelectedManager.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/WidgetSelectedManager.java new file mode 100644 index 000000000..d211887f5 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/WidgetSelectedManager.java @@ -0,0 +1,121 @@ +package com.fr.design.mainframe.share.ui.local; + +import com.fr.form.share.group.DefaultShareGroupManager; +import com.fr.form.share.Group; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * @Author: Yuan.Wang + * @Date: 2021/1/15 + */ +public class WidgetSelectedManager { + private final Map> selectedWidgetMap = new HashMap<>(); + + private WidgetSelectedManager() { + + } + + private static class Holder { + private static final WidgetSelectedManager INSTANCE = new WidgetSelectedManager(); + } + + public static WidgetSelectedManager getInstance() { + return Holder.INSTANCE; + } + + /** + * 添加选中组件 + */ + public synchronized void addSelect(String groupName, String uuid) { + if (selectedWidgetMap.containsKey(groupName)) { + selectedWidgetMap.get(groupName).add(uuid); + } else { + selectedWidgetMap.put(groupName, Stream.of(uuid).collect(Collectors.toList())); + } + } + + /** + * 删除选中组件 + */ + public synchronized void removeSelect(String groupName, String uuid) { + if (selectedWidgetMap.containsKey(groupName)) { + selectedWidgetMap.get(groupName).remove(uuid); + } + } + + /** + * 卸载单个选中组件 + */ + public synchronized boolean unInstallSelect(String groupName, String uuid) { + Group group = DefaultShareGroupManager.getInstance().getGroup(groupName); + return group != null && group.unInstallSelect(Stream.of(uuid).collect(Collectors.toList())); + } + + /** + * 卸载所有选中组件 + */ + public synchronized boolean unInstallSelect() { + boolean result = true; + for (String groupName : selectedWidgetMap.keySet()) { + Group group = DefaultShareGroupManager.getInstance().getGroup(groupName); + result &= group != null && group.unInstallSelect(selectedWidgetMap.get(groupName)); + } + selectedWidgetMap.clear(); + return result; + } + + /** + * 是否选中某组件 + */ + public synchronized boolean isSelected(String groupName, String uuid) { + return selectedWidgetMap.containsKey(groupName) && selectedWidgetMap.get(groupName).contains(uuid); + } + + /** + * 清空选中组件 + */ + public synchronized void clearSelect() { + selectedWidgetMap.clear(); + } + + /** + * 被选中是否为空 + */ + public synchronized boolean isSelectEmpty() { + return selectedWidgetMap.isEmpty() || selectedWidgetMap.values().stream().noneMatch(list -> (list.size() > 0)); + } + + /** + * 移动所有选中到某分组 + */ + public synchronized boolean moveSelect(String toGroupName) { + boolean result = true; + Group toGroup = DefaultShareGroupManager.getInstance().getGroup(toGroupName); + if (toGroup == null) { + return false; + } + for (String groupName : selectedWidgetMap.keySet()) { + Group fromGroup = DefaultShareGroupManager.getInstance().getGroup(groupName); + result &= fromGroup != null && fromGroup.moveModule(toGroup, selectedWidgetMap.get(groupName)); + } + selectedWidgetMap.clear(); + return result; + } + + /** + * 移动单独组件到某分组 + */ + public synchronized boolean moveSelect(String formGroupName, String toGroupName, String uuid) { + Group fromGroup = DefaultShareGroupManager.getInstance().getGroup(formGroupName); + Group toGroup = DefaultShareGroupManager.getInstance().getGroup(toGroupName); + if (fromGroup == null || toGroup == null) { + return false; + } + return fromGroup.moveModule(toGroup, Stream.of(uuid).collect(Collectors.toList())); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/menu/SnapChatKeys.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/menu/SnapChatKeys.java new file mode 100644 index 000000000..cf563d2e8 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/menu/SnapChatKeys.java @@ -0,0 +1,32 @@ +package com.fr.design.mainframe.share.ui.menu; + +import com.fr.design.notification.SnapChatKey; + +/** + * created by Harrison on 2020/03/24 + **/ +public enum SnapChatKeys implements SnapChatKey { + + /** + * 组件 + */ + COMPONENT("components"), + + /** + * 模板 + */ + TEMPLATE("template"); + + private String sign; + + private static final String PREFIX = "com.fr.component.share"; + + SnapChatKeys(String sign) { + this.sign = sign; + } + + @Override + public String calc() { + return PREFIX + "-" + sign; + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/menu/TemplateStoreMenu.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/menu/TemplateStoreMenu.java new file mode 100644 index 000000000..7346cb1f5 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/menu/TemplateStoreMenu.java @@ -0,0 +1,53 @@ +package com.fr.design.mainframe.share.ui.menu; + +import com.fr.base.BaseUtils; +import com.fr.design.actions.UpdateAction; +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.share.collect.ComponentCollector; +import com.fr.design.menu.MenuKeySet; +import com.fr.design.utils.BrowseUtils; +import com.fr.general.CloudCenter; + +import javax.swing.KeyStroke; +import java.awt.event.ActionEvent; + +/** + * created by Harrison on 2020/03/24 + **/ +public class TemplateStoreMenu extends UpdateAction { + + public TemplateStoreMenu() { + + this.setMenuKeySet(TEMPLATE); + this.setName(getMenuKeySet().getMenuName()); + this.setMnemonic(getMenuKeySet().getMnemonic()); + this.setSmallIcon(BaseUtils.readIcon("/com/fr/base/images/share/template_store.png")); + } + + public static final MenuKeySet TEMPLATE = new MenuKeySet() { + + @Override + public String getMenuName() { + + return Toolkit.i18nText("Fine-Design_Share_Template_Store"); + } + + @Override + public KeyStroke getKeyStroke() { + return null; + } + + @Override + public char getMnemonic() { + + return 'T'; + } + }; + + @Override + public void actionPerformed(ActionEvent e) { + ComponentCollector.getInstance().collectTepMenuEnterClick(); + String url = CloudCenter.getInstance().acquireUrlByKind("design.market.template"); + BrowseUtils.browser(url); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/AbstractOnlineWidgetShowPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/AbstractOnlineWidgetShowPane.java new file mode 100644 index 000000000..5a5d43234 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/AbstractOnlineWidgetShowPane.java @@ -0,0 +1,269 @@ +package com.fr.design.mainframe.share.ui.online; + +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.share.sort.OnlineWidgetSortType; +import com.fr.design.mainframe.share.ui.base.FlexSearchFieldPane; +import com.fr.design.mainframe.share.ui.base.LoadingPane; +import com.fr.design.mainframe.share.ui.widgetfilter.FilterPane; +import com.fr.form.share.base.DataLoad; +import com.fr.form.share.bean.OnlineShareWidget; +import com.fr.form.share.utils.ShareUtils; +import com.fr.general.IOUtils; +import com.fr.stable.StringUtils; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.SwingWorker; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import java.awt.BorderLayout; +import java.awt.CardLayout; +import java.awt.Color; +import java.awt.FlowLayout; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Created by kerry on 2020-10-19 + */ +public abstract class AbstractOnlineWidgetShowPane extends JPanel { + private static final String SEARCH_RESULT_PANE = "SEARCH_RESULT_PANE"; + private static final String MAIN_FILTER_TAB_PANE = "MAIN_FILTER_TAB_PANE"; + + private JPanel componentSelectPane; + private JPanel searchResultShowPane; + private JPanel mainCenterPane; + private FilterPane filterPane; + private JPanel centerPane; + private SortTabPane sortTabPane; + + private final JPanel loadingPane = new LoadingPane(); + + private OnlineShareWidget[] sharableWidgetProviders; + + //缓存一份用于搜索 + private final OnlineShareWidget[] sharableWidgetCache; + //主面板和搜索面板的cardLayout + private CardLayout mainCardLayout; + + + public AbstractOnlineWidgetShowPane(OnlineShareWidget[] sharableWidgetProviders) { + this.sharableWidgetCache = sharableWidgetProviders; + this.sharableWidgetProviders = sharableWidgetProviders; + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + JPanel contentPane = initContentPane(); + this.add(contentPane, BorderLayout.CENTER); + } + + protected JPanel initContentPane() { + JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + OnlineWidgetSortType.COMPOSITE.sort(sharableWidgetProviders); + componentSelectPane = createOnlineWidgetSelectPane(sharableWidgetProviders); + centerPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + centerPane.add(componentSelectPane, BorderLayout.CENTER); + filterPane = createFilterPane(); + filterPane.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 8)); + initFilterPaneListener(filterPane); + sortTabPane = new SortTabPane(); + initSortTabPane(sortTabPane); + FlexSearchFieldPane flexSearchPane = new FlexSearchFieldPane(filterPane); + initSearchTextFieldPaneListener(flexSearchPane); + + JPanel northPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + northPane.add(flexSearchPane, BorderLayout.CENTER); + northPane.add(sortTabPane, BorderLayout.SOUTH); + initNorthPane(jPanel, northPane); + + searchResultShowPane = createOnlineWidgetSelectPane(new OnlineShareWidget[]{}); + mainCardLayout = new CardLayout(); + mainCenterPane = new JPanel(mainCardLayout); + mainCenterPane.add(centerPane, MAIN_FILTER_TAB_PANE); + mainCenterPane.add(searchResultShowPane, SEARCH_RESULT_PANE); + jPanel.add(mainCenterPane, BorderLayout.CENTER); + + filterPane.addPopupStateChangeListener(state -> setWidgetPaneScrollEnable(!state)); + return jPanel; + } + + protected void initNorthPane(JPanel jPanel, JPanel northPane) { + jPanel.add(northPane, BorderLayout.NORTH); + } + + + protected OnlineWidgetSelectPane createOnlineWidgetSelectPane(OnlineShareWidget[] sharableWidgetProviders) { + return new OnlineWidgetSelectPane(sharableWidgetProviders, filterPane, 50); + } + + protected OnlineWidgetSelectPane createOnlineWidgetSelectPane(DataLoad dataLoad) { + return new OnlineWidgetSelectPane(dataLoad, filterPane, 50); + } + + protected FilterPane createFilterPane() { + return FilterPane.createOnlineFilterPane(); + } + + protected OnlineShareWidget[] getSharableWidgetProviders() { + return sharableWidgetProviders; + } + + public void searchByKeyword(String text) { + if (StringUtils.isEmpty(text)) { + this.mainCardLayout.show(mainCenterPane, MAIN_FILTER_TAB_PANE); + return; + } + List widgets = new ArrayList<>(); + if (StringUtils.isNotEmpty(text)) { + for (OnlineShareWidget provider : sharableWidgetCache) { + if (provider.getName().toLowerCase().contains(text)) { + widgets.add(provider); + } + } + } + + if (searchResultShowPane != null) { + mainCenterPane.remove(searchResultShowPane); + } + this.searchResultShowPane = createOnlineWidgetSelectPane(widgets.toArray(new OnlineShareWidget[widgets.size()])); + this.mainCenterPane.add(searchResultShowPane, SEARCH_RESULT_PANE); + this.mainCardLayout.show(mainCenterPane, SEARCH_RESULT_PANE); + this.validate(); + this.repaint(); + + } + + public void initFilterPaneListener(FilterPane filterPane) { + filterPane.registerChangeListerner(new ChangeListener() { + @Override + public void stateChanged(final ChangeEvent e) { + String filterStr = e.getSource().toString(); + centerPane.remove(componentSelectPane); + componentSelectPane = createOnlineWidgetSelectPane(() -> { + sharableWidgetProviders = new OnlineShareWidget[0]; + sharableWidgetProviders = ShareUtils.getFilterWidgets(filterStr); + return sharableWidgetProviders; + }); + centerPane.add(componentSelectPane, BorderLayout.CENTER); + AbstractOnlineWidgetShowPane.this.validate(); + AbstractOnlineWidgetShowPane.this.repaint(); + } + }); + } + + public void initSearchTextFieldPaneListener(FlexSearchFieldPane searchFieldPane) { + searchFieldPane.registerChangeListener(event -> { + Object object = event.getSource(); + if (object instanceof String) { + String text = (String) object; + sortTabPane.setVisible(StringUtils.isEmpty(text)); + searchByKeyword(text); + } + }); + } + + public void initSortTabPane(SortTabPane sortTabPane) { + + } + + private void setWidgetPaneScrollEnable(boolean enable) { + if (componentSelectPane instanceof OnlineWidgetSelectPane) { + ((OnlineWidgetSelectPane) componentSelectPane).setWidgetPaneScrollEnable(enable); + } + } + + public class SortTabPane extends JPanel { + private final Color BLUE = Color.decode("#419BF9"); + private int index; + private final UILabel[] labels; + private final Map recordMap; + private List mouseListeners = new ArrayList<>(); + + public SortTabPane() { + setLayout(new FlowLayout(FlowLayout.LEFT)); + setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 10)); + OnlineWidgetSortType[] sortTypes = OnlineWidgetSortType.values(); + recordMap = new HashMap<>(); + labels = new UILabel[sortTypes.length]; + int i = 0; + for (OnlineWidgetSortType sortType : sortTypes) { + labels[i] = createTab(sortType); + recordMap.put(sortType.getDisplayName(), i); + add(labels[i]); + i++; + if (i != sortTypes.length) { + add(createSeparator()); + } + } + setIndex(0); + } + + public void setIndex(int index) { + labels[this.index].setForeground(Color.black); + labels[index].setForeground(BLUE); + this.index = index; + repaint(); + } + + public int getIndex() { + return index; + } + + private UILabel createTab(OnlineWidgetSortType sortType) { + UILabel label = new UILabel(sortType.getDisplayName()); + label.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + if (sharableWidgetProviders.length == 0) { + return; + } + String title = label.getText(); + if (index != recordMap.get(title)) { + setIndex(recordMap.get(title)); + } + if (componentSelectPane != null) { + centerPane.remove(componentSelectPane); + centerPane.add(loadingPane); + } + AbstractOnlineWidgetShowPane.this.validate(); + AbstractOnlineWidgetShowPane.this.repaint(); + new SwingWorker() { + @Override + protected Boolean doInBackground() { + sortType.sort(sharableWidgetProviders); + componentSelectPane = createOnlineWidgetSelectPane(sharableWidgetProviders); + return true; + } + + @Override + protected void done() { + centerPane.removeAll(); + centerPane.add(componentSelectPane, BorderLayout.CENTER); + AbstractOnlineWidgetShowPane.this.validate(); + AbstractOnlineWidgetShowPane.this.repaint(); + } + }.execute(); + + for (MouseListener listener : mouseListeners) { + listener.mouseClicked(e); + } + } + }); + return label; + } + + private UILabel createSeparator() { + UILabel label = new UILabel(IOUtils.readIcon("/com/fr/base/images/share/separator.png")); + label.setBorder(BorderFactory.createEmptyBorder(0, 2, 0, 2)); + return label; + } + + public void registerSortTabMouseListener(MouseListener listener) { + mouseListeners.add(listener); + } + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineDownloadPackagePane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineDownloadPackagePane.java new file mode 100644 index 000000000..59a09c466 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineDownloadPackagePane.java @@ -0,0 +1,253 @@ +package com.fr.design.mainframe.share.ui.online; + +import com.fr.design.dialog.FineJOptionPane; +import com.fr.design.gui.icontainer.UIScrollPane; +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.share.ui.base.DownloadProgressPane; +import com.fr.design.mainframe.share.ui.base.ImitationProgress; +import com.fr.design.mainframe.share.ui.base.MouseClickListener; +import com.fr.design.mainframe.share.ui.block.OnlineWidgetBlock; +import com.fr.design.mainframe.share.ui.block.SimpleWidgetBlock; +import com.fr.design.mainframe.share.ui.local.LocalWidgetRepoPane; +import com.fr.design.mainframe.share.ui.online.widgetpackage.OnlineWidgetPackagesShowPane; +import com.fr.design.mainframe.share.util.DownloadUtils; +import com.fr.design.mainframe.share.util.InstallUtils; +import com.fr.design.mainframe.share.util.ShareComponentUtils; +import com.fr.form.share.bean.OnlineShareWidget; +import com.fr.form.share.Group; +import com.fr.log.FineLoggerFactory; +import com.fr.stable.StableUtils; +import org.jetbrains.annotations.Nullable; + +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.SwingWorker; +import java.awt.AlphaComposite; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Composite; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.event.MouseEvent; +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ExecutionException; + +/** + * @Author: Yuan.Wang + * @Date: 2020/12/22 + */ +public class OnlineDownloadPackagePane extends OnlineWidgetSelectPane { + private final String packageId; + private volatile double process; + + + private ImitationThread imitationThread; + private SwingWorker downloadWorker; + private DownloadProgressPane downloadProgressPane; + private final OnlineWidgetPackagesShowPane parentPane; + + + public OnlineDownloadPackagePane(OnlineWidgetPackagesShowPane parentPane, OnlineShareWidget[] providers, int widgetsPerNum) { + super(providers, widgetsPerNum); + this.parentPane = parentPane; + this.packageId = parentPane.getCurrentPackageId(); + } + + protected OnlineWidgetBlock createWidgetBlock(OnlineShareWidget provider) { + return new SimpleWidgetBlock(provider, this); + } + + protected void setScrollPaneStyle(UIScrollPane scrollPane) { + scrollPane.setBorder(null); + scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); + scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); + scrollPane.setWheelScrollingEnabled(false); + } + + @Override + protected boolean pagePaneEnable() { + return false; + } + + protected JPanel createWidgetPane() { + return new JPanel() { + @Override + public void paint(Graphics g) { + super.paint(g); + Graphics2D g2d = (Graphics2D) g; + Composite oldComposite = g2d.getComposite(); + AlphaComposite composite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.65f); + g2d.setComposite(composite); + g2d.setColor(Color.DARK_GRAY); + g2d.fillRect(0, 0, getWidth(), getHeight()); + g2d.setComposite(oldComposite); + } + }; + } + + protected JPanel createContentPane(JPanel widgetPane) { + JPanel panel = new JPanel() { + @Override + public void paint(Graphics g) { + for (int i = 0; i < getComponentCount(); i++) { + getComponent(i).setSize(getSize()); + } + super.paint(g); + } + }; + panel.setLayout(null); + downloadProgressPane = new DownloadProgressPane(new MouseClickListener() { + @Override + public void mouseClicked(MouseEvent e) { + int returnVal = FineJOptionPane.showConfirmDialog(DesignerContext.getDesignerFrame(), + Toolkit.i18nText("Fine-Design_Share_Download_Cancel_Confirm"), Toolkit.i18nText("Fine-Design_Share_Group_Confirm"), + FineJOptionPane.OK_CANCEL_OPTION); + if (returnVal == FineJOptionPane.OK_OPTION) { + //取消下载线程 + imitationThread.interrupt(); + downloadWorker.cancel(false); + + //切换面板 + parentPane.resetWidgetDetailPane(packageId, getSharableWidgetProviders()); + } + } + }); + panel.add(downloadProgressPane); + panel.add(widgetPane, BorderLayout.CENTER); + return panel; + } + + public void downloadWidget(OnlineShareWidget onlineShareWidget) { + + final com.fr.design.extra.Process downloadProcess = aDouble -> { + OnlineDownloadPackagePane.this.process = 0.8 * aDouble; + downloadProgressPane.updateProgress(process); + }; + final com.fr.design.extra.Process installProcess = aDouble -> { + OnlineDownloadPackagePane.this.process = 0.8 + 0.2 * aDouble; + downloadProgressPane.updateProgress(process); + }; + + downloadProcess.process(0.0D); + + //假进度线程 + final ImitationProgress imitationProgress = new ImitationProgress(downloadProcess, getSharableWidgetNum()); + imitationThread = new ImitationThread(imitationProgress); + imitationThread.setName("Component-ImitationProcessThread"); + + //下载线程 + downloadWorker = new DownLoadSwingWorker(installProcess, onlineShareWidget); + + parallel(imitationThread, downloadWorker); + } + + private void parallel(Thread imitationProcessThread, SwingWorker worker) { + imitationProcessThread.start(); + worker.execute(); + } + + /** + * 假进度线程 + */ + private static class ImitationThread extends Thread { + + private final ImitationProgress imitationProgress; + + public ImitationThread(ImitationProgress progress) { + imitationProgress = progress; + } + + @Override + public void run() { + imitationProgress.start(); + } + + public void complete() { + imitationProgress.completed(); + this.interrupt(); + } + + public void stopThread() { + imitationProgress.stop(); + this.interrupt(); + } + } + + private class DownLoadSwingWorker extends SwingWorker { + final com.fr.design.extra.Process installProcess; + final OnlineShareWidget onlineShareWidget; + + public DownLoadSwingWorker(com.fr.design.extra.Process installProcess, OnlineShareWidget onlineShareWidget) { + this.installProcess = installProcess; + this.onlineShareWidget = onlineShareWidget; + } + + @Override + @Nullable + protected Group doInBackground() { + final String filePath; + List failureList = new ArrayList<>(); + try { + filePath = DownloadUtils.downloadPackage(onlineShareWidget.getId(), onlineShareWidget.getName(), DownLoadSwingWorker.this::isCancelled); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + imitationThread.stopThread(); + return null; + } + if (this.isCancelled()) { + imitationThread.stopThread(); + StableUtils.deleteFile(new File(filePath)); + return null; + } + + //等待假进度线程结束 + imitationThread.complete(); + try { + imitationThread.join(); + } catch (InterruptedException ignore) { + } + + //再判断一次 + if (this.isCancelled()) { + StableUtils.deleteFile(new File(filePath)); + return null; + } + ShareComponentUtils.checkReadMe(); + //安装 + File file = new File(filePath); + installProcess.process(0.0D); + downloadProgressPane.changeState(); + InstallUtils.InstallResult result = null; + try { + if (file.exists()) { + result = InstallUtils.installReusFile(file, System.currentTimeMillis(), failureList, installProcess); + } + } finally { + //删掉下载组件的目录 + StableUtils.deleteFile(file); + } + return result == null ? null : result.group; + } + + @Override + protected void done() { + OnlineDownloadPackagePane.this.process = 0.0D; + //替换面板,显示下载label + parentPane.resetWidgetDetailPane(packageId, getSharableWidgetProviders()); + parentPane.repaint(); + if (!isCancelled()) { + try { + Group group = get(); + if (group != null) { + LocalWidgetRepoPane.getInstance().addGroup(group); + } + } catch (InterruptedException | ExecutionException e) { + FineLoggerFactory.getLogger().error(e, e.getMessage()); + } + } + } + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineResourceManager.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineResourceManager.java new file mode 100644 index 000000000..6a99209d3 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineResourceManager.java @@ -0,0 +1,53 @@ +package com.fr.design.mainframe.share.ui.online; + +import javax.swing.SwingWorker; +import java.util.ArrayList; +import java.util.List; + +/** + * Created by kerry on 2020-12-10 + */ +public class OnlineResourceManager { + private static class HOLDER { + private static final OnlineResourceManager singleton = new OnlineResourceManager(); + } + + private OnlineResourceManager(){ + + } + + public static OnlineResourceManager getInstance() { + return HOLDER.singleton; + } + + private SwingWorker swingWorker; + + private final List loaderList = new ArrayList<>(); + + public void cancelLoad() { + if (swingWorker != null) { + swingWorker.cancel(true); + } + this.loaderList.clear(); + } + + public void addLoader(ResourceLoader loader) { + this.loaderList.add(loader); + } + + public void loadImage() { + swingWorker = new SwingWorker() { + @Override + protected Boolean doInBackground() { + for (ResourceLoader loader : loaderList) { + loader.load(); + } + return true; + } + }; + swingWorker.execute(); + + } + + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetRepoPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetRepoPane.java new file mode 100644 index 000000000..af329cde8 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetRepoPane.java @@ -0,0 +1,189 @@ +package com.fr.design.mainframe.share.ui.online; + +import com.fr.base.BaseUtils; +import com.fr.design.dialog.BasicPane; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.share.ui.base.LoadingPane; +import com.fr.design.mainframe.share.ui.base.MouseClickListener; +import com.fr.form.share.bean.OnlineShareWidget; +import com.fr.form.share.utils.ShareUtils; +import com.fr.log.FineLoggerFactory; +import com.fr.stable.StringUtils; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.SwingConstants; +import javax.swing.SwingWorker; +import java.awt.BorderLayout; +import java.awt.CardLayout; +import java.awt.Color; +import java.awt.Cursor; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.event.MouseEvent; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ExecutionException; + + +/** + * Created by kerry on 2020-10-16 + */ +public class OnlineWidgetRepoPane extends BasicPane { + private static final String MARKET_URL = "https://market.fanruan.com/reuse"; + private OnlineWidgetTabPane componentTabPane; + private JPanel centerPane; + private boolean isShowPackagePanel = false; + private CardLayout cardLayout; + + enum Status {LOADING, DISCONNECTED, NORMAL} + + public static OnlineWidgetRepoPane getInstance() { + return OnlineWidgetRepoPane.HOLDER.singleton; + } + + private static class HOLDER { + private static final OnlineWidgetRepoPane singleton = new OnlineWidgetRepoPane(); + } + + @Override + protected String title4PopupWindow() { + return Toolkit.i18nText("Fine-Design_Share_Online"); + } + + public OnlineWidgetRepoPane() { + initPane(); + } + + public boolean isShowPackagePanel() { + return isShowPackagePanel; + } + + public void setShowPackagePanel(boolean showPackagePanel) { + isShowPackagePanel = showPackagePanel; + } + + private void initPane() { + cardLayout = new CardLayout(); + this.setLayout(cardLayout); + this.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0)); + this.centerPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + + this.add(new LoadingPane(), Status.LOADING.name()); + this.add(this.centerPane, Status.NORMAL.name()); + this.add(createInternetErrorPane(), Status.DISCONNECTED.name()); + + switchPane(Status.LOADING); + synchronizedLoadingContent(); + } + + private void addCenterPane() { + this.centerPane.removeAll(); + this.centerPane.add(this.componentTabPane, BorderLayout.CENTER); + this.switchPane(Status.NORMAL); + } + + public void switch2InternetErrorPane() { + switchPane(Status.DISCONNECTED); + } + + private void switchPane(Status status) { + cardLayout.show(this, status.name()); + } + + private void synchronizedLoadingContent() { + new SwingWorker() { + @Override + protected Boolean doInBackground() throws Exception { + return initContentPane(); + } + + @Override + protected void done() { + try { + if (get()) { + addCenterPane(); + } + } catch (InterruptedException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + Thread.currentThread().interrupt(); + } catch (ExecutionException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + } + }.execute(); + } + + private boolean initContentPane() { + List sharableWidgets = new ArrayList<>(); + List sharableWidgetPackage = new ArrayList<>(); + + try { + ShareUtils.getAllSharableWidgetsFromShop(sharableWidgets, sharableWidgetPackage); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + switchPane(Status.DISCONNECTED); + return false; + } + this.componentTabPane = new OnlineWidgetTabPane(sharableWidgets.toArray(new OnlineShareWidget[sharableWidgets.size()]), + sharableWidgetPackage.toArray(new OnlineShareWidget[sharableWidgetPackage.size()])); + + return true; + } + + private void reload() { + this.removeAll(); + initPane(); + this.validate(); + this.repaint(); + } + + private JPanel createInternetErrorPane() { + JPanel panel = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, FlowLayout.LEADING, 0, 5); + UILabel imagePanel = new UILabel(BaseUtils.readIcon("/com/fr/base/images/share/internet_error.png")); + imagePanel.setPreferredSize(new Dimension(240, 96)); + imagePanel.setHorizontalAlignment(SwingConstants.CENTER); + panel.add(imagePanel); + UILabel uiLabel = tipLabel(Toolkit.i18nText("Fine-Design_Share_Internet_Connect_Failed")); + uiLabel.setForeground(Color.decode("#8F8F92")); + UILabel reloadLabel = tipLabel(Toolkit.i18nText("Fine-Design_Share_Online_Reload")); + reloadLabel.setForeground(Color.decode("#419BF9")); + reloadLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + reloadLabel.addMouseListener(new MouseClickListener() { + @Override + public void mouseClicked(MouseEvent e) { + super.mouseClicked(e); + reload(); + } + }); + + + UILabel tipLabel1 = tipLabel(Toolkit.i18nText("Fine-Design_Share_Internet_Connect_Failed_Tip1")); + tipLabel1.setForeground(Color.decode("#8F8F92")); + UILabel tipLabel2 = tipLabel(Toolkit.i18nText("Fine-Design_Share_Internet_Connect_Failed_Tip2")); + tipLabel2.setForeground(Color.decode("#8F8F92")); + UILabel tipLabel3 = tipLabel(MARKET_URL); + tipLabel3.setForeground(Color.decode("#8F8F92")); + + + UILabel emptyLabel = tipLabel(StringUtils.EMPTY); + panel.add(uiLabel); + panel.add(reloadLabel); + panel.add(emptyLabel); + panel.add(tipLabel1); + panel.add(tipLabel2); + panel.add(tipLabel3); + panel.setBorder(BorderFactory.createEmptyBorder(240, 0, 0, 0)); + return panel; + } + + private UILabel tipLabel(String text) { + UILabel tipLabel = new UILabel(text); + tipLabel.setHorizontalAlignment(SwingConstants.CENTER); + tipLabel.setPreferredSize(new Dimension(240, 20)); + return tipLabel; + } + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetSelectPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetSelectPane.java new file mode 100644 index 000000000..61e3ced83 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetSelectPane.java @@ -0,0 +1,225 @@ +package com.fr.design.mainframe.share.ui.online; + +import com.fr.design.gui.icontainer.UIScrollPane; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.share.AbstractWidgetSelectPane; +import com.fr.design.mainframe.share.ui.base.LoadingPane; +import com.fr.design.mainframe.share.ui.base.NoMatchPane; +import com.fr.design.mainframe.share.ui.base.PagingFiledPane; +import com.fr.design.mainframe.share.ui.block.OnlineWidgetBlock; +import com.fr.design.mainframe.share.ui.block.PreviewWidgetBlock; +import com.fr.design.mainframe.share.ui.widgetfilter.FilterPane; +import com.fr.form.share.base.DataLoad; +import com.fr.form.share.bean.OnlineShareWidget; +import com.fr.form.share.constants.ShareComponentConstants; +import com.fr.form.share.utils.ShareUtils; +import com.fr.log.FineLoggerFactory; +import com.fr.stable.ArrayUtils; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.SwingWorker; +import java.awt.BorderLayout; +import java.awt.CardLayout; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.util.concurrent.ExecutionException; + +/** + * Created by kerry on 2020-10-19 + */ +public class OnlineWidgetSelectPane extends AbstractWidgetSelectPane { + protected static final int H_GAP = 5; + protected static final int V_GAP = 10; + + enum PaneStatue {NORMAL, NO_MATCH, LOADING, DISCONNECTED} + + private OnlineShareWidget[] sharableWidgetProviders; + private PagingFiledPane pagingFiledPane; + private JPanel contentPane; + private UIScrollPane scrollPane; + private FilterPane filterPane; + private final int widgetsPerNum; + private CardLayout cardLayout; + + public OnlineWidgetSelectPane(OnlineShareWidget[] providers, FilterPane filterPane, int widgetsPerNum) { + this(providers, widgetsPerNum); + this.filterPane = filterPane; + } + + public OnlineWidgetSelectPane(final DataLoad dataLoad, FilterPane filterPane, final int widgetsPerNum) { + this(dataLoad, widgetsPerNum); + this.filterPane = filterPane; + } + + public OnlineWidgetSelectPane(OnlineShareWidget[] providers, int widgetsPerNum) { + this.widgetsPerNum = widgetsPerNum; + sharableWidgetProviders = providers; + init(); + initPagingPane(); + switchPane(createComponents()); + } + + public OnlineWidgetSelectPane(final DataLoad dataLoad, final int widgetsPerNum) { + this.widgetsPerNum = widgetsPerNum; + init(); + //异步获取组件信息 + new SwingWorker() { + @Override + protected PaneStatue doInBackground() { + sharableWidgetProviders = dataLoad.load(); + initPagingPane(); + return createComponents(); + } + + @Override + protected void done() { + try { + switchPane(get()); + } catch (InterruptedException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + Thread.currentThread().interrupt(); + } catch (ExecutionException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + } + }.execute(); + } + + private void init() { + cardLayout = new CardLayout(); + this.setLayout(cardLayout); + // 设置面板的边框 ,距离上、左、下、右 的距离 + this.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0)); + contentPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + this.add(new LoadingPane(), PaneStatue.LOADING.name()); + this.add(new NoMatchPane(), PaneStatue.NO_MATCH.name()); + this.add(contentPane, PaneStatue.NORMAL.name()); + switchPane(PaneStatue.LOADING); + } + + public int getSharableWidgetNum() { + return sharableWidgetProviders == null ? 0 : sharableWidgetProviders.length; + } + + public OnlineShareWidget[] getSharableWidgetProviders() { + return sharableWidgetProviders; + } + + /** + * 切换需要显示的面板 + */ + private void switchPane(PaneStatue statue) { + if (statue == PaneStatue.DISCONNECTED) { + OnlineWidgetRepoPane.getInstance().switch2InternetErrorPane(); + return; + } + cardLayout.show(this, statue.name()); + if (statue == PaneStatue.NORMAL) { + //异步加载组件缩略图 + OnlineResourceManager.getInstance().loadImage(); + } + } + + private void synchronizedLoadingContent() { + new SwingWorker() { + @Override + protected PaneStatue doInBackground() { + return createComponents(); + } + + @Override + protected void done() { + try { + switchPane(get()); + } catch (InterruptedException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + Thread.currentThread().interrupt(); + } catch (ExecutionException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + } + }.execute(); + } + + private void initPagingPane() { + this.pagingFiledPane = new PagingFiledPane(sharableWidgetProviders.length, widgetsPerNum); + this.pagingFiledPane.registerChangeListener(event -> { + OnlineWidgetSelectPane.this.switchPane(PaneStatue.LOADING); + synchronizedLoadingContent(); + }); + pagingFiledPane.setEnable(pagePaneEnable()); + } + + private PaneStatue createComponents() { + if (ArrayUtils.isEmpty(sharableWidgetProviders)) { + return PaneStatue.NO_MATCH; + } + if (!ShareUtils.testConnection()) { + return PaneStatue.DISCONNECTED; + } + OnlineResourceManager.getInstance().cancelLoad(); + + contentPane.removeAll(); + scrollPane = createScrollPane(); + + contentPane.add(scrollPane, BorderLayout.CENTER); + contentPane.add(this.pagingFiledPane, BorderLayout.SOUTH); + return PaneStatue.NORMAL; + } + + private UIScrollPane createScrollPane() { + OnlineShareWidget[] showWidgets = this.pagingFiledPane.getShowItems(this.sharableWidgetProviders); + JPanel widgetPane = createWidgetPane(); + widgetPane.setLayout(new FlowLayout(FlowLayout.LEFT, H_GAP, V_GAP)); + for (OnlineShareWidget provider : showWidgets) { + PreviewWidgetBlock widgetButton = createWidgetBlock(provider); + widgetPane.add(widgetButton); + } + widgetPane.setPreferredSize(new Dimension(240, getPaneHeight(showWidgets.length))); + + UIScrollPane scrollPane = new UIScrollPane(createContentPane(widgetPane)); + setScrollPaneStyle(scrollPane); + return scrollPane; + } + + protected JPanel createWidgetPane() { + return new JPanel(); + } + + protected JPanel createContentPane(JPanel widgetPane) { + JPanel panel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + panel.add(widgetPane, BorderLayout.CENTER); + return panel; + } + + protected boolean pagePaneEnable() { + return true; + } + + protected void setScrollPaneStyle(UIScrollPane scrollPane) { + scrollPane.setBorder(null); + scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); + scrollPane.setWheelScrollingEnabled(filterPane == null || !filterPane.isShowPopup()); + } + + protected PreviewWidgetBlock createWidgetBlock(OnlineShareWidget provider) { + return new OnlineWidgetBlock(provider, this); + } + + protected int getPaneHeight(int count) { + return (count + 1) / 2 * (ShareComponentConstants.SHARE_BLOCK_HEIGHT + V_GAP); + } + + public void setWidgetPaneScrollEnable(boolean enable) { + if (scrollPane != null) { + scrollPane.setWheelScrollingEnabled(enable); + } + } + + protected Container getParentContainer() { + return this.getParent(); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetShowPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetShowPane.java new file mode 100644 index 000000000..691defde7 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetShowPane.java @@ -0,0 +1,144 @@ +package com.fr.design.mainframe.share.ui.online; + +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.mainframe.share.collect.ComponentCollector; +import com.fr.design.mainframe.share.ui.base.FlexSearchFieldPane; +import com.fr.design.mainframe.share.ui.widgetfilter.FilterPane; +import com.fr.form.share.bean.OnlineShareWidget; +import com.fr.stable.StringUtils; + +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import javax.swing.text.BadLocationException; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + + +/** + * Created by kerry on 2020-10-19 + */ +public class OnlineWidgetShowPane extends AbstractOnlineWidgetShowPane { + private String lastSearch = StringUtils.EMPTY; + private String lastFilter = StringUtils.EMPTY; + private int lastSortTabSelectedIndex = 0; + + public OnlineWidgetShowPane(OnlineShareWidget[] sharableWidgetProviders) { + super(sharableWidgetProviders); + } + + @Override + public void initSearchTextFieldPaneListener(FlexSearchFieldPane searchFieldPane) { + super.initSearchTextFieldPaneListener(searchFieldPane); + + searchFieldPane.registerSearchTextFieldFocusListener(new FocusAdapter() { + private KeyListener keyListener = new KeyAdapter() { + @Override + public void keyPressed(KeyEvent e) { + if (e.getKeyCode() == KeyEvent.VK_DELETE) { + collectSearchText(false); + } + } + }; + public void focusGained(FocusEvent e) { + searchFieldPane.addKeyListener(keyListener); + } + @Override + public void focusLost(FocusEvent e) { + searchFieldPane.removeKeyListener(keyListener); + collectSearchText(true); + + } + }); + + searchFieldPane.registerDeleteIconMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + collectSearchText(false); + } + }); + + searchFieldPane.registerFieldDocumentListener(new DocumentListener() { + @Override + public void insertUpdate(DocumentEvent e) { + try { + lastSearch = e.getDocument().getText(0, e.getDocument().getLength()); + } catch (BadLocationException ex) { + ex.printStackTrace(); + } + } + @Override + public void removeUpdate(DocumentEvent e) { + textChanged(e); + } + + @Override + public void changedUpdate(DocumentEvent e) { + textChanged(e); + } + + public void textChanged(DocumentEvent e) {}; + }); + } + + @Override + public void initFilterPaneListener(FilterPane filterPane) { + super.initFilterPaneListener(filterPane); + filterPane.registerChangeListerner(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + lastFilter = e.getSource().toString(); + } + }); + filterPane.addPopupStateChangeListener(new FilterPane.PopStateChangeListener() { + @Override + public void stateChange(boolean state) { + if (!state) { + collectFilterContent(); + } + } + }); + } + + @Override + public void initSortTabPane(SortTabPane sortTabPane) { + super.initSortTabPane(sortTabPane); + lastSortTabSelectedIndex = sortTabPane.getIndex(); + sortTabPane.registerSortTabMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + if (sortTabPane.getIndex() != lastSortTabSelectedIndex) { + collectSortType(((UILabel) e.getSource()).getText()); + lastSortTabSelectedIndex = sortTabPane.getIndex(); + } + } + }); + } + + private void collectSearchText(boolean isSaveInfo) { + if (StringUtils.isNotEmpty(lastSearch)) { + ComponentCollector.getInstance().collectSearchContent(this.lastSearch); + if (isSaveInfo) { + ComponentCollector.getInstance().saveInfo(); + } + lastSearch = StringUtils.EMPTY; + } + } + + private void collectFilterContent() { + if (StringUtils.isNotEmpty(lastFilter)) { + ComponentCollector.getInstance().collectFilterContent(lastFilter); + lastSearch = StringUtils.EMPTY; + } + } + + private void collectSortType(String sortType) { + ComponentCollector.getInstance().collectSortType(sortType); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetTabPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetTabPane.java new file mode 100644 index 000000000..96837fd3c --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetTabPane.java @@ -0,0 +1,58 @@ +package com.fr.design.mainframe.share.ui.online; + +import com.fr.design.gui.ibutton.UITabGroup; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.share.collect.ComponentCollector; +import com.fr.design.mainframe.share.ui.online.widgetpackage.OnlineWidgetPackagesShowPane; +import com.fr.form.share.bean.OnlineShareWidget; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import java.awt.BorderLayout; +import java.awt.CardLayout; + +/** + * Created by kerry on 2020-10-19 + */ +public class OnlineWidgetTabPane extends JPanel { + private static final String COMPONENT = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Share"); + private static final String COMPONENT_PACKAGE = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Share_Package"); + private CardLayout cardLayout; + private JPanel centerPane; + private boolean packagePaneCreated = false; + + public OnlineWidgetTabPane(OnlineShareWidget[] sharableWidgets, OnlineShareWidget[] sharableWidgetPackage) { + initPane(sharableWidgets, sharableWidgetPackage); + } + + private void initPane(OnlineShareWidget[] sharableWidgets, OnlineShareWidget[] sharableWidgetPackages) { + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + this.cardLayout = new CardLayout(); + this.centerPane = new JPanel(cardLayout); + this.centerPane.add(new OnlineWidgetShowPane(sharableWidgets), COMPONENT); + //延迟组件包面板的初始化,防止组件面板里组件的缩略图和组件包面板里组件的缩略图一起加载 + UITabGroup headGroup = new UITabGroup(new String[]{COMPONENT, COMPONENT_PACKAGE}) { + public void tabChanged(int newSelectedIndex) { + OnlineWidgetRepoPane.getInstance().setShowPackagePanel(newSelectedIndex != 0); + if (newSelectedIndex == 0) { + cardLayout.show(centerPane, COMPONENT); + } else { + ComponentCollector.getInstance().collectCmpPktClick(); + //延迟组件包面板的初始化,防止组件面板里组件和缩略图和组件包面板里组件的缩略图一起加载 + if (!packagePaneCreated) { + centerPane.add(new OnlineWidgetPackagesShowPane(sharableWidgetPackages), COMPONENT_PACKAGE); + packagePaneCreated = true; + } + cardLayout.show(centerPane, COMPONENT_PACKAGE); + } + } + }; + headGroup.setSelectedIndex(0); + this.centerPane.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0)); + JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + jPanel.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 10)); + jPanel.add(headGroup, BorderLayout.CENTER); + this.add(jPanel, BorderLayout.NORTH); + this.add(centerPane, BorderLayout.CENTER); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/ResourceLoader.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/ResourceLoader.java new file mode 100644 index 000000000..a57a64588 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/ResourceLoader.java @@ -0,0 +1,13 @@ +package com.fr.design.mainframe.share.ui.online; + +/** + * Created by kerry on 2020-12-10 + * todo 后面看看能不能和DataLoad合并起来 + */ +public interface ResourceLoader { + /** + * 加载资源文件 + */ + void load(); + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/widgetpackage/OnlineWidgetPackageSelectPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/widgetpackage/OnlineWidgetPackageSelectPane.java new file mode 100644 index 000000000..2271f0c89 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/widgetpackage/OnlineWidgetPackageSelectPane.java @@ -0,0 +1,40 @@ +package com.fr.design.mainframe.share.ui.online.widgetpackage; + +import com.fr.design.mainframe.share.ui.block.OnlineWidgetPackageBlock; +import com.fr.design.mainframe.share.ui.block.PreviewWidgetBlock; +import com.fr.design.mainframe.share.ui.online.OnlineWidgetSelectPane; +import com.fr.form.share.base.DataLoad; +import com.fr.form.share.bean.OnlineShareWidget; +import com.fr.form.share.constants.ShareComponentConstants; + +/** + * Created by kerry on 2020-10-21 + */ +public class OnlineWidgetPackageSelectPane extends OnlineWidgetSelectPane { + private final OnlineWidgetPackagesShowPane parentPane; + + public OnlineWidgetPackageSelectPane(OnlineShareWidget[] providers, int widgetsPerNum, OnlineWidgetPackagesShowPane parentPane) { + super(providers, widgetsPerNum); + this.parentPane = parentPane; + + } + + public OnlineWidgetPackageSelectPane(DataLoad dataLoad, int widgetsPerNum, OnlineWidgetPackagesShowPane parentPane) { + super(dataLoad, widgetsPerNum); + this.parentPane = parentPane; + + } + + public void showWidgetDetailPane(String id) { + this.parentPane.showWidgetDetailPane(id); + } + + protected PreviewWidgetBlock createWidgetBlock(OnlineShareWidget provider) { + return new OnlineWidgetPackageBlock(provider, this); + } + + protected int getPaneHeight(int count) { + return count * (ShareComponentConstants.SHARE_PACKAGE_BLOCK_HEIGHT + V_GAP); + } + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/widgetpackage/OnlineWidgetPackagesShowPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/widgetpackage/OnlineWidgetPackagesShowPane.java new file mode 100644 index 000000000..d9697495b --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/widgetpackage/OnlineWidgetPackagesShowPane.java @@ -0,0 +1,183 @@ +package com.fr.design.mainframe.share.ui.online.widgetpackage; + + +import com.fr.design.dialog.FineJOptionPane; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.share.ui.base.MouseClickListener; +import com.fr.design.mainframe.share.ui.online.AbstractOnlineWidgetShowPane; +import com.fr.design.mainframe.share.ui.online.OnlineDownloadPackagePane; +import com.fr.design.mainframe.share.ui.online.OnlineWidgetSelectPane; +import com.fr.design.mainframe.share.ui.widgetfilter.FilterPane; +import com.fr.form.share.base.DataLoad; +import com.fr.form.share.bean.OnlineShareWidget; +import com.fr.form.share.utils.ShareUtils; +import com.fr.stable.StringUtils; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import java.awt.BorderLayout; +import java.awt.CardLayout; +import java.awt.Color; +import java.awt.Cursor; +import java.awt.event.MouseEvent; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Created by kerry on 2020-10-19 + */ +public class OnlineWidgetPackagesShowPane extends AbstractOnlineWidgetShowPane { + private static final Color TEXT_COLOR = Color.decode("#419BF9"); + private static final String WIDGETS_INFO = "WIDGETS_INFO"; + private static final String WIDGET_DETAIL = "WIDGET_DETAIL"; + + private CardLayout cardLayout; + private JPanel centerPane; + private JPanel detailPane; + private String currentPackageId; + private OnlineWidgetSelectPane onlineWidgetSelectPane; + private UILabel downloadLabel; + private final Map cachePanelMap = new HashMap<>(); + + public OnlineWidgetPackagesShowPane(OnlineShareWidget[] sharableWidgetProviders) { + super(sharableWidgetProviders); + } + + protected JPanel initContentPane() { + JPanel firstPane = super.initContentPane(); + cardLayout = new CardLayout(); + centerPane = new JPanel(cardLayout); + centerPane.add(firstPane, WIDGETS_INFO); + + JPanel secondPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + UILabel backLabel = createLabel(Toolkit.i18nText("Fine-Design_Report_AlphaFine_Back"), new MouseClickListener() { + @Override + public void mouseClicked(MouseEvent e) { + cardLayout.show(centerPane, WIDGETS_INFO); + } + }); + downloadLabel = createLabel(Toolkit.i18nText("Fine-Design_Share_Download_All_Component"), new MouseClickListener() { + @Override + public void mouseClicked(MouseEvent e) { + String message = Toolkit.i18nText("Fine-Design_Share_Download_All_Component_Message") + + "\n" + + Toolkit.i18nText("Fine-Design_Share_Total") + + onlineWidgetSelectPane.getSharableWidgetNum() + + Toolkit.i18nText("Fine-Design_Share_Piece"); + int returnValue = FineJOptionPane.showConfirmDialog(DesignerContext.getDesignerFrame(), message, Toolkit.i18nText("Fine-Design_Basic_Confirm"), FineJOptionPane.YES_NO_OPTION); + if (returnValue == FineJOptionPane.OK_OPTION && onlineWidgetSelectPane.getSharableWidgetNum() != 0) { + downLoadPackage(); + } + } + }); + + JPanel downloadPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + downloadPane.setBorder(BorderFactory.createEmptyBorder(0, 130, 0, 0)); + downloadPane.add(downloadLabel, BorderLayout.CENTER); + + JPanel labelPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + labelPane.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 10)); + labelPane.add(backLabel, BorderLayout.WEST); + labelPane.add(downloadPane, BorderLayout.CENTER); + + secondPane.add(labelPane, BorderLayout.NORTH); + detailPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + detailPane.add(new OnlineWidgetSelectPane(new OnlineShareWidget[]{}, 50), BorderLayout.CENTER); + secondPane.add(detailPane, BorderLayout.CENTER); + centerPane.add(secondPane, WIDGET_DETAIL); + cardLayout.show(centerPane, WIDGETS_INFO); + return centerPane; + } + + private void downLoadPackage() { + downloadLabel.setVisible(false); + detailPane.removeAll(); + OnlineDownloadPackagePane widgetSelectPane = new OnlineDownloadPackagePane(this, onlineWidgetSelectPane.getSharableWidgetProviders(), 50); + detailPane.add(widgetSelectPane, BorderLayout.CENTER); + cardLayout.show(centerPane, WIDGET_DETAIL); + + cachePanelMap.put(currentPackageId, widgetSelectPane); + + for (OnlineShareWidget onlineShareWidget : getSharableWidgetProviders()) { + if (StringUtils.equals(onlineShareWidget.getId(), currentPackageId)) { + widgetSelectPane.downloadWidget(onlineShareWidget); + break; + } + } + } + + private UILabel createLabel(String i18nText, MouseClickListener clickListener) { + UILabel label = new UILabel(i18nText); + label.setForeground(TEXT_COLOR); + label.addMouseListener(clickListener); + label.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + return label; + } + + protected void initNorthPane(JPanel jPanel, JPanel northPane) { + //暂时隐藏,以后会展示出来 + } + + + protected OnlineWidgetSelectPane createOnlineWidgetSelectPane(OnlineShareWidget[] sharableWidgetProviders) { + return new OnlineWidgetPackageSelectPane(filterPackageWidget(sharableWidgetProviders), 10, this); + } + + protected OnlineWidgetSelectPane createOnlineWidgetSelectPane(DataLoad dataLoad) { + return new OnlineWidgetPackageSelectPane(dataLoad, 10, this); + } + + private OnlineShareWidget[] filterPackageWidget(OnlineShareWidget[] sharableWidgetProviders) { + List onlineShareWidgets = new ArrayList<>(); + for (OnlineShareWidget widget : sharableWidgetProviders) { + if (widget.isWidgetPackage()) { + onlineShareWidgets.add(widget); + } + } + return onlineShareWidgets.toArray(new OnlineShareWidget[onlineShareWidgets.size()]); + } + + public void showWidgetDetailPane(final String id) { + currentPackageId = id; + boolean containsCache = cachePanelMap.containsKey(id); + onlineWidgetSelectPane = containsCache ? cachePanelMap.get(id) : new OnlineWidgetSelectPane(() -> ShareUtils.getPackageWidgets(id), 50); + downloadLabel.setVisible(!containsCache); + showWidgetDetailPane(onlineWidgetSelectPane); + } + + + public void resetWidgetDetailPane(String id, final OnlineShareWidget[] onlineShareWidgets) { + if (StringUtils.equals(id, currentPackageId)) { + showWidgetDetailPane(new OnlineWidgetSelectPane(onlineShareWidgets, 50)); + setDownloadLabelVisible(true); + } + removeCachePane(id); + } + + private void showWidgetDetailPane(OnlineWidgetSelectPane onlineWidgetSelectPane) { + detailPane.removeAll(); + detailPane.add(onlineWidgetSelectPane, BorderLayout.CENTER); + cardLayout.show(centerPane, WIDGET_DETAIL); + } + + public void setDownloadLabelVisible(boolean visible) { + downloadLabel.setVisible(visible); + } + + public String getCurrentPackageId() { + return currentPackageId; + } + + public void removeCachePane(String packageId) { + cachePanelMap.remove(packageId); + } + + protected FilterPane createFilterPane() { + return FilterPane.createOnlinePackageFilterPane(); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/widgetfilter/FilterPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/widgetfilter/FilterPane.java new file mode 100644 index 000000000..ce976e217 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/widgetfilter/FilterPane.java @@ -0,0 +1,235 @@ +package com.fr.design.mainframe.share.ui.widgetfilter; + +import com.fr.base.BaseUtils; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.share.ui.base.MouseClickListener; +import com.fr.form.share.bean.WidgetFilterTypeInfo; +import com.fr.form.share.utils.ShareUtils; +import com.fr.general.ComparatorUtils; +import com.fr.invoke.Reflect; + +import javax.swing.BorderFactory; +import javax.swing.Icon; +import javax.swing.JPanel; +import javax.swing.Popup; +import javax.swing.PopupFactory; +import javax.swing.SwingConstants; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import java.awt.AWTEvent; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Cursor; +import java.awt.Dimension; +import java.awt.Point; +import java.awt.event.AWTEventListener; +import java.awt.event.MouseEvent; +import java.util.ArrayList; +import java.util.EventListener; +import java.util.List; + +/** + * Created by kerry on 2020-10-21 + */ +public class FilterPane extends JPanel { + public static final String SOURCE_FILTER_KEY = "2@source"; + public static final String CHART_FILTER_KEY = "3@chart"; + public static final String REPORT_FILTER_KEY = "4@report"; + + private static final Icon FILTER_COMBO = BaseUtils.readIcon("/com/fr/base/images/share/filter_combo.png"); + private static final Icon FILTER_COMBO_UP = BaseUtils.readIcon("/com/fr/base/images/share/filter_combo_up.png"); + private final UILabel filterLabel; + private UILabel arrowButton; + private Popup popup; + private boolean showPopup = false; + private FilterPopupPane filterPopupPane; + private ChangeListener changeListener; + private final AWTEventListener awtEventListener; + List listenerList = new ArrayList<>(); + + private FilterPane() { + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + final JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + jPanel.setBorder(BorderFactory.createLineBorder(Color.decode("#D9DADD"))); + this.add(jPanel, BorderLayout.CENTER); + jPanel.setBackground(Color.WHITE); + this.filterLabel = new UILabel(Toolkit.i18nText("Fine-Design_Share_Online_No_Filter"), SwingConstants.LEFT); + filterLabel.setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 0)); + filterLabel.setPreferredSize(new Dimension(80, 20)); + filterLabel.setForeground(Color.decode("#8F8F92")); + filterLabel.addMouseListener(new MouseClickListener() { + @Override + public void mouseClicked(MouseEvent e) { + super.mouseClicked(e); + if (filterPopupPane != null) { + if (filterPopupPane.hasFilter()) { + filterPopupPane.reset(); + } else { + controlFilterPopUp(); + } + } + + } + }); + jPanel.addMouseListener( + new MouseClickListener() { + @Override + public void mouseClicked(MouseEvent e) { + super.mouseClicked(e); + controlFilterPopUp(); + } + } + ); + JPanel subPane = FRGUIPaneFactory.createLeftFlowZeroGapBorderPane(); + subPane.add(filterLabel); + subPane.setBackground(Color.WHITE); + jPanel.add(subPane, BorderLayout.CENTER); + arrowButton = new UILabel(FILTER_COMBO); + awtEventListener = event -> { + if (event instanceof MouseEvent) { + MouseEvent mv = (MouseEvent) event; + if (isCanHide(mv, jPanel)) { + hideFilterPopUp(); + } + } + + }; + jPanel.add(arrowButton, BorderLayout.EAST); + } + + public static FilterPane createLocalFilterPane() { + FilterPane pane = new FilterPane(); + pane.filterPopupPane = new LocalFilterPopupPane(pane, LocalWidgetFilterCategory.getLocalCategory()); + return pane; + } + + public static FilterPane createOnlineFilterPane() { + FilterPane pane = new FilterPane(); + pane.filterPopupPane = new OnlineFilterPopupPane(pane, pane.loadFilterCategories()); + return pane; + } + + public static FilterPane createOnlinePackageFilterPane() { + FilterPane pane = new FilterPane() { + @Override + protected List loadFilterCategories() { + List filterTypeInfos = super.loadFilterCategories(); + filterTypeInfos.removeIf(info -> ComparatorUtils.equals(FilterPane.CHART_FILTER_KEY, info.getKey()) + || ComparatorUtils.equals(FilterPane.REPORT_FILTER_KEY, info.getKey())); + return filterTypeInfos; + } + }; + pane.filterPopupPane = new LocalFilterPopupPane(pane, pane.loadFilterCategories()); + return pane; + } + + public void changeFilterButtonStatus(boolean hasFilter) { + if (hasFilter) { + switchToClearFilter(); + } else { + switchToNoFilter(); + } + } + + public boolean isShowPopup() { + return showPopup; + } + + private void controlFilterPopUp() { + if (!showPopup) { + showFilterPopUp(); + } else { + hideFilterPopUp(); + } + } + + private synchronized void showFilterPopUp() { + PopupFactory pf = PopupFactory.getSharedInstance(); + Point p = FilterPane.this.getLocationOnScreen(); + popup = pf.getPopup(FilterPane.this, filterPopupPane, p.x, p.y + FilterPane.this.getHeight()); + popup.show(); + filterPopupPane.setPreferredSize(new Dimension(228, filterPopupPane.getHeight())); + showPopup = true; + arrowButton.setIcon(FILTER_COMBO_UP); + firePopupStateChange(true); + java.awt.Toolkit.getDefaultToolkit().addAWTEventListener(awtEventListener, AWTEvent.MOUSE_EVENT_MASK); + } + + private void hideFilterPopUp() { + popup.hide(); + showPopup = false; + arrowButton.setIcon(FILTER_COMBO); + firePopupStateChange(false); + java.awt.Toolkit.getDefaultToolkit().removeAWTEventListener(awtEventListener); + } + + protected List loadFilterCategories() { + return ShareUtils.getWidgetFilterTypeInfos(); + } + + private boolean isCanHide(MouseEvent mv, JPanel jPanel) { + if (mv.getClickCount() < 1) { + return false; + } + // 表示Popup弹窗是否能被点击到 + boolean clickFlag = false; + if (popup != null && showPopup) { + Component component = Reflect.on(popup).call("getComponent").get(); + Point p = component.getLocationOnScreen(); + Point clickPoint = mv.getLocationOnScreen(); + clickFlag = clickPoint.getX() >= p.getX() + && clickPoint.getY() >= p.getY() + && clickPoint.getX() <= component.getWidth() + p.getX() + && clickPoint.getY() <= p.getY() + component.getHeight(); + + } + return popup != null && showPopup + && !clickFlag && !ComparatorUtils.equals(mv.getSource(), jPanel) + && !ComparatorUtils.equals(mv.getSource(), filterLabel); + } + + public void registerChangeListerner(ChangeListener changeListener) { + this.changeListener = changeListener; + } + + public void fireChangeListener(ChangeEvent e) { + this.changeListener.stateChanged(e); + } + + public void reset() { + if (filterPopupPane != null && filterPopupPane.hasFilter()) { + filterPopupPane.reset(); + } + switchToNoFilter(); + } + + private void switchToNoFilter() { + filterLabel.setText(Toolkit.i18nText("Fine-Design_Share_Online_No_Filter")); + filterLabel.setForeground(Color.decode("#8F8F92")); + filterLabel.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + } + + private void switchToClearFilter() { + filterLabel.setText(Toolkit.i18nText("Fine-Design_Share_Online_Clear_Filter")); + filterLabel.setForeground(Color.decode("#419BF9")); + filterLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + } + + public void firePopupStateChange(boolean PopupState) { + for (PopStateChangeListener listener : listenerList) { + listener.stateChange(PopupState); + } + } + + public void addPopupStateChangeListener(PopStateChangeListener listener) { + listenerList.add(listener); + } + + public interface PopStateChangeListener extends EventListener { + void stateChange(boolean state); + } + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/widgetfilter/FilterPopupPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/widgetfilter/FilterPopupPane.java new file mode 100644 index 000000000..e2bcd5344 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/widgetfilter/FilterPopupPane.java @@ -0,0 +1,201 @@ +package com.fr.design.mainframe.share.ui.widgetfilter; + +import com.fr.design.gui.icheckbox.UICheckBox; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.layout.VerticalFlowLayout; +import com.fr.form.share.bean.WidgetFilterInfo; +import com.fr.form.share.bean.WidgetFilterTypeInfo; +import com.fr.general.ComparatorUtils; +import com.fr.stable.StringUtils; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.event.ChangeEvent; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Font; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.util.ArrayList; +import java.util.List; + +/** + * @Author: Yuan.Wang + * @Date: 2020/11/11 + */ +public abstract class FilterPopupPane extends JPanel { + private static final Color BORDER_COLOR = Color.decode("#D9DADD"); + private static final String FILTER_ALL_ID = "0"; + + FilterPane filterPane; + private List filterList = new ArrayList<>(); + private final List checkBoxList = new ArrayList<>(); + private boolean reset = false; + + + public FilterPopupPane(FilterPane filterPane, List widgetFilterCategories) { + this.filterPane = filterPane; + initPane(widgetFilterCategories); + } + + private void initPane(List widgetFilterCategories) { + this.setBackground(Color.WHITE); + this.setBorder(BorderFactory.createLineBorder(BORDER_COLOR)); + this.setForeground(Color.decode("#FFFFFF")); + this.setLayout(new BorderLayout()); + this.add(createVerticalFlowPane(widgetFilterCategories), BorderLayout.CENTER); + } + + public boolean hasFilter() { + return filterList.size() > 0; + } + + protected List getFilterList() { + return filterList; + } + + private JPanel createVerticalFlowPane(List widgetFilterCategories) { + + List topWidgetTypeFilter = new ArrayList<>(); + List widgetTypeFilter = new ArrayList<>(); + List otherWidgetTypeFilter = new ArrayList<>(); + + for (WidgetFilterTypeInfo info : widgetFilterCategories) { + if (ComparatorUtils.equals(FilterPane.CHART_FILTER_KEY, info.getKey()) + || ComparatorUtils.equals(FilterPane.REPORT_FILTER_KEY, info.getKey())) { + widgetTypeFilter.add(info); + } else if (ComparatorUtils.equals(FilterPane.SOURCE_FILTER_KEY, info.getKey())) { + topWidgetTypeFilter.add(info); + } else { + otherWidgetTypeFilter.add(info); + } + } + + JPanel verticalFlowPane = new JPanel(); + verticalFlowPane.setBackground(Color.WHITE); + VerticalFlowLayout layout = new VerticalFlowLayout(FlowLayout.LEADING, 0, 10); + layout.setAlignLeft(true); + verticalFlowPane.setLayout(layout); + + verticalFlowPane.setBackground(Color.WHITE); + verticalFlowPane.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5)); + + for (WidgetFilterTypeInfo info : topWidgetTypeFilter) { + verticalFlowPane.add(createOtherCategoryPane(info)); + } + if (widgetTypeFilter.size() > 0) { + verticalFlowPane.add(createWidgetTypeFilterPane(widgetTypeFilter)); + } + for (WidgetFilterTypeInfo info : otherWidgetTypeFilter) { + verticalFlowPane.add(createOtherCategoryPane(info)); + } + return verticalFlowPane; + } + + private JPanel createWidgetTypeFilterPane(List widgetTypeFilter) { + JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + jPanel.setBackground(Color.WHITE); + UILabel titleLabel = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Type")); + titleLabel.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5)); + titleLabel.setPreferredSize(new Dimension(226, 20)); + titleLabel.setOpaque(true); + titleLabel.setBackground(Color.decode("#EDEDEE")); + jPanel.add(titleLabel, BorderLayout.NORTH); + + JPanel contentPane = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, FlowLayout.LEADING, 0, 10); + contentPane.setBackground(Color.WHITE); + for (WidgetFilterTypeInfo info : widgetTypeFilter) { + contentPane.add(createTypeFilterPane(info)); + } + jPanel.add(contentPane, BorderLayout.CENTER); + return jPanel; + } + + private JPanel createTypeFilterPane(WidgetFilterTypeInfo widgetFilterTypeInfo) { + JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + jPanel.setBackground(Color.WHITE); + UILabel titleLabel = new UILabel(widgetFilterTypeInfo.getTitle() + ":"); + titleLabel.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5)); + titleLabel.setFont(new Font(titleLabel.getFont().getName(), Font.BOLD, titleLabel.getFont().getSize())); + jPanel.add(titleLabel, BorderLayout.NORTH); + jPanel.add(createCategoryDetailPane(widgetFilterTypeInfo), BorderLayout.CENTER); + return jPanel; + } + + private JPanel createOtherCategoryPane(WidgetFilterTypeInfo filterTypeInfo) { + JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + jPanel.setBackground(Color.WHITE); + UILabel titleLabel = new UILabel(filterTypeInfo.getTitle()); + titleLabel.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5)); + titleLabel.setPreferredSize(new Dimension(226, 20)); + titleLabel.setOpaque(true); + titleLabel.setBackground(Color.decode("#EDEDEE")); + jPanel.add(titleLabel, BorderLayout.NORTH); + jPanel.add(createCategoryDetailPane(filterTypeInfo), BorderLayout.CENTER); + return jPanel; + } + + private JPanel createCategoryDetailPane(WidgetFilterTypeInfo filterTypeInfo) { + JPanel contentPane = FRGUIPaneFactory.createNColumnGridInnerContainer_S_Pane(2); + contentPane.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0)); + contentPane.setBackground(Color.WHITE); + int displayCount = 0; + for (final WidgetFilterInfo filterInfo : filterTypeInfo.getFilterItems()) { + if (!ComparatorUtils.equals(FILTER_ALL_ID, filterInfo.getId())) { + displayCount++; + } + } + int contentPaneHeight = ((displayCount + 1) / 2) * 27; + contentPane.setPreferredSize(new Dimension(228, contentPaneHeight)); + for (final WidgetFilterInfo filterInfo : filterTypeInfo.getFilterItems()) { + if (ComparatorUtils.equals(FILTER_ALL_ID, filterInfo.getId())) { + continue; + } + final UICheckBox checkBox = new UICheckBox(filterInfo.getName()); + checkBox.setBackground(Color.WHITE); + + checkBox.addItemListener(new ItemListener() { + @Override + public void itemStateChanged(ItemEvent e) { + if (reset) { + return; + } + if (checkBox.isSelected()) { + filterList.add(filterInfo); + } else if (filterList.contains(filterInfo)) { + filterList.remove(filterInfo); + } + checkFilterButtonStatus(); + filterPane.fireChangeListener(new ChangeEvent(assembleFilter())); + } + }); + + + checkBoxList.add(checkBox); + contentPane.add(checkBox); + } + return contentPane; + } + + protected abstract String assembleFilter(); + + private void checkFilterButtonStatus() { + filterPane.changeFilterButtonStatus(hasFilter()); + } + + public void reset() { + reset = true; + for (UICheckBox checkBox : checkBoxList) { + checkBox.setSelected(false); + } + filterList.clear(); + checkFilterButtonStatus(); + filterPane.fireChangeListener(new ChangeEvent(StringUtils.EMPTY)); + reset = false; + } + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/widgetfilter/LocalFilterPopupPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/widgetfilter/LocalFilterPopupPane.java new file mode 100644 index 000000000..5a589d32c --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/widgetfilter/LocalFilterPopupPane.java @@ -0,0 +1,23 @@ +package com.fr.design.mainframe.share.ui.widgetfilter; + +import com.fr.form.share.bean.WidgetFilterTypeInfo; +import com.fr.stable.StringUtils; + +import java.util.ArrayList; +import java.util.List; + +/** + * @Author: Yuan.Wang + * @Date: 2020/11/11 + */ +public class LocalFilterPopupPane extends FilterPopupPane { + public LocalFilterPopupPane(FilterPane pane, List loadFilterCategories) { + super(pane, loadFilterCategories); + } + + @Override + protected String assembleFilter() { + LocalWidgetFilter.getInstance().setFilterList(getFilterList() == null ? new ArrayList<>() : getFilterList()); + return StringUtils.EMPTY; + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/widgetfilter/LocalWidgetFilter.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/widgetfilter/LocalWidgetFilter.java new file mode 100644 index 000000000..259e6fcc9 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/widgetfilter/LocalWidgetFilter.java @@ -0,0 +1,139 @@ +package com.fr.design.mainframe.share.ui.widgetfilter; + +import com.fr.design.i18n.Toolkit; +import com.fr.form.share.DefaultSharableWidget; +import com.fr.form.share.SharableWidgetProvider; +import com.fr.form.share.bean.WidgetFilterInfo; +import com.fr.design.mainframe.share.constants.DisplayDevice; +import com.fr.stable.ArrayUtils; +import com.fr.stable.StringUtils; + +import java.util.ArrayList; +import java.util.List; + +/** + * @Author: Yuan.Wang + * @Date: 2020/11/11 + */ +public class LocalWidgetFilter { + private List filterList; + + private LocalWidgetFilter() { + filterList = new ArrayList<>(); + } + + private static class Holder { + private static final LocalWidgetFilter HOLDER = new LocalWidgetFilter(); + } + + public static LocalWidgetFilter getInstance() { + return Holder.HOLDER; + } + + public void setFilterList(List filterList) { + this.filterList = filterList; + } + + public boolean shouldShow(SharableWidgetProvider provider) { + if (filterList == null || filterList.size() == 0) { + return true; + } + if (provider instanceof DefaultSharableWidget) { + DefaultSharableWidget bindInfo = (DefaultSharableWidget) provider; + //类型,即图表类型或报表类型 + boolean sameType = true; + //展示终端,即PC端、移动端 + boolean sameDisplayDevice = true; + //价格,即免费或者付费 + boolean sameSource = true; + + //如果有筛选条件,先初始化为false + for (WidgetFilterInfo filterInfo : filterList) { + if (StringUtils.equals(filterInfo.getType(), "chart") | StringUtils.equals(filterInfo.getType(), "report")) { + sameType = false; + } + if (StringUtils.equals(filterInfo.getType(), "displayDevice")) { + sameDisplayDevice = false; + } + if (StringUtils.equals(filterInfo.getType(), "source")) { + sameSource = false; + } + } + //符合条件,设置为true + for (WidgetFilterInfo filterInfo : filterList) { + //类型 + sameType |= filterType(filterInfo, bindInfo); + //展示终端 + sameDisplayDevice |= filterDisplayDevice(filterInfo, bindInfo); + //来源 + sameSource |= filterSource(filterInfo, bindInfo); + } + return sameDisplayDevice & sameSource & sameType; + } + return false; + } + + public SharableWidgetProvider[] filter(SharableWidgetProvider[] elCaseBindInfoList) { + SharableWidgetProvider[] result = elCaseBindInfoList; + for (SharableWidgetProvider provider : result) { + if (!LocalWidgetFilter.getInstance().shouldShow(provider)) { + result = ArrayUtils.removeElement(result, provider); + } + } + return result; + } + + public boolean hasFilter() { + return filterList != null && filterList.size() != 0; + } + + private boolean filterType(WidgetFilterInfo filterInfo, DefaultSharableWidget bindInfo) { + //图表报表类型 + if (StringUtils.equals(filterInfo.getType(), "chart") | StringUtils.equals(filterInfo.getType(), "report")) { + //图表、报表类型改名之后的兼容 + if (sameType(filterInfo, bindInfo)) { + return true; + } + return StringUtils.equals(bindInfo.getChildClassify(), filterInfo.getName()); + } + return false; + } + + private boolean filterDisplayDevice(WidgetFilterInfo filterInfo, DefaultSharableWidget bindInfo) { + if (StringUtils.equals(filterInfo.getType(), "displayDevice")) { + boolean sameMobile = StringUtils.equals(filterInfo.getName(), "移动端") & DisplayDevice.supportMobile(bindInfo.getDisplayDevice()); + boolean samePC = StringUtils.equals(filterInfo.getName(), "PC端") & DisplayDevice.supportPC(bindInfo.getDisplayDevice()); + //filterInfo的设备信息 = bindInfo的设备信息,为true + return sameMobile | samePC; + } + return false; + } + + private boolean filterSource(WidgetFilterInfo filterInfo, DefaultSharableWidget bindInfo) { + if (StringUtils.equals(filterInfo.getType(), "source")) { + boolean sameMarket = StringUtils.equals(filterInfo.getName(), "商城") && StringUtils.equals(bindInfo.getSource(), DefaultSharableWidget.MARKET); + boolean sameLocal = StringUtils.equals(filterInfo.getName(), "本地") && StringUtils.equals(bindInfo.getSource(), DefaultSharableWidget.LOCAL); + return sameMarket | sameLocal; + } + return false; + } + + private boolean sameType(WidgetFilterInfo filterInfo, DefaultSharableWidget bindInfo) { + //旧:其他 新:其它图表 + boolean other = StringUtils.equals(filterInfo.getName(), Toolkit.i18nText("Fine-Design_Share_Type_Chart_Other")) + && (StringUtils.equals(bindInfo.getChildClassify(), Toolkit.i18nText("Fine-Design_Share_Type_Chart_Other")) + || StringUtils.equals(bindInfo.getChildClassify(), Toolkit.i18nText("Fine-Design_Share_Type_Others"))); + + //旧:移动维度切换 新:多维度切换 + boolean dimensionChange = StringUtils.equals(filterInfo.getName(), Toolkit.i18nText("Fine-Design_Share_Type_Dimension_Change")) + && (StringUtils.equals(bindInfo.getChildClassify(), Toolkit.i18nText("Fine-Design_Share_Type_Mobile_Dimension_Change")) + || StringUtils.equals(bindInfo.getChildClassify(), Toolkit.i18nText("Fine-Design_Share_Type_Dimension_Change"))); + + //旧:移动填报 新:填报 + boolean fill = StringUtils.equals(filterInfo.getName(), Toolkit.i18nText("Fine-Design_Share_Type_Fill")) + && (StringUtils.equals(bindInfo.getChildClassify(), Toolkit.i18nText("Fine-Design_Share_Type_Fill")) + || StringUtils.equals(bindInfo.getChildClassify(), Toolkit.i18nText("Fine-Design_Share_Type_Mobile_Fill"))); + + return other | dimensionChange | fill; + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/widgetfilter/LocalWidgetFilterCategory.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/widgetfilter/LocalWidgetFilterCategory.java new file mode 100644 index 000000000..9e5d4f34e --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/widgetfilter/LocalWidgetFilterCategory.java @@ -0,0 +1,82 @@ +package com.fr.design.mainframe.share.ui.widgetfilter; + +import com.fr.form.share.bean.WidgetFilterInfo; +import com.fr.form.share.bean.WidgetFilterTypeInfo; + +import java.util.ArrayList; +import java.util.List; + +/** + * @Author: Yuan.Wang + * @Date: 2020/11/12 + */ +public class LocalWidgetFilterCategory { + + public static List getLocalCategory() { + List category = new ArrayList<>(); + + WidgetFilterTypeInfo source = new WidgetFilterTypeInfo(); + source.setTitle("来源"); + source.setKey("2@source"); + source.addFilterItem(new WidgetFilterInfo("本地", "1", "source")); + source.addFilterItem(new WidgetFilterInfo("商城", "2", "source")); + source.addFilterItem(new WidgetFilterInfo("全部", "0", "source")); + + WidgetFilterTypeInfo displayDevice = new WidgetFilterTypeInfo(); + displayDevice.setTitle("展示终端"); + displayDevice.setKey("1@displayDevice"); + displayDevice.addFilterItem(new WidgetFilterInfo("PC端", "1", "displayDevice")); + displayDevice.addFilterItem(new WidgetFilterInfo("移动端", "2", "displayDevice")); + displayDevice.addFilterItem(new WidgetFilterInfo("全部", "0", "displayDevice")); + + WidgetFilterTypeInfo fee = new WidgetFilterTypeInfo(); + fee.setTitle("价格"); + fee.setKey("2@fee"); + fee.addFilterItem(new WidgetFilterInfo("付费", "2", "fee")); + fee.addFilterItem(new WidgetFilterInfo("免费", "1", "fee")); + fee.addFilterItem(new WidgetFilterInfo("全部", "0", "fee")); + + WidgetFilterTypeInfo chart = new WidgetFilterTypeInfo(); + chart.setTitle("基础元素"); + chart.setKey("3@chart"); + chart.addFilterItem(new WidgetFilterInfo("柱形图/条形图", "1", "chart")); + chart.addFilterItem(new WidgetFilterInfo("折线图", "3", "chart")); + chart.addFilterItem(new WidgetFilterInfo("组合图", "4", "chart")); + chart.addFilterItem(new WidgetFilterInfo("饼图", "2", "chart")); + chart.addFilterItem(new WidgetFilterInfo("仪表盘", "5", "chart")); + chart.addFilterItem(new WidgetFilterInfo("地图", "6", "chart")); + chart.addFilterItem(new WidgetFilterInfo("其他图表", "7", "chart")); + chart.addFilterItem(new WidgetFilterInfo("明细表", "8", "chart")); + chart.addFilterItem(new WidgetFilterInfo("基础控件", "9", "chart")); + chart.addFilterItem(new WidgetFilterInfo("全部", "0", "chart")); + + WidgetFilterTypeInfo report = new WidgetFilterTypeInfo(); + report.setTitle("综合应用"); + report.setKey("4@report"); + report.addFilterItem(new WidgetFilterInfo("指标卡", "1", "report")); + report.addFilterItem(new WidgetFilterInfo("标题头", "2", "report")); + report.addFilterItem(new WidgetFilterInfo("特殊功能卡", "4", "report")); + report.addFilterItem(new WidgetFilterInfo("多维度切换", "5", "report")); + report.addFilterItem(new WidgetFilterInfo("移动目录导航", "6", "report")); + report.addFilterItem(new WidgetFilterInfo("填报", "8", "report")); + report.addFilterItem(new WidgetFilterInfo("全部", "0", "report")); + + WidgetFilterTypeInfo style = new WidgetFilterTypeInfo(); + style.setTitle("风格"); + style.setKey("5@style"); + style.addFilterItem(new WidgetFilterInfo("简约清新", "1", "style")); + style.addFilterItem(new WidgetFilterInfo("商务稳重", "2", "style")); + style.addFilterItem(new WidgetFilterInfo("活泼绚丽", "3", "style")); + style.addFilterItem(new WidgetFilterInfo("酷炫科技", "4", "style")); + style.addFilterItem(new WidgetFilterInfo("其他风格", "5", "style")); + style.addFilterItem(new WidgetFilterInfo("全部", "0", "style")); + + category.add(displayDevice); + category.add(source); + category.add(chart); + category.add(report); + return category; + + } + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/widgetfilter/OnlineFilterPopupPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/widgetfilter/OnlineFilterPopupPane.java new file mode 100644 index 000000000..2543b4a77 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/widgetfilter/OnlineFilterPopupPane.java @@ -0,0 +1,23 @@ +package com.fr.design.mainframe.share.ui.widgetfilter; + +import com.fr.form.share.bean.WidgetFilterTypeInfo; +import com.fr.form.share.utils.ShareUtils; + +import java.util.List; + +/** + * @Author: Yuan.Wang + * @Date: 2020/11/11 + */ +public class OnlineFilterPopupPane extends FilterPopupPane { + + public OnlineFilterPopupPane(FilterPane filterPane, List widgetFilterCategories) { + super(filterPane, widgetFilterCategories); + } + + protected String assembleFilter() { + return ShareUtils.assembleFilter(getFilterList()); + } + + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/util/DownloadUtils.java b/designer-form/src/main/java/com/fr/design/mainframe/share/util/DownloadUtils.java new file mode 100644 index 000000000..93a8f73b0 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/util/DownloadUtils.java @@ -0,0 +1,143 @@ +package com.fr.design.mainframe.share.util; + +import com.fr.config.MarketConfig; +import com.fr.design.extra.PluginConstants; +import com.fr.form.share.base.CancelCheck; +import com.fr.form.share.constants.ShareComponentConstants; +import com.fr.general.CloudCenter; +import com.fr.log.FineLoggerFactory; +import com.fr.stable.ProductConstants; +import com.fr.stable.StableUtils; +import com.fr.third.org.apache.http.HttpEntity; +import com.fr.third.org.apache.http.HttpException; +import com.fr.third.org.apache.http.HttpStatus; +import com.fr.third.org.apache.http.client.config.CookieSpecs; +import com.fr.third.org.apache.http.client.config.RequestConfig; +import com.fr.third.org.apache.http.client.methods.CloseableHttpResponse; +import com.fr.third.org.apache.http.client.methods.HttpUriRequest; +import com.fr.third.org.apache.http.client.methods.RequestBuilder; +import com.fr.third.org.apache.http.impl.client.BasicCookieStore; +import com.fr.third.org.apache.http.impl.client.CloseableHttpClient; +import com.fr.third.org.apache.http.impl.client.HttpClients; +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.InputStream; + +/** + * created by Harrison on 2020/05/27 + **/ +public class DownloadUtils { + private static final String MARKET_LOGIN_URL = CloudCenter.getInstance().acquireUrlByKind("market.login"); + private static final String REUSES_URL = CloudCenter.getInstance().acquireUrlByKind("af.reuseInfo") + "file/"; + private static final String PACKAGE_REUSES_URL = CloudCenter.getInstance().acquireUrlByKind("af.reuseInfo") + "package/download/"; + + + public static boolean login(CloseableHttpClient client) throws Exception { + + HttpUriRequest login = RequestBuilder.post() + .setUri(MARKET_LOGIN_URL) + .setHeader("User-Agent", "Mozilla/5.0") + .addParameter("username", MarketConfig.getInstance().getBbsUsername()) + .addParameter("password", MarketConfig.getInstance().getBbsPassword()) + .build(); + CloseableHttpResponse loginResponse = client.execute(login); + return loginResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK; + } + + private static CloseableHttpClient createClient() { + + BasicCookieStore cookieStore = new BasicCookieStore(); + return HttpClients.custom() + .setDefaultRequestConfig(RequestConfig.custom() + .setCookieSpec(CookieSpecs.STANDARD).build()) + .setDefaultCookieStore(cookieStore) + .build(); + } + + @NotNull + public static String download(String id, String fileName, com.fr.design.extra.Process process) throws Exception { + CloseableHttpResponse fileRes = getHttpResponse(REUSES_URL, id); + if (fileRes.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { + + String realPath = StableUtils.pathJoin(ProductConstants.getEnvHome(), ShareComponentConstants.PLUGIN_CACHE, ShareComponentConstants.DOWNLOAD_SHARE); + String filePath; + + HttpEntity entity = fileRes.getEntity(); + long totalSize = entity.getContentLength(); + + InputStream content = entity.getContent(); + filePath = StableUtils.pathJoin(realPath, fileName + ".reu"); + StableUtils.makesureFileExist(new File(filePath)); + FileOutputStream writer = new FileOutputStream(filePath); + byte[] data = new byte[PluginConstants.BYTES_NUM]; + int bytesRead; + int totalBytesRead = 0; + + while ((bytesRead = content.read(data)) > 0) { + writer.write(data, 0, bytesRead); + data = new byte[PluginConstants.BYTES_NUM]; + totalBytesRead += bytesRead; + process.process(totalBytesRead / (double) totalSize); + } + content.close(); + writer.flush(); + writer.close(); + FineLoggerFactory.getLogger().info("download widget{} success", id); + return filePath; + } else { + FineLoggerFactory.getLogger().info("download widget{} failed", id); + throw new HttpException(); + } + } + + public static String downloadPackage(String id, String fileName, CancelCheck cancelCheck) throws Exception { + + CloseableHttpResponse fileRes = getHttpResponse(PACKAGE_REUSES_URL, id); + + String realPath = StableUtils.pathJoin(ProductConstants.getEnvHome(), ShareComponentConstants.PLUGIN_CACHE, ShareComponentConstants.DOWNLOAD_PACKAGE_SHARE); + String filePath; + if (fileRes.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { + HttpEntity entity = fileRes.getEntity(); + filePath = StableUtils.pathJoin(realPath, fileName + ".reus"); + StableUtils.makesureFileExist(new File(filePath)); + + InputStream content = entity.getContent(); + FileOutputStream writer = new FileOutputStream(filePath); + + byte[] data = new byte[PluginConstants.BYTES_NUM * 20]; + int bytesRead; + + while (!cancelCheck.isCanceled() && (bytesRead = content.read(data)) > 0) { + writer.write(data, 0, bytesRead); + data = new byte[PluginConstants.BYTES_NUM * 20]; + } + + content.close(); + writer.flush(); + writer.close(); + if (cancelCheck.isCanceled()) { + FineLoggerFactory.getLogger().info("download widget{} canceled", id); + } else { + FineLoggerFactory.getLogger().info("download widget{} failed", id); + } + return filePath; + } else { + FineLoggerFactory.getLogger().info("download widget{} failed", id); + throw new HttpException(); + } + } + + private static CloseableHttpResponse getHttpResponse(String url, String id) throws Exception { + //先登录一下。不然可能失败 + CloseableHttpClient client = createClient(); + FineLoggerFactory.getLogger().info("login fr-market"); + login(client); + FineLoggerFactory.getLogger().info("start download widget {}", id); + HttpUriRequest file = RequestBuilder.get() + .setUri(url + id) + .build(); + return client.execute(file); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/util/InstallComponentHelper.java b/designer-form/src/main/java/com/fr/design/mainframe/share/util/InstallComponentHelper.java new file mode 100644 index 000000000..8e4de49f3 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/util/InstallComponentHelper.java @@ -0,0 +1,64 @@ +package com.fr.design.mainframe.share.util; + +import com.fr.design.mainframe.share.ui.menu.SnapChatKeys; +import com.fr.design.notification.SnapChat; +import com.fr.design.notification.SnapChatFactory; +import com.fr.form.share.constants.ComponentPath; +import com.fr.form.share.group.filter.DirFilter; +import com.fr.form.share.group.filter.ReuFilter; +import com.fr.io.utils.ResourceIOUtils; +import com.fr.log.FineLoggerFactory; +import com.fr.stable.ArrayUtils; +import com.fr.stable.StableUtils; +import com.fr.workspace.WorkContext; + +import java.io.InputStream; + +/** + * @Author: Yuan.Wang + * @Date: 2020/12/4 + */ +public class InstallComponentHelper { + + private static final String PRE_INSTALL_PATH = "/com/fr/form/share/components"; + private static final String[] PRE_INSTALL_COMPONENTS = new String[]{ + "大屏标题-蓝白.739e7afd-ce1d-40ea-b272-3c96eacc27f8.reu", + "单数据指标卡-绿色.48ea0497-1c7f-4894-a927-0f18fe4d2f27.reu", + "单数据指标卡-蓝色.d158c9d6-66be-410a-8697-47b19a8f9565.reu", + "分类对比竖向仪表板-浅色.a90a7b81-26fd-4461-8a39-ce1c07a16ad0.reu", + "分层雷达图-浅色.d2cd7a40-c14c-4a79-a30e-25d2ba555479.reu", + "进度表格-浅色.8aafad8b-d85c-4921-b45d-1acb4c226ca2.reu" + }; + + public static void installPreComponent() { + if (needPreInstallComponent()) { + for (String componentPath : PRE_INSTALL_COMPONENTS) { + try { + InputStream inputStream = InstallComponentHelper.class.getResourceAsStream(StableUtils.pathJoin(PRE_INSTALL_PATH, componentPath)); + byte[] data = ResourceIOUtils.inputStream2Bytes(inputStream); + WorkContext.getWorkResource().write(StableUtils.pathJoin(ComponentPath.SHARE_PATH.path(), componentPath), data); + } catch (Exception e) { + FineLoggerFactory.getLogger().error("install Component filed" + e.getMessage(), e); + } + } + } + + } + + private static boolean needPreInstallComponent() { + //老用户或者组件库里已有组件,不预装组件 + SnapChat snapChat = SnapChatFactory.createSnapChat(false, SnapChatKeys.COMPONENT); + return !snapChat.hasRead() && !hasComponentInstalled(); + } + + /** + * 判断是否已有组件被安装 + */ + private static boolean hasComponentInstalled() { + String sharePath = ComponentPath.SHARE_PATH.path(); + String[] components = WorkContext.getWorkResource().list(sharePath, new ReuFilter()); + String[] dirs = WorkContext.getWorkResource().list(sharePath, new DirFilter()); + return components != null && ArrayUtils.isNotEmpty(components) + || (dirs != null && ArrayUtils.isNotEmpty(dirs)); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/util/InstallUtils.java b/designer-form/src/main/java/com/fr/design/mainframe/share/util/InstallUtils.java new file mode 100644 index 000000000..c25f53f51 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/util/InstallUtils.java @@ -0,0 +1,150 @@ +package com.fr.design.mainframe.share.util; + +import com.fr.form.share.group.DefaultShareGroup; +import com.fr.form.share.group.DefaultShareGroupManager; +import com.fr.form.share.Group; +import com.fr.form.share.group.TempFileOperator; +import com.fr.form.share.utils.ReuxUtils; +import com.fr.form.share.utils.ShareUtils; +import com.fr.io.repository.base.fs.FileSystemRepository; +import com.fr.log.FineLoggerFactory; +import com.fr.stable.ProductConstants; +import com.fr.stable.StableUtils; +import com.fr.stable.project.ProjectConstants; +import org.jetbrains.annotations.Nullable; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +/** + * @Author: Yuan.Wang + * @Date: 2020/12/21 + */ +public class InstallUtils { + + private static final String DOT = "."; + + /** + * 安装组件包 + */ + public static boolean installReusFile(File chosenFile, long installTime, List list) { + return installReusFile(chosenFile, installTime, list, o -> { + //do nothing + }).installStatus; + } + + /** + * 安装组件包 + */ + public static InstallResult installReusFile(File chosenFile, long installTime, List list, com.fr.design.extra.Process process) { + Group group = createComponentGroup(chosenFile.getName()); + if (group == null) { + return new InstallResult(false, null); + } + int totalFileNum; + int installedFileNum = 0; + try (TempFileOperator tempFilOperator = new TempFileOperator(getUnZipCacheDir())) { + File[] files = unZipReuxsFile(chosenFile, tempFilOperator.getTempFilePath()); + totalFileNum = files.length; + boolean installStatus = true; + for (File file : files) { + boolean success = installReuFile(group, file, installTime); + if (!success) { + list.add(getFilePrefix(chosenFile) + ": " + getFilePrefix(file)); + } + installedFileNum++; + process.process(installedFileNum / (double) totalFileNum); + installStatus &= success; + } + return new InstallResult(installStatus, group); + } catch (Exception e) { + process.process(1.0); + FineLoggerFactory.getLogger().error(e.getMessage(), e); + return new InstallResult(false, group); + } + + } + + /** + * 安装组件 + */ + public static boolean installReuFile(File chosenFile, long installTime, List list) { + Group defaultGroup = DefaultShareGroupManager.getInstance().getGroup(DefaultShareGroup.GROUP_NAME); + if (defaultGroup == null) { + return false; + } + boolean success = installReuFile(defaultGroup, chosenFile, installTime); + if (!success) { + list.add(getFilePrefix(chosenFile)); + } + return success; + } + + @Nullable + private static Group createComponentGroup(String fileName) { + String groupName = fileName.substring(0, fileName.indexOf(DOT + ReuxUtils.REUS_SUFFIX)); + + //有重名分组则加后缀 + if (DefaultShareGroupManager.getInstance().getGroup(groupName) != null) { + int suffix = 1; + while (DefaultShareGroupManager.getInstance().getGroup(groupName + suffix) != null) { + suffix++; + } + groupName = groupName + suffix; + } + + if (!DefaultShareGroupManager.getInstance().createGroup(groupName)) { + return null; + } + return DefaultShareGroupManager.getInstance().getGroup(groupName); + } + + private static boolean installReuFile(Group group, File chosenFile, long installTime) { + try { + if (!group.installModule(chosenFile)) { + return false; + } + ShareUtils.recordInstallTime(chosenFile.getName(), installTime); + return true; + } catch (IOException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + return false; + } + } + + private static File[] unZipReuxsFile(File chosenFile, String tempFilePath) throws IOException { + List files = new ArrayList<>(); + ReuxUtils.unzipRueFile(chosenFile, tempFilePath); + String[] components = FileSystemRepository.getSingleton().list(tempFilePath, s -> s.endsWith(ProjectConstants.REU)); + for (String component : components) { + files.add(new File(StableUtils.pathJoin(tempFilePath, component))); + } + return files.toArray(new File[files.size()]); + } + + private static String getUnZipCacheDir() { + return StableUtils.pathJoin(ProductConstants.getEnvHome(), "plugin_cache", "reu_share_temp"); + } + + private static String getFilePrefix(File file) { + String fileName = file.getName(); + return fileName.contains(DOT) ? fileName.substring(0, fileName.indexOf(DOT)) : fileName; + } + + /** + * 安装的返回结果 + */ + public static class InstallResult { + public final boolean installStatus; + public final Group group; + + public InstallResult(boolean installStatus, Group group) { + this.installStatus = installStatus; + this.group = group; + } + } + + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/util/ShareComponentUtils.java b/designer-form/src/main/java/com/fr/design/mainframe/share/util/ShareComponentUtils.java new file mode 100644 index 000000000..abd2c5450 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/util/ShareComponentUtils.java @@ -0,0 +1,93 @@ +package com.fr.design.mainframe.share.util; + +import com.fr.base.io.IOFile; +import com.fr.base.iofile.attr.ExtendSharableAttrMark; +import com.fr.design.designer.creator.XCreator; +import com.fr.design.designer.creator.XCreatorUtils; +import com.fr.design.designer.creator.XLayoutContainer; +import com.fr.design.file.HistoryTemplateListCache; +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.FormSelection; +import com.fr.design.mainframe.JForm; +import com.fr.design.mainframe.JTemplate; +import com.fr.form.share.SharableWidgetProvider; +import com.fr.form.share.bean.ShareLayoutWidget; +import com.fr.form.share.constants.ComponentPath; +import com.fr.form.ui.Widget; +import com.fr.form.ui.container.cardlayout.WCardMainBorderLayout; +import com.fr.stable.StableUtils; +import com.fr.stable.StringUtils; +import com.fr.workspace.WorkContext; +import org.jetbrains.annotations.NotNull; + +import java.awt.Dimension; +import java.awt.Rectangle; + +/** + * Coder: zack + * Date: 2016/9/20 + * Time: 12:00 + */ +public class ShareComponentUtils { + + @NotNull + public static XCreator createXCreator(Widget creatorSource, String shareId, SharableWidgetProvider provider) { + + XCreator xCreator; + if (creatorSource instanceof WCardMainBorderLayout) { + xCreator = XCreatorUtils.createXCreator(creatorSource, new Dimension(500, 300)); + } else if (creatorSource instanceof ShareLayoutWidget) { + xCreator = XCreatorUtils.createXCreator(((ShareLayoutWidget) creatorSource).getWidget(), new Dimension(provider.getWidth(), provider.getHeight())); + } else { + xCreator = XCreatorUtils.createXCreator(creatorSource, new Dimension(provider.getWidth(), provider.getHeight())); + } + xCreator.setBackupBound(new Rectangle(provider.getWidth(), provider.getHeight())); + xCreator.setShareId(shareId); + return xCreator; + } + + /** + * 检查readme.txt文件 + */ + public static void checkReadMe() { + String shareDir = ComponentPath.SHARE_PATH.path(); + String readmePath = StableUtils.pathJoin(shareDir, "readme.txt"); + if (WorkContext.getWorkResource().exist(readmePath)) { + return; + } + String msg = Toolkit.i18nText("Fine-Design_Share_Share_Read_Me_Tip"); + WorkContext.getWorkResource().write(readmePath, msg.getBytes()); + } + + public static String getWidgetId(Widget widget) { + if (StringUtils.isEmpty(widget.getWidgetID())) { + // 做下兼容处理,之前的插件创建的组件没有对应的widgetId + return widget.getWidgetName(); + } + return widget.getWidgetID(); + } + + public static String getCurrentTemplateID() { + JTemplate jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + IOFile target = (IOFile) jt.getTarget(); + return target.getTemplateID(); + } + + public static boolean isShareWidget(XCreator xCreator) { + if (xCreator == null) { + return false; + } + if (xCreator.isShared()) { + return true; + } + if (xCreator instanceof XLayoutContainer) { + XLayoutContainer xLayoutContainer = (XLayoutContainer) xCreator; + ExtendSharableAttrMark sharableAttrMark = xLayoutContainer.toData().getWidgetAttrMark(ExtendSharableAttrMark.XML_TAG); + return sharableAttrMark != null && StringUtils.isNotEmpty(sharableAttrMark.getShareId()); + } + return false; + } + + + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/util/ShareUIUtils.java b/designer-form/src/main/java/com/fr/design/mainframe/share/util/ShareUIUtils.java new file mode 100644 index 000000000..204553f1d --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/util/ShareUIUtils.java @@ -0,0 +1,189 @@ +package com.fr.design.mainframe.share.util; + +import com.fr.design.dialog.FineJOptionPane; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.DesignerContext; +import com.fr.invoke.Reflect; +import com.fr.log.FineLoggerFactory; +import com.fr.stable.ArrayUtils; +import com.fr.third.net.sf.cglib.proxy.Callback; +import com.fr.third.net.sf.cglib.proxy.CallbackFilter; +import com.fr.third.net.sf.cglib.proxy.Enhancer; +import com.fr.third.net.sf.cglib.proxy.MethodInterceptor; +import com.fr.third.net.sf.cglib.proxy.MethodProxy; +import com.fr.third.net.sf.cglib.proxy.NoOp; +import org.jetbrains.annotations.NotNull; + +import javax.swing.AbstractButton; +import javax.swing.JComponent; +import javax.swing.SwingConstants; +import javax.swing.plaf.ComponentUI; +import java.awt.Graphics; +import java.awt.event.ActionEvent; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; + +/** + * created by Harrison on 2020/04/20 + **/ +public class ShareUIUtils { + + private static final String PAINT_METHOD = "paint"; + + private static final String widthStyle = "%s"; + + /** + * 停止当前线程 xx s + * + * @param limit 限制 + * @throws InterruptedException 中断异常 + */ + public static void wait(int limit) throws InterruptedException { + + long start = System.currentTimeMillis(); + while (System.currentTimeMillis() - start < limit) { + Thread.sleep(50); + } + } + + public static String formatWidthString(String msg, int width) { + + return String.format(widthStyle, width, msg); + } + + public static UILabel createTipsLabel(String msg) { + + String tips = "" + msg + ""; + return new UILabel(tips); + } + + public static UILabel createTopRightUILabel(String msg) { + + UILabel label = new UILabel(msg, SwingConstants.RIGHT); + label.setVerticalAlignment(SwingConstants.TOP); + return label; + } + + public static UILabel createCenterRightUILabel(String msg) { + + UILabel label = new UILabel(msg, SwingConstants.RIGHT); + label.setVerticalAlignment(SwingConstants.CENTER); + return label; + } + + public static UILabel createHyperlinkLabel(String msg) { + + String hyperlink = ("") + msg + ""; + return new UILabel(hyperlink); + } + + public static String convertStateChange(int stateChange) { + + return String.valueOf(stateChange); + } + + public static void simulateAction(AbstractButton button) { + + ActionEvent event = new ActionEvent(button, + ActionEvent.ACTION_PERFORMED, + button.getActionCommand()); + button.dispatchEvent(event); + } + + public static T wrapUI(final ComponentUI newUI, final T component, Object... constructArgs) { + + try { + return warpUI0(newUI, component, constructArgs); + } catch (Exception e) { + //虽然没渲染上,但是不影响使用。 使用 warn 吧 + FineLoggerFactory.getLogger().warn(e.getMessage(), e); + return component; + } + } + + @SuppressWarnings("unchecked") + private static T warpUI0(final ComponentUI newUI, final T component, Object... constructArgs) throws NoSuchMethodException { + + Enhancer enhancer = new Enhancer(); + enhancer.setSuperclass(component.getClass()); + enhancer.setCallbacks(new Callback[]{ + NoOp.INSTANCE, + new MethodInterceptor() { + @Override + public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { + + Object value = methodProxy.invokeSuper(o, objects); + newUI.paint((Graphics) objects[0], component); + return value; + } + } + }); + enhancer.setCallbackFilter(new CallbackFilter() { + @Override + public int accept(Method method) { + return method.getName().equals(PAINT_METHOD) ? 1 : 0; + } + }); + + + Constructor constructor = constructor(component.getClass(), constructArgs); + if (constructArgs.length == 0 || constructor == null) { + return (T) enhancer.create(); + } + return (T) enhancer.create(constructor.getParameterTypes(), constructArgs); + } + + + public static Constructor constructor(Class type, Object... args) { + + Class[] types = argumentTypes(args); + try { + return type.getDeclaredConstructor(types); + } catch (NoSuchMethodException e) { + for (Constructor constructor : type.getDeclaredConstructors()) { + if (match(constructor.getParameterTypes(), types)) { + return constructor; + } + } + } + return null; + } + + public static void showErrorMessageDialog(String message) { + FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), + message, + Toolkit.i18nText("Fine-Design_Share_Dialog_Message"), + FineJOptionPane.ERROR_MESSAGE); + } + + private static boolean match(Class[] declaredTypes, Class[] actualTypes) { + if (declaredTypes.length == actualTypes.length) { + for (int i = 0; i < actualTypes.length; i++) { + if (Reflect.wrapper(declaredTypes[i]).isAssignableFrom(Reflect.wrapper(actualTypes[i]))) { + continue; + } + return false; + } + return true; + } else { + return false; + } + } + + @NotNull + private static Class[] argumentTypes(Object[] constructArgs) { + + if (ArrayUtils.isEmpty(constructArgs)) { + return new Class[0]; + } + int length = constructArgs.length; + Class[] classes = new Class[length]; + for (int i = 0; i < length; i++) { + classes[i] = constructArgs[i].getClass(); + } + return classes; + } + + +} diff --git a/designer-form/src/test/java/com/fr/design/mainframe/ShareWidgetButtonTest.java b/designer-form/src/test/java/com/fr/design/mainframe/ShareWidgetButtonTest.java deleted file mode 100644 index 50f8afc18..000000000 --- a/designer-form/src/test/java/com/fr/design/mainframe/ShareWidgetButtonTest.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.fr.design.mainframe; - -import com.fr.chart.chartattr.ChartCollection; -import com.fr.design.designer.creator.XCreator; -import com.fr.form.share.SharableWidgetProvider; -import com.fr.form.ui.ChartEditor; -import com.fr.general.ImageWithSuffix; -import com.fr.invoke.Reflect; -import org.easymock.EasyMock; -import org.junit.Assert; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.powermock.core.classloader.annotations.PowerMockIgnore; -import org.powermock.modules.junit4.PowerMockRunner; - -@RunWith(PowerMockRunner.class) -@PowerMockIgnore({"com.fr.jvm.assist.*", "javax.swing.*"}) -public class ShareWidgetButtonTest { - - @Test - public void testCreateXCreator() throws Exception { - - SharableWidgetProvider provider = EasyMock.mock(SharableWidgetProvider.class); - EasyMock.expect(provider.getWidth()).andReturn(300).anyTimes(); - EasyMock.expect(provider.getHeight()).andReturn(400).anyTimes(); - EasyMock.expect(provider.getName()).andReturn("test-drag").anyTimes(); - EasyMock.expect(provider.getCover()).andReturn(new ImageWithSuffix("utf-8")).anyTimes(); - EasyMock.replay(provider); - - ShareWidgetButton.ShareWidgetUI ui = new ShareWidgetButton.ShareWidgetUI(); - - ChartEditor editor = new ChartEditor(); - Reflect.on(editor).set("chartCollection", new ChartCollection()); - XCreator xCreator = ui.createXCreator(editor, "333", provider); - Assert.assertEquals(300, xCreator.getWidth()); - Assert.assertEquals(400, xCreator.getHeight()); - } -} \ No newline at end of file diff --git a/designer-realize/src/main/java/com/fr/design/share/effect/BaseEffectItem.java b/designer-realize/src/main/java/com/fr/design/share/effect/BaseEffectItem.java new file mode 100644 index 000000000..20d562621 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/effect/BaseEffectItem.java @@ -0,0 +1,115 @@ +package com.fr.design.share.effect; + +import com.fr.design.beans.BasicBeanPane; +import com.fr.design.gui.controlpane.NameableCreator; +import com.fr.design.share.effect.source.SourceNode; +import com.fr.stable.StringUtils; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; + +public class BaseEffectItem implements EffectItem{ + private String name = StringUtils.EMPTY; + private String description = StringUtils.EMPTY; + private NameableCreator creator; + private T object; + private SourceNode sourceNode; + + @Override + public SourceNode getSourceNode() { + return sourceNode; + } + + @Override + public String getConfigPath() { + return getSourceNode().toString(); + } + + public void setSourceNode(SourceNode sourceNode) { + this.sourceNode = sourceNode; + } + + @Override + public String getName() { + return name; + } + + @Override + public void setName(String name) { + this.name = name; + } + + @Override + public String getDescription() { + return description; + } + + @Override + public void setDescription(String description) { + this.description = description; + } + + + @Override + public void save() { + + } + + @Override + public Object getPopulateBean(){ + return getObject(); + } + + @Override + public void updateBean(Object bean) { + + } + + @Override + public T getObject() { + return object; + } + + @Override + public void setObject(T ob) { + this.object = ob; + } + + @Override + public NameableCreator creator() { + return this.creator; + } + + public void setNameableCreator(NameableCreator creator) { + this.creator = creator; + } + + @Override + public BasicBeanPane createPaneByCreators(NameableCreator creator) { + try { + return creator.getUpdatePane().newInstance(); + } catch (InstantiationException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + } + + @Override + public BasicBeanPane createPaneByCreators(NameableCreator creator, String string) { + Constructor constructor; + 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); + } + } +} diff --git a/designer-realize/src/main/java/com/fr/design/share/effect/ConditionEffectItem.java b/designer-realize/src/main/java/com/fr/design/share/effect/ConditionEffectItem.java new file mode 100644 index 000000000..ea5096085 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/effect/ConditionEffectItem.java @@ -0,0 +1,86 @@ +package com.fr.design.share.effect; + +import com.fr.chart.chartattr.Plot; +import com.fr.chart.chartglyph.ConditionAttr; +import com.fr.design.ChartTypeInterfaceManager; +import com.fr.design.beans.BasicBeanPane; +import com.fr.design.condition.ConditionAttributesPane; +import com.fr.design.gui.controlpane.NameObjectCreator; +import com.fr.design.gui.controlpane.NameableCreator; +import com.fr.design.share.effect.source.SourceNode; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; + +public class ConditionEffectItem extends BaseEffectItem { + private ConditionAttr condition; + private Plot plot; + public ConditionEffectItem(ConditionAttr condition, SourceNode sourceNode, Plot plot) { + this.condition = condition; + this.plot = plot; + this.setSourceNode(sourceNode); + init(); + } + + private void init() { + ConditionAttr object; + try { + object = (ConditionAttr) condition.clone(); + } catch (CloneNotSupportedException e) { + object = new ConditionAttr(); + object.setName(condition.getName()); + object.setCondition(condition.getCondition()); + for (int i = 0; i < condition.getDataSeriesConditionCount(); i++) { + object.addDataSeriesCondition(condition.getDataSeriesCondition(i)); + } + } + setObject(object); + this.setName(condition.getName()); + this.setNameableCreator(new NameObjectCreator(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Condition_Attributes"), ConditionAttr.class, getPlotConditionPane(this.plot))); + } + + private Class getPlotConditionPane(Plot plot) { + return ChartTypeInterfaceManager.getInstance().getPlotConditionPane(plot).getClass(); + } + + @Override + public void setName(String name) { + super.setName(name); + getObject().setName(name); + } + + @Override + public BasicBeanPane createPaneByCreators(NameableCreator creator) { + Constructor constructor = null; + try { + constructor = creator.getUpdatePane().getConstructor(Plot.class); + return constructor.newInstance(this.plot); + + } catch (InstantiationException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } + return null; + } + + @Override + public void updateBean(Object bean) { + ConditionAttr conditionAttr = (ConditionAttr) bean; + conditionAttr.setName(this.getName()); + setObject(conditionAttr); + } + + public void save() { + condition.setName(getObject().getName()); + condition.setCondition(getObject().getCondition()); + condition.removeAll(); + for (int i = 0; i < getObject().getDataSeriesConditionCount(); i++) { + condition.addDataSeriesCondition(getObject().getDataSeriesCondition(i)); + } + } +} diff --git a/designer-realize/src/main/java/com/fr/design/share/effect/EffectItem.java b/designer-realize/src/main/java/com/fr/design/share/effect/EffectItem.java new file mode 100644 index 000000000..33bfe7fe5 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/effect/EffectItem.java @@ -0,0 +1,32 @@ +package com.fr.design.share.effect; + +import com.fr.design.beans.BasicBeanPane; +import com.fr.design.gui.controlpane.NameableCreator; +import com.fr.design.share.effect.source.SourceNode; +import com.fr.stable.Nameable; + +public interface EffectItem extends Nameable { + SourceNode getSourceNode(); + + String getConfigPath(); + + String getDescription(); + + void setDescription(String description); + + T getObject(); + + void setObject(T ob); + + Object getPopulateBean(); + + void save(); + + void updateBean(Object bean); + + NameableCreator creator(); + + BasicBeanPane createPaneByCreators(NameableCreator creator); + + BasicBeanPane createPaneByCreators(NameableCreator creator, String string); +} diff --git a/designer-realize/src/main/java/com/fr/design/share/effect/EffectItemGroup.java b/designer-realize/src/main/java/com/fr/design/share/effect/EffectItemGroup.java new file mode 100644 index 000000000..923c200d1 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/effect/EffectItemGroup.java @@ -0,0 +1,279 @@ +package com.fr.design.share.effect; + +import com.fr.chart.chartattr.Chart; +import com.fr.chart.chartattr.ChartCollection; +import com.fr.chart.chartattr.Plot; +import com.fr.chart.chartglyph.ConditionCollection; +import com.fr.chartx.attr.ChartProvider; +import com.fr.design.share.effect.source.SourceNode; +import com.fr.design.share.effect.source.SourceNodeUtils; +import com.fr.form.FormElementCaseProvider; +import com.fr.form.event.Listener; +import com.fr.form.ui.ChartEditor; +import com.fr.form.ui.ElementCaseEditor; +import com.fr.form.ui.Widget; +import com.fr.form.ui.container.WTitleLayout; +import com.fr.js.NameJavaScript; +import com.fr.js.NameJavaScriptGroup; +import com.fr.plugin.chart.attr.axis.VanChartAlertValue; +import com.fr.plugin.chart.attr.axis.VanChartAxis; +import com.fr.plugin.chart.attr.plot.VanChartPlot; +import com.fr.plugin.chart.attr.plot.VanChartRectanglePlot; +import com.fr.plugin.chart.custom.VanChartCustomPlot; +import com.fr.report.cell.DefaultTemplateCellElement; +import com.fr.report.cell.cellattr.highlight.DefaultHighlight; +import com.fr.report.cell.cellattr.highlight.HighlightGroup; +import com.fr.report.web.util.ReportEngineEventMapping; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; + +public class EffectItemGroup { + private List conditionEffectItems = new ArrayList(); + private List highlightEffectItems = new ArrayList(); + private List hyperlinkEffectItems = new ArrayList(); + private List listenerEffectItems = new ArrayList(); + private List stackAndAxisConditionEffectItems = new ArrayList(); + private List vanChartAlertValueEffectItems = new ArrayList(); + private List effectItems = new ArrayList(); + private LinkedHashMap> effectItemsMap; + private Widget widget; + + public EffectItemGroup() { + + } + + public EffectItemGroup(Widget widget) { + this.widget = widget; + initListener(widget); + if (widget instanceof WTitleLayout) { + WTitleLayout wTitleLayout = (WTitleLayout) widget; + this.widget = wTitleLayout.getBodyBoundsWidget().getWidget(); + if (this.widget instanceof ElementCaseEditor) { + initElementCase(); + } else if (this.widget instanceof ChartEditor) { + initChartEditor(); + } + } + } + + public Widget getWidget() { + return widget; + } + + private void initListener(Widget widget) { + int listenerSize = widget.getListenerSize(); + for (int index = 0; index < listenerSize; index ++) { + Listener listener = widget.getListener(index); + SourceNode sourceNode = SourceNodeUtils.createSourceNode(widget, null); + String eventName = switchLang(listener.getEventName()) + (index + 1); + this.add(new ListenerEffectItem(listener, sourceNode, eventName)); + } + } + + private String switchLang(String eventName) { + // 在 properties 文件中找到相应的 key 值 + String localeKey = ReportEngineEventMapping.getLocaleName(eventName); + return com.fr.design.i18n.Toolkit.i18nText(localeKey); + } + + private void initElementCase() { + ElementCaseEditor editor = (ElementCaseEditor) this.widget; + FormElementCaseProvider elementCase = editor.getElementCase(); + Iterator cellIterator = elementCase.cellIterator(); + + while(cellIterator.hasNext()) { + DefaultTemplateCellElement cellElement = (DefaultTemplateCellElement) cellIterator.next(); + SourceNode cellSourceNode = SourceNodeUtils.createSourceNode(cellElement, null); + + // 条件属性 + if (cellElement.getHighlightGroup() != null) { + HighlightGroup highlightGroup = cellElement.getHighlightGroup(); + for (int index = 0; index < highlightGroup.size(); index ++) { + DefaultHighlight highlight=(DefaultHighlight) highlightGroup.getHighlight(index); + this.add(new HighlightEffectItem(highlight, cellSourceNode)); + } + } + + // 超链 + if (cellElement.getNameHyperlinkGroup() != null) { + NameJavaScriptGroup nameHyperlinkGroup = cellElement.getNameHyperlinkGroup(); + for (int index = 0; index < nameHyperlinkGroup.size(); index ++) { + NameJavaScript nameJavaScript = nameHyperlinkGroup.getNameHyperlink(index); + this.add(new HyperlinkEffectItem(nameJavaScript, cellSourceNode)); + } + } + + // 图表内部 + Object value = cellElement.getValue(); + if (value instanceof ChartCollection) { + ChartCollection chartCollection = (ChartCollection) value; + for (int index = 0; index < chartCollection.getChartCount(); index++) { + Chart chart= (Chart) chartCollection.getChart(index, ChartProvider.class); + SourceNode chartSourceNode = SourceNodeUtils.createSourceNode(chart.getPlot(), chartCollection.getChartName(index), cellSourceNode); + Plot plot = chart.getPlot(); + initChartPlot(plot, chartSourceNode, false); + } + + } + } + + } + + private void initChartEditor() { + ChartEditor editor = (ChartEditor) this.widget; + ChartCollection chartCollection = (ChartCollection) editor.getChartCollection(); + for (int index = 0; index < chartCollection.getChartCount(); index++) { + Chart chart= (Chart) chartCollection.getChart(index, ChartProvider.class); + SourceNode plotSourceNode = SourceNodeUtils.createSourceNode(chart.getPlot(), chartCollection.getChartName(index), null); + Plot plot = chart.getPlot(); + initChartPlot(plot, plotSourceNode, false); + } + + } + + private void initChartPlot(Plot plot, SourceNode sourceNode, boolean isSubChart) { + if (plot.getConditionCollection() != null) { + // 图表条件属性 + ConditionCollection conditionCollection = plot.getConditionCollection(); + for (int j = 0; j < conditionCollection.getConditionAttrSize(); j ++) { + this.add(new ConditionEffectItem(conditionCollection.getConditionAttr(j), sourceNode, plot)); + } + } + + if (plot.getHotHyperLink() != null) { + // 图表超链 + NameJavaScriptGroup nameHyperlinkGroup = plot.getHotHyperLink(); + for (int j = 0; j < nameHyperlinkGroup.size(); j ++) { + NameJavaScript nameJavaScript = nameHyperlinkGroup.getNameHyperlink(j); + this.add(new HyperlinkEffectItem(nameJavaScript, sourceNode)); + } + } + + if (plot instanceof VanChartRectanglePlot) { + VanChartRectanglePlot rectanglePlot = (VanChartRectanglePlot) plot; + // 堆积和坐标轴 + ConditionCollection stackAndAxisCondition= rectanglePlot.getStackAndAxisCondition(); + + for(int index = 0; index < stackAndAxisCondition.getConditionAttrSize(); index ++) { + this.add(new StackAndAxisConditionEffectItem(stackAndAxisCondition.getConditionAttr(index), sourceNode, (VanChartRectanglePlot) plot)); + } + if (!isSubChart) { + // 警戒线 + List xAxisList = rectanglePlot.getXAxisList(); + List yAxisList = rectanglePlot.getYAxisList(); + for(VanChartAxis axis : xAxisList) { + for(VanChartAlertValue alertValue: axis.getAlertValues()) { + this.add(new VanChartAlertValueEffectItem(alertValue, sourceNode, (VanChartRectanglePlot) plot)); + } + } + for(VanChartAxis axis : yAxisList) { + for(VanChartAlertValue alertValue: axis.getAlertValues()) { + this.add(new VanChartAlertValueEffectItem(alertValue, sourceNode, (VanChartRectanglePlot) plot)); + } + } + } + } + + if (plot instanceof VanChartCustomPlot) { + VanChartCustomPlot customPlot = (VanChartCustomPlot) plot; + List plotList= customPlot.getCustomPlotList(); + for(VanChartPlot innerPlot : plotList) { + initChartPlot(innerPlot, SourceNodeUtils.createSourceNode(innerPlot, sourceNode), true); + } + } + } + + public List getConditionEffectItems() { + return conditionEffectItems; + } + + public List getHighlightEffectItems() { + return highlightEffectItems; + } + + public List getHyperlinkEffectItems() { + return hyperlinkEffectItems; + } + + public List getListenerEffectItems() { + return listenerEffectItems; + } + + public List getStackAndAxisConditionEffectItems() { + return stackAndAxisConditionEffectItems; + } + + public List getVanChartAlertLineEffectItems() { + return vanChartAlertValueEffectItems; + } + + public List getEffectItems() { + return effectItems; + } + + public void add(ConditionEffectItem conditionEffectItem) { + conditionEffectItems.add(conditionEffectItem); + effectItems.add(conditionEffectItem); + } + + public void add(HighlightEffectItem highlightEffectItem) { + highlightEffectItems.add(highlightEffectItem); + effectItems.add(highlightEffectItem); + } + + public void add(HyperlinkEffectItem hyperlinkEffectItem) { + hyperlinkEffectItems.add(hyperlinkEffectItem); + effectItems.add(hyperlinkEffectItem); + } + + public void add(ListenerEffectItem listenerEffectItem) { + listenerEffectItems.add(listenerEffectItem); + effectItems.add(listenerEffectItem); + } + + public void add(StackAndAxisConditionEffectItem stackAndAxisConditionEffectItem) { + stackAndAxisConditionEffectItems.add(stackAndAxisConditionEffectItem); + effectItems.add(stackAndAxisConditionEffectItem); + } + + public void add(VanChartAlertValueEffectItem vanChartAlertLineEffectItem) { + vanChartAlertValueEffectItems.add(vanChartAlertLineEffectItem); + effectItems.add(vanChartAlertLineEffectItem); + } + + public LinkedHashMap> getEffectItemsWithClassify() { + if (effectItemsMap != null) { + return effectItemsMap; + } + effectItemsMap = new LinkedHashMap>(); + + if (listenerEffectItems.size() > 0) { + effectItemsMap.put(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Event"), listenerEffectItems); + } + if (highlightEffectItems.size() > 0 || conditionEffectItems.size() > 0) { + List tmpEffectItems = new ArrayList<>(); + tmpEffectItems.addAll(highlightEffectItems); + tmpEffectItems.addAll(conditionEffectItems); + effectItemsMap.put(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Condition_Attributes"), tmpEffectItems); + } + if (hyperlinkEffectItems.size() > 0) { + effectItemsMap.put(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Hyperlink"), hyperlinkEffectItems); + } + if (vanChartAlertValueEffectItems.size() > 0 || stackAndAxisConditionEffectItems.size() > 0) { + List tmpEffectItems = new ArrayList<>(); + tmpEffectItems.addAll(vanChartAlertValueEffectItems); + tmpEffectItems.addAll(stackAndAxisConditionEffectItems); + effectItemsMap.put(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Other"), tmpEffectItems); + } + return effectItemsMap; + } + + public void save() { + for (EffectItem effectItem : this.effectItems) { + effectItem.save(); + } + } +} diff --git a/designer-realize/src/main/java/com/fr/design/share/effect/HighlightEffectItem.java b/designer-realize/src/main/java/com/fr/design/share/effect/HighlightEffectItem.java new file mode 100644 index 000000000..806e2e51a --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/effect/HighlightEffectItem.java @@ -0,0 +1,56 @@ +package com.fr.design.share.effect; + +import com.fr.design.condition.HighLightConditionAttributesPane; +import com.fr.design.gui.controlpane.NameObjectCreator; +import com.fr.design.share.effect.source.SourceNode; +import com.fr.report.cell.cellattr.highlight.DefaultHighlight; + +public class HighlightEffectItem extends BaseEffectItem{ + private DefaultHighlight highlight; + + public HighlightEffectItem(DefaultHighlight highlight, SourceNode sourceNode) { + this.highlight = highlight; + this.setSourceNode(sourceNode); + this.init(); + } + + private void init() { + DefaultHighlight object; + try { + object = (DefaultHighlight) highlight.clone(); + } catch (CloneNotSupportedException e) { + object = new DefaultHighlight(); + object.setName(highlight.getName()); + object.setCondition(highlight.getCondition()); + for (int i = 0; i < highlight.actionCount(); i++) { + object.addHighlightAction(highlight.getHighlightAction(i)); + } + } + setObject(object); + + this.setName(highlight.getName()); + this.setNameableCreator(new NameObjectCreator(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Condition_Attributes"), DefaultHighlight.class, HighLightConditionAttributesPane.class)); + } + + public void setName(String name) { + super.setName(name); + getObject().setName(name); + } + + @Override + public void updateBean(Object bean) { + DefaultHighlight highlight = (DefaultHighlight) bean; + highlight.setName(this.getName()); + setObject(highlight); + } + + @Override + public void save() { + highlight.setCondition(getObject().getCondition()); + highlight.setName(getObject().getName()); + highlight.removeActions(); + for (int i = 0; i < getObject().actionCount(); i++) { + highlight.addHighlightAction(getObject().getHighlightAction(i)); + } + } +} diff --git a/designer-realize/src/main/java/com/fr/design/share/effect/HyperlinkEffectItem.java b/designer-realize/src/main/java/com/fr/design/share/effect/HyperlinkEffectItem.java new file mode 100644 index 000000000..d7a572664 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/effect/HyperlinkEffectItem.java @@ -0,0 +1,93 @@ +package com.fr.design.share.effect; + +import com.fr.design.ExtraDesignClassManager; +import com.fr.design.form.javascript.FormEmailPane; +import com.fr.design.fun.HyperlinkProvider; +import com.fr.design.gui.controlpane.NameObjectCreator; +import com.fr.design.gui.controlpane.NameableCreator; +import com.fr.design.module.DesignModuleFactory; +import com.fr.design.share.effect.source.SourceNode; +import com.fr.general.ComparatorUtils; +import com.fr.js.EmailJavaScript; +import com.fr.js.JavaScript; +import com.fr.js.NameJavaScript; +import com.fr.stable.ListMap; + +import java.util.Map; +import java.util.Set; + +public class HyperlinkEffectItem extends BaseEffectItem{ + private NameJavaScript javaScript; + + public HyperlinkEffectItem(NameJavaScript javaScript, SourceNode sourceNode) { + this.javaScript = javaScript; + this.setSourceNode(sourceNode); + this.init(); + } + + private void init() { + NameJavaScript object; + try { + object = (NameJavaScript) javaScript.clone(); + } catch (CloneNotSupportedException e) { + object = new NameJavaScript(javaScript.getName(), javaScript.getJavaScript()); + } + setObject(object); + + this.setName(this.javaScript.getName()); + NameableCreator[] creators = createNameableCreator(); + for (NameableCreator creator : creators) { + if (creator.acceptObject2Populate(javaScript.getJavaScript()) != null) { + this.setNameableCreator(creator); + return; + } + } + } + + public void setName(String name) { + super.setName(name); + getObject().setName(name); + } + + private NameableCreator[] createNameableCreator() { + Map nameCreators = new ListMap<>(); + NameableCreator[] creators = DesignModuleFactory.getHyperlinkGroupType().getHyperlinkCreators(); + for (NameableCreator creator : creators) { + nameCreators.put(creator.menuName(), creator); + } + Set providers = ExtraDesignClassManager.getInstance().getArray(HyperlinkProvider.XML_TAG); + for (HyperlinkProvider provider : providers) { + NameableCreator nc = provider.createHyperlinkCreator(); + nameCreators.put(nc.menuName(), nc); + } + + creators = nameCreators.values().toArray(new NameableCreator[nameCreators.size()]); + for (int i = 0; i < creators.length; i++) { + if (ComparatorUtils.equals(creators[i].menuName(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Email"))) { + creators[i] = new NameObjectCreator(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Email"), EmailJavaScript.class, FormEmailPane.class); + break; + } + } + + return creators; + } + + @Override + public Object getPopulateBean() { + return getObject().getObject(); + } + + @Override + public void updateBean(Object bean) { + JavaScript javaScript = (JavaScript) bean; + getObject().setJavaScript(javaScript); + getObject().setObject(bean); + } + + @Override + public void save() { + javaScript.setName(getObject().getName()); + javaScript.setObject(getObject().getObject()); + javaScript.setJavaScript(getObject().getJavaScript()); + } +} diff --git a/designer-realize/src/main/java/com/fr/design/share/effect/ListenerEffectItem.java b/designer-realize/src/main/java/com/fr/design/share/effect/ListenerEffectItem.java new file mode 100644 index 000000000..38d635424 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/effect/ListenerEffectItem.java @@ -0,0 +1,41 @@ +package com.fr.design.share.effect; + +import com.fr.design.designer.properties.EventPropertyTable; +import com.fr.design.share.effect.source.SourceNode; +import com.fr.design.widget.EventCreator; +import com.fr.form.event.Listener; +import com.fr.form.ui.Widget; + +public class ListenerEffectItem extends BaseEffectItem { + private Listener listener; + + public ListenerEffectItem(Listener listener, SourceNode sourceNode, String name) { + this.listener = listener; + this.setSourceNode(sourceNode); + this.setName(name); + init(); + } + + private void init() { + Listener object; + try { + object = (Listener) listener.clone(); + } catch (CloneNotSupportedException e) { + object = new Listener(listener.getTargetWidget(), listener.getEventName(), listener.getAction(), listener.isInvokeOnce()); + } + setObject(object); + this.setNameableCreator(new EventCreator(Widget.EVENT_STATECHANGE, EventPropertyTable.WidgetEventListenerUpdatePane.class)); + } + + @Override + public void updateBean(Object bean) { + setObject((Listener) bean); + } + + public void save() { + listener.setEventName(getObject().getEventName()); + listener.setAction(getObject().getAction()); + listener.setInvokeOnce(getObject().isInvokeOnce()); + listener.setTargetWidget(getObject().getTargetWidget()); + } +} diff --git a/designer-realize/src/main/java/com/fr/design/share/effect/StackAndAxisConditionEffectItem.java b/designer-realize/src/main/java/com/fr/design/share/effect/StackAndAxisConditionEffectItem.java new file mode 100644 index 000000000..a4b8804ae --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/effect/StackAndAxisConditionEffectItem.java @@ -0,0 +1,73 @@ +package com.fr.design.share.effect; + +import com.fr.chart.chartglyph.ConditionAttr; +import com.fr.design.share.effect.source.SourceNode; +import com.fr.plugin.chart.attr.DefaultAxisHelper; +import com.fr.plugin.chart.attr.plot.VanChartRectanglePlot; +import com.fr.plugin.chart.base.AttrSeriesStackAndAxis; +import com.fr.van.chart.column.VanChartCustomStackAndAxisConditionPane; +import com.fr.van.chart.designer.style.series.StackedAndAxisNameObjectCreator; + +public class StackAndAxisConditionEffectItem extends BaseEffectItem { + private ConditionAttr condition; + private VanChartRectanglePlot plot; + + public StackAndAxisConditionEffectItem(ConditionAttr condition, SourceNode sourceNode, VanChartRectanglePlot plot) { + this.condition = condition; + this.plot = plot; + this.setSourceNode(sourceNode); + + init(); + } + + private void init() { + setAxisNamesArray(condition); + + ConditionAttr object; + try { + object = (ConditionAttr) condition.clone(); + } catch (CloneNotSupportedException e) { + object = new ConditionAttr(); + object.setName(condition.getName()); + object.setCondition(condition.getCondition()); + for (int i = 0; i < condition.getDataSeriesConditionCount(); i++) { + object.addDataSeriesCondition(condition.getDataSeriesCondition(i)); + } + } + setObject(object); + + this.setName(condition.getName()); + this.setNameableCreator(new StackedAndAxisNameObjectCreator(new AttrSeriesStackAndAxis(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Stack_And_Series"), ConditionAttr.class, VanChartCustomStackAndAxisConditionPane.class)); + } + + @Override + public void setName(String name) { + super.setName(name); + getObject().setName(name); + } + + @Override + public void updateBean(Object bean) { + ConditionAttr conditionAttr = (ConditionAttr) bean; + conditionAttr.setName(getName()); + setAxisNamesArray(conditionAttr); + setObject(conditionAttr); + } + + public void save() { + condition.setName(getObject().getName()); + condition.setCondition(getObject().getCondition()); + condition.removeAll(); + for (int i = 0; i < getObject().getDataSeriesConditionCount(); i++) { + condition.addDataSeriesCondition(getObject().getDataSeriesCondition(i)); + } + } + + private void setAxisNamesArray(ConditionAttr conditionAttr) { + String[] axisXNames = DefaultAxisHelper.getXAxisNames(plot); + String[] axisYNames = DefaultAxisHelper.getYAxisNames(plot); + AttrSeriesStackAndAxis stackAndAxis = (AttrSeriesStackAndAxis) conditionAttr.getExisted(AttrSeriesStackAndAxis.class); + stackAndAxis.setXAxisNamesArray(axisXNames); + stackAndAxis.setYAxisNameArray(axisYNames); + } +} diff --git a/designer-realize/src/main/java/com/fr/design/share/effect/VanChartAlertValueEffectItem.java b/designer-realize/src/main/java/com/fr/design/share/effect/VanChartAlertValueEffectItem.java new file mode 100644 index 000000000..349ec91eb --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/effect/VanChartAlertValueEffectItem.java @@ -0,0 +1,94 @@ +package com.fr.design.share.effect; + +import com.fr.design.share.effect.source.SourceNode; +import com.fr.plugin.chart.attr.DefaultAxisHelper; +import com.fr.plugin.chart.attr.axis.VanChartAlertValue; +import com.fr.plugin.chart.attr.axis.VanChartAxis; +import com.fr.plugin.chart.attr.plot.VanChartRectanglePlot; +import com.fr.van.chart.designer.style.background.ChartNameObjectCreator; +import com.fr.van.chart.designer.style.background.VanChartAlertValuePane; + +import java.util.List; + +public class VanChartAlertValueEffectItem extends BaseEffectItem { + private VanChartAlertValue alertValue; + private VanChartRectanglePlot plot; + + public VanChartAlertValueEffectItem(VanChartAlertValue alertValue, SourceNode sourceNode, VanChartRectanglePlot plot) { + this.alertValue = alertValue; + this.plot = plot; + this.setSourceNode(sourceNode); + init(); + } + + private void init() { + List xAxisList = plot.getXAxisList(); + List yAxisList = plot.getYAxisList(); + String[] axisNames = DefaultAxisHelper.getAllAxisNames(plot); + for (VanChartAxis axis : xAxisList) { + List values = axis.getAlertValues(); + for (VanChartAlertValue alertValue : values) { + alertValue.setAxisNamesArray(axisNames); + alertValue.setAxisName(plot.getXAxisName(axis)); + } + } + for (VanChartAxis axis : yAxisList) { + List values = axis.getAlertValues(); + for (VanChartAlertValue alertValue : values) { + alertValue.setAxisNamesArray(axisNames); + alertValue.setAxisName(plot.getYAxisName(axis)); + } + } + + VanChartAlertValue object; + try{ + object = (VanChartAlertValue) alertValue.clone(); + }catch (CloneNotSupportedException e) { + object = new VanChartAlertValue(); + object.setAxisNamesArray(alertValue.getAxisNamesArray()); + object.setAxisName(alertValue.getAxisName()); + object.setAlertContentFormula(alertValue.getAlertContentFormula()); + object.setAlertContent(alertValue.getAlertContent()); + object.setAlertPosition(alertValue.getAlertPosition()); + object.setAlertValueFormula(alertValue.getAlertValueFormula()); + object.setAlertFont(alertValue.getAlertFont()); + object.setAlertLineAlpha(alertValue.getAlertLineAlpha()); + object.setAlertPaneSelectName(alertValue.getAlertPaneSelectName()); + object.setLineColor(alertValue.getLineColor()); + object.setLineStyle(alertValue.getLineStyle()); + } + setObject(object); + + this.setName(alertValue.getAlertPaneSelectName()); + this.setNameableCreator(new ChartNameObjectCreator(axisNames, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Alert_Line"), VanChartAlertValue.class, VanChartAlertValuePane.class)); + } + + @Override + public void setName(String name) { + super.setName(name); + getObject().setAlertPaneSelectName(name); + } + + @Override + public void updateBean(Object bean) { + VanChartAlertValue alertValue = (VanChartAlertValue) bean; + alertValue.setAlertPaneSelectName(getName()); + setObject(alertValue); + } + + @Override + public void save() { + VanChartAlertValue object = getObject(); + alertValue.setAxisNamesArray(object.getAxisNamesArray()); + alertValue.setAxisName(object.getAxisName()); + alertValue.setAlertContentFormula(object.getAlertContentFormula()); + alertValue.setAlertContent(object.getAlertContent()); + alertValue.setAlertPosition(object.getAlertPosition()); + alertValue.setAlertValueFormula(object.getAlertValueFormula()); + alertValue.setAlertFont(object.getAlertFont()); + alertValue.setAlertLineAlpha(object.getAlertLineAlpha()); + alertValue.setAlertPaneSelectName(object.getAlertPaneSelectName()); + alertValue.setLineColor(object.getLineColor()); + alertValue.setLineStyle(object.getLineStyle()); + } +} diff --git a/designer-realize/src/main/java/com/fr/design/share/effect/source/BaseSourceNode.java b/designer-realize/src/main/java/com/fr/design/share/effect/source/BaseSourceNode.java new file mode 100644 index 000000000..feac2413b --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/effect/source/BaseSourceNode.java @@ -0,0 +1,42 @@ +package com.fr.design.share.effect.source; + +public class BaseSourceNode implements SourceNode { + private String path; + private SourceNode parent; + private T target; + + @Override + public String toString() { + if (getParent() != null) { + return getParent().toString() + "-" + path; + } + return path; + } + + @Override + public T getTarget() { + return target; + } + + public void setTarget(T target) { + this.target = target; + } + + @Override + public SourceNode getParent() { + return parent; + } + + @Override + public void setParent(SourceNode parent) { + this.parent = parent; + } + + public void setPath(String path) { + this.path = path; + } + + public String getPath() { + return path; + } +} diff --git a/designer-realize/src/main/java/com/fr/design/share/effect/source/CellSourceNode.java b/designer-realize/src/main/java/com/fr/design/share/effect/source/CellSourceNode.java new file mode 100644 index 000000000..52cff5251 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/effect/source/CellSourceNode.java @@ -0,0 +1,21 @@ +package com.fr.design.share.effect.source; + + +import com.fr.report.cell.DefaultTemplateCellElement; + +public class CellSourceNode extends BaseSourceNode { + + public CellSourceNode(DefaultTemplateCellElement cellElement) { + this(cellElement, null); + } + + public CellSourceNode(DefaultTemplateCellElement cellElement, SourceNode parent) { + this(cellElement, cellElement.toString(), parent); + } + + public CellSourceNode(DefaultTemplateCellElement cellElement, String path, SourceNode parent) { + this.setTarget(cellElement); + this.setPath(path); + this.setParent(parent); + } +} diff --git a/designer-realize/src/main/java/com/fr/design/share/effect/source/EventSourceNode.java b/designer-realize/src/main/java/com/fr/design/share/effect/source/EventSourceNode.java new file mode 100644 index 000000000..7f30a2d8a --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/effect/source/EventSourceNode.java @@ -0,0 +1,25 @@ +package com.fr.design.share.effect.source; + +import com.fr.form.ui.Widget; + +public class EventSourceNode extends BaseSourceNode { + static final private String DEFAULT_PATH = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Event"); + + public EventSourceNode(Widget widget) { + this(widget, DEFAULT_PATH, null); + } + + public EventSourceNode(Widget widget, String path) { + this(widget, path, null); + } + + public EventSourceNode(Widget widget, SourceNode parent) { + this(widget, DEFAULT_PATH, parent); + } + + public EventSourceNode(Widget widget, String path, SourceNode parent) { + this.setTarget(widget); + this.setPath(path); + this.setParent(parent); + } +} diff --git a/designer-realize/src/main/java/com/fr/design/share/effect/source/PlotSourceNode.java b/designer-realize/src/main/java/com/fr/design/share/effect/source/PlotSourceNode.java new file mode 100644 index 000000000..c4698fd24 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/effect/source/PlotSourceNode.java @@ -0,0 +1,31 @@ +package com.fr.design.share.effect.source; + +import com.fr.chart.chartattr.Plot; +import com.fr.design.ChartTypeInterfaceManager; +import com.fr.stable.StringUtils; + +public class PlotSourceNode extends BaseSourceNode { + + public PlotSourceNode(Plot plot) { + this(plot, StringUtils.EMPTY, null); + } + + public PlotSourceNode(Plot plot, SourceNode parent) { + this(plot, StringUtils.EMPTY, parent); + } + + public PlotSourceNode(Plot plot, String chartName) { + this(plot, chartName, null); + } + + public PlotSourceNode(Plot plot, String chartName, SourceNode parent) { + String path = ChartTypeInterfaceManager.getInstance().getName(plot.getPlotID()); + if (StringUtils.isNotEmpty(chartName)) { + path = path + "-" + chartName; + } + this.setPath(path); + this.setTarget(plot); + this.setParent(parent); + } + +} diff --git a/designer-realize/src/main/java/com/fr/design/share/effect/source/SourceNode.java b/designer-realize/src/main/java/com/fr/design/share/effect/source/SourceNode.java new file mode 100644 index 000000000..7094a6959 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/effect/source/SourceNode.java @@ -0,0 +1,14 @@ +package com.fr.design.share.effect.source; + + + +public interface SourceNode { + String toString(); + + T getTarget(); + + SourceNode getParent(); + + void setParent(SourceNode parent); +} + diff --git a/designer-realize/src/main/java/com/fr/design/share/effect/source/SourceNodeUtils.java b/designer-realize/src/main/java/com/fr/design/share/effect/source/SourceNodeUtils.java new file mode 100644 index 000000000..9d988710f --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/effect/source/SourceNodeUtils.java @@ -0,0 +1,34 @@ +package com.fr.design.share.effect.source; + +import com.fr.chart.chartattr.Plot; +import com.fr.form.ui.Widget; +import com.fr.report.cell.DefaultTemplateCellElement; + +public class SourceNodeUtils { + static public SourceNode createSourceNode(Widget widget, SourceNode parent) { + return new EventSourceNode(widget, parent); + } + + static public SourceNode createSourceNode(DefaultTemplateCellElement cellElement, SourceNode parent) { + return new CellSourceNode(cellElement, parent); + } + + + static public SourceNode createSourceNode(Plot plot, SourceNode parent) { + return new PlotSourceNode(plot, parent); + } + + static public SourceNode createSourceNode(Plot plot, String chartName, SourceNode parent) { + return new PlotSourceNode(plot, chartName, parent); + } + + static public SourceNode getCellSourceNode(SourceNode sourceNode) { + if (sourceNode instanceof CellSourceNode) { + return sourceNode; + } + if (sourceNode.getParent() != null) { + return getCellSourceNode(sourceNode.getParent()); + } + return null; + } +} diff --git a/designer-realize/src/main/java/com/fr/design/share/ui/config/ShareConfigContentPane.java b/designer-realize/src/main/java/com/fr/design/share/ui/config/ShareConfigContentPane.java new file mode 100644 index 000000000..fefb5649d --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/ui/config/ShareConfigContentPane.java @@ -0,0 +1,175 @@ +package com.fr.design.share.ui.config; + +import com.fr.design.gui.icontainer.UIScrollPane; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.layout.VerticalFlowLayout; +import com.fr.design.mainframe.share.ui.base.PlaceholderTextArea; +import com.fr.design.share.effect.EffectItem; +import com.fr.design.share.effect.EffectItemGroup; +import com.fr.design.share.effect.source.SourceNode; +import com.fr.design.share.effect.source.SourceNodeUtils; +import com.fr.design.share.ui.config.table.ExpandEffectTable; +import com.fr.design.share.ui.effect.PreviewPane; +import com.fr.form.ui.Widget; +import com.fr.grid.selection.CellSelection; +import com.fr.locale.InterProviderFactory; +import com.fr.report.cell.DefaultTemplateCellElement; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.JTable; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.event.ComponentEvent; +import java.awt.event.ComponentListener; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class ShareConfigContentPane extends JPanel { + private EffectItemGroup effectItemGroup; + private PreviewPane previewPane; + private String info; + private List expandEffectTables = new ArrayList<>(); + + public ShareConfigContentPane(EffectItemGroup effectItemGroup, String info) { + this.effectItemGroup = effectItemGroup; + this.info = info; + initComponent(); + } + + private void initComponent() { + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + JPanel leftPane = createLeftPane(); + JPanel rightPane = createRightPane(); + this.add(leftPane, BorderLayout.WEST); + this.add(rightPane, BorderLayout.CENTER); + } + + private JPanel createLeftPane() { + JPanel leftPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + leftPane.add(createPreviewPane(), BorderLayout.NORTH); + leftPane.add(createInfoPane(), BorderLayout.CENTER); + return leftPane; + } + + private JPanel createRightPane() { + JPanel rightPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + rightPane.setBorder(BorderFactory.createEmptyBorder(0, 3, 0, 0)); + rightPane.add(createEffectPane(), BorderLayout.CENTER); + return rightPane; + } + + private JPanel createPreviewPane() { + + JPanel pane= FRGUIPaneFactory.createTitledBorderPane(Toolkit.i18nText(Toolkit.i18nText("Fine-Design_Share_Preview"))); + previewPane = new PreviewPane(getWidget()); + pane.add(previewPane, BorderLayout.CENTER); + return pane; + } + + private JPanel createInfoPane() { + JPanel infoPane = FRGUIPaneFactory.createTitledBorderPane(Toolkit.i18nText("Fine-Design_Share_Introduce")); + PlaceholderTextArea textArea = new PlaceholderTextArea(); + textArea.setText(this.info); + textArea.setPlaceholder(Toolkit.i18nText("Fine-Design_Share_No_Introduction")); + textArea.setEditable(false); + UIScrollPane scrollPane = new UIScrollPane(textArea); + scrollPane.setPreferredSize(new Dimension(373, 176)); + infoPane.add(scrollPane, BorderLayout.CENTER); + return infoPane; + } + + private JPanel createEffectPane() { + JPanel effectPane = FRGUIPaneFactory.createTitledBorderPane(Toolkit.i18nText(Toolkit.i18nText("Fine-Design_Share_Effects"))); + JPanel effectContainer = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, VerticalFlowLayout.TOP,0, 0); + + EffectItemGroup effectItemGroup = getEffectItemGroup(); + LinkedHashMap> effectItemsMap = effectItemGroup.getEffectItemsWithClassify(); + + Set>> entrySet = effectItemsMap.entrySet(); + Iterator>> iterator = entrySet.iterator(); + + expandEffectTables.clear(); + while (iterator.hasNext()) { + Map.Entry> entry= iterator.next(); + String title = entry.getKey(); + List effectItems = entry.getValue(); + ExpandEffectTable expandEffectTable= new ExpandEffectTable(effectItems, title); + expandEffectTables.add(expandEffectTable); + JTable table = expandEffectTable.getTable(); + if (previewPane.isElementCaseEditor()) { + table.getSelectionModel().addListSelectionListener(new ListSelectionListener() { + @Override + public void valueChanged(ListSelectionEvent e) { + if (table.getSelectedRow() >= 0) { + EffectItem effectItem= effectItems.get(table.getSelectedRow()); + SourceNode cellSourceNode = SourceNodeUtils.getCellSourceNode(effectItem.getSourceNode()); + if (cellSourceNode != null) { + DefaultTemplateCellElement cellElement = (DefaultTemplateCellElement) cellSourceNode.getTarget(); + previewPane.getElementCasePane().setSelection(new CellSelection(cellElement.getColumn(), cellElement.getRow(), cellElement.getColumnSpan(), cellElement.getRowSpan())); + } + } + } + }); + } + effectContainer.add(expandEffectTable); + + } + + UIScrollPane scrollPane = new UIScrollPane(effectContainer); + scrollPane.setPreferredSize(new Dimension(465, 545)); + scrollPane.getViewport().addComponentListener(new ComponentListener() { + @Override + public void componentResized(ComponentEvent e) { + Component component = e.getComponent(); + if (component != null) { + for(ExpandEffectTable expandEffectTable : expandEffectTables) { + for(Component co : expandEffectTable.getComponents()) { + co.setPreferredSize(new Dimension(component.getWidth(), co.getHeight())); + co.setSize(new Dimension(component.getWidth(), co.getHeight())); + } + } + } + } + @Override + public void componentMoved(ComponentEvent e) { + + } + @Override + public void componentShown(ComponentEvent e) { + + } + @Override + public void componentHidden(ComponentEvent e) { + + } + }); + scrollPane.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0)); + + effectPane.add(scrollPane, BorderLayout.CENTER); + return effectPane; + } + + private Widget getWidget() { + return getEffectItemGroup().getWidget(); + } + + private EffectItemGroup getEffectItemGroup() { + return effectItemGroup; + } + + public void reset() { + if (previewPane.isElementCaseEditor() && (previewPane.getElementCasePane() != null)) { + previewPane.getElementCasePane().setSelection(new CellSelection(0, 0, 0, 0)); + } + } + +} diff --git a/designer-realize/src/main/java/com/fr/design/share/ui/config/ShareConfigPane.java b/designer-realize/src/main/java/com/fr/design/share/ui/config/ShareConfigPane.java new file mode 100644 index 000000000..9b55dc122 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/ui/config/ShareConfigPane.java @@ -0,0 +1,239 @@ +package com.fr.design.share.ui.config; + +import com.fr.design.constants.UIConstants; +import com.fr.design.dialog.BasicDialog; +import com.fr.design.dialog.BasicPane; +import com.fr.design.dialog.DialogActionAdapter; +import com.fr.design.file.HistoryTemplateListCache; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.ibutton.UIButtonUI; +import com.fr.design.gui.icontainer.UIScrollPane; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.layout.VerticalFlowLayout; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.DesignerFrame; +import com.fr.design.mainframe.share.collect.ComponentCollector; +import com.fr.design.mainframe.share.ui.base.PlaceholderTextArea; +import com.fr.design.mainframe.share.util.ShareComponentUtils; +import com.fr.design.share.effect.EffectItemGroup; +import com.fr.design.share.utils.EffectItemUtils; +import com.fr.design.share.utils.ShareDialogUtils; +import com.fr.design.utils.gui.GUIPaintUtils; +import com.fr.form.ui.Widget; +import com.fr.form.ui.container.WTitleLayout; +import com.fr.locale.InterProviderFactory; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.border.Border; +import java.awt.BorderLayout; +import java.awt.CardLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Graphics2D; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.HashMap; +import java.util.List; + +public class ShareConfigPane extends BasicPane { + private static final Dimension DIALOG_SIZE = new Dimension(900, 680); + private static final Border DIALOG_BORDER = BorderFactory.createEmptyBorder(0, 6, 4, 6); + private static final Color EMPTY_TEXT_COLOR = new Color(51, 51, 51, 128); + + private Widget widget; + private List effectItemGroups; + private HashMap quickConfigContentPaneMap = new HashMap(); + + private BasicDialog dialog; + private int selectIndex = 0; + private CardLayout cardLayout; + private JPanel contentPane; + private UILabel nameLabel; + private UIButton preButton; + private UIButton nextButton; + + + + public ShareConfigPane(Widget widget) { + this.widget = widget; + effectItemGroups = EffectItemUtils.getEffectItemGroupsByWidget(widget); + initComponent(); + } + + private void initComponent() { + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + this.setBorder(DIALOG_BORDER); + this.setPreferredSize(DIALOG_SIZE); + + if (effectItemGroups.size() > 0) { + this.add(createNaviPane(), BorderLayout.NORTH); + this.add(createContentPane(), BorderLayout.CENTER); + } else { + this.add(createInfoPane(), BorderLayout.WEST); + this.add(createEffectEmptyPane(), BorderLayout.EAST); + } + + } + + private JPanel createNaviPane() { + JPanel naviPane = new JPanel(); + naviPane.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 0)); + naviPane.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 0)); + + preButton = new UIButton(Toolkit.i18nText("Fine-Design_Share_Prev")); + preButton.setPreferredSize(new Dimension(62, 20)); + preButton.setUI(disabledUIButtonUI); + preButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + quickConfigContentPaneMap.get(getSelectWidget().getWidgetName()).reset(); + selectIndex--; + TogglePage(); + } + }); + preButton.setEnabled(hasPreview()); + + nextButton = new UIButton(Toolkit.i18nText("Fine-Design_Share_Next")); + nextButton.setPreferredSize(new Dimension(62, 20)); + nextButton.setUI(disabledUIButtonUI); + nextButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + quickConfigContentPaneMap.get(getSelectWidget().getWidgetName()).reset(); + selectIndex++; + TogglePage(); + } + }); + nextButton.setEnabled(hasNext()); + + nameLabel = new UILabel(""); + nameLabel.setPreferredSize(new Dimension(nameLabel.getFont().getSize() * 20, 15)); + + naviPane.add(preButton); + naviPane.add(nextButton); + naviPane.add(nameLabel); + + return naviPane; + } + + private JPanel createContentPane() { + contentPane = new JPanel(); + cardLayout = new CardLayout(); + contentPane.setLayout(cardLayout); + addContent(); + return contentPane; + } + + private void addContent() { + ShareConfigContentPane content = new ShareConfigContentPane(getSelectEffectItemGroup(), getDescription()); + contentPane.add(getSelectWidget().getWidgetName(), content); + quickConfigContentPaneMap.put(getSelectWidget().getWidgetName(), content); + updateContent(); + } + + private void updateContent() { + cardLayout.show(contentPane, getSelectWidget().getWidgetName()); + nameLabel.setText(getSelectWidget().getWidgetName()); + nameLabel.setToolTipText(getSelectWidget().getWidgetName()); + } + + private void TogglePage() { + preButton.setEnabled(hasPreview()); + nextButton.setEnabled(hasNext()); + if (quickConfigContentPaneMap.containsKey(getSelectWidget().getWidgetName())) { + updateContent(); + } else { + addContent(); + } + } + + private JPanel createInfoPane() { + JPanel infoPane = FRGUIPaneFactory.createTitledBorderPane(Toolkit.i18nText("Fine-Design_Share_Introduce")); + PlaceholderTextArea textArea = new PlaceholderTextArea(); + textArea.setText(this.widget.getDescription()); + textArea.setPlaceholder(Toolkit.i18nText("Fine-Design_Share_No_Introduction")); + textArea.setEditable(false); + UIScrollPane scrollPane = new UIScrollPane(textArea); + scrollPane.setPreferredSize(new Dimension(373, 176)); + infoPane.add(scrollPane, BorderLayout.CENTER); + return infoPane; + } + + private String getDescription() { + if (this.widget instanceof WTitleLayout) { + return ((WTitleLayout) this.widget).getBodyBoundsWidget().getWidget().getDescription(); + } + return this.widget.getDescription(); + } + + private JPanel createEffectEmptyPane() { + JPanel effectPane = FRGUIPaneFactory.createTitledBorderPane(Toolkit.i18nText("Fine-Design_Share_Effects")); + effectPane.setLayout(new VerticalFlowLayout(FlowLayout.CENTER,0 , 0)); + effectPane.setPreferredSize(new Dimension(480, 545)); + UILabel label = new UILabel(Toolkit.i18nText("Fine-Design_Share_Empty")); + label.setAlignmentX(Component.CENTER_ALIGNMENT); + label.setPreferredSize(new Dimension(480, 22)); + label.setHorizontalAlignment(UILabel.CENTER); + label.setForeground(EMPTY_TEXT_COLOR); + effectPane.add(label); + return effectPane; + } + + @Override + protected String title4PopupWindow() { + return Toolkit.i18nText("Fine-Design_Share_Help_Settings"); + } + + public void show() { + final DesignerFrame designerFrame = DesignerContext.getDesignerFrame(); + dialog = this.showWindowWithCustomSize(designerFrame, null, DIALOG_SIZE); + ShareDialogUtils.getInstance().setConfigDialog(dialog); + dialog.addDialogActionListener(new DialogActionAdapter() { + @Override + public void doOk() { + for(EffectItemGroup effectItemGroup : effectItemGroups) { + effectItemGroup.save(); + } + HistoryTemplateListCache.getInstance().getCurrentEditingTemplate().saveTemplate(); + ComponentCollector.getInstance().setHelpConfigUseInfo(ShareComponentUtils.getCurrentTemplateID(), ShareComponentUtils.getWidgetId(widget)); + } + }); + dialog.setVisible(true); + } + + private boolean hasPreview() { + return selectIndex > 0; + } + + private boolean hasNext() { + return selectIndex < effectItemGroups.size() - 1; + } + + private Widget getSelectWidget() { + return getSelectEffectItemGroup().getWidget(); + } + + private EffectItemGroup getSelectEffectItemGroup() { + return effectItemGroups.get(selectIndex); + } + + private UIButtonUI disabledUIButtonUI = new UIButtonUI() { + protected void doExtraPainting(UIButton b, Graphics2D g2d, int w, int h, String selectedRoles) { + if (!b.isEnabled()) { + GUIPaintUtils.fillPaint(g2d, 0, 0, w, h, b.isRoundBorder(), b.getRectDirection(), new Color(240, 240, 241), UIConstants.ARC); + } else if (isPressed(b) && b.isPressedPainted()) { + GUIPaintUtils.fillPressed(g2d, 0, 0, w, h, b.isRoundBorder(), b.getRectDirection(), b.isDoneAuthorityEdited(selectedRoles)); + } else if (isRollOver(b)) { + GUIPaintUtils.fillRollOver(g2d, 0, 0, w, h, b.isRoundBorder(), b.getRectDirection(), b.isDoneAuthorityEdited(selectedRoles), b.isPressedPainted()); + } else if (b.isNormalPainted()) { + GUIPaintUtils.fillNormal(g2d, 0, 0, w, h, b.isRoundBorder(), b.getRectDirection(), b.isDoneAuthorityEdited(selectedRoles), b.isPressedPainted()); + } + } + }; + +} diff --git a/designer-realize/src/main/java/com/fr/design/share/ui/config/table/ConfigItemRender.java b/designer-realize/src/main/java/com/fr/design/share/ui/config/table/ConfigItemRender.java new file mode 100644 index 000000000..1d8874afa --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/ui/config/table/ConfigItemRender.java @@ -0,0 +1,87 @@ +package com.fr.design.share.ui.config.table; + +import com.fr.base.BaseUtils; +import com.fr.design.i18n.Toolkit; +import com.fr.locale.InterProviderFactory; +import com.fr.stable.StringUtils; + +import javax.swing.BorderFactory; +import javax.swing.Icon; +import javax.swing.JComponent; +import javax.swing.JTable; +import javax.swing.border.Border; +import javax.swing.table.DefaultTableCellRenderer; +import java.awt.Color; +import java.awt.Component; +import java.awt.Cursor; + +public class ConfigItemRender extends DefaultTableCellRenderer { + static final private Color PLACEHOLDER_COLOR = new Color(193, 193, 193); + static final private Color NO_EDITABLE_BG = new Color(240, 240, 241); + + static final private Border DEFAULT_NO_FOCUS_BORDER = BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(1, 5, 1, 5), BorderFactory.createEmptyBorder(0, 4, 0, 4)); + static final private Border SELECTED_BORDER = BorderFactory.createLineBorder(new Color(160,190,240)); + + private final Icon editIcon = BaseUtils.readIcon("com/fr/base/images/share/edit.png"); + + public ConfigItemRender() { + super(); + setBorder(DEFAULT_NO_FOCUS_BORDER); + } + + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + setText(StringUtils.EMPTY); + setToolTipText(null); + setBorder(DEFAULT_NO_FOCUS_BORDER); + setBackground(null); + setForeground(null); + setIcon(null); + setAlignmentX(JComponent.LEFT_ALIGNMENT); + + if (column == 2) { + setIcon(editIcon); + setAlignmentX(JComponent.CENTER_ALIGNMENT); + return this; + } + + if (value == null) { + return this; + } + + if (StringUtils.isNotEmpty(value.toString())) { + setValue(value); + } + setForeground(Color.black); + + if (column == 1) { + if (!table.isCellEditable(row, column)) { + setForeground(PLACEHOLDER_COLOR); + setBackground(NO_EDITABLE_BG); + setToolTipText(Toolkit.i18nText("Fine-Design_Share_Not_Support_Rename")); + } + if (StringUtils.isEmpty(value.toString())) { + setValue(Toolkit.i18nText("Fine-Design_Share_Need_Rename")); + setForeground(PLACEHOLDER_COLOR); + } + } + + if (table.getSelectedRow() == row && table.getSelectedColumn() == column && table.isCellEditable(row, column) ) { + setBorder(SELECTED_BORDER); + setBackground(null); + table.setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR)); + } else { + if (isSelected) { + setBackground(table.getSelectionBackground()); + } + table.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + } + + return this; + } + + + public void setValue(Object value) { + super.setValue(value); + setToolTipText((value == null) ? null : value.toString()); + } +} diff --git a/designer-realize/src/main/java/com/fr/design/share/ui/config/table/ConfigTableModel.java b/designer-realize/src/main/java/com/fr/design/share/ui/config/table/ConfigTableModel.java new file mode 100644 index 000000000..29fe8e125 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/ui/config/table/ConfigTableModel.java @@ -0,0 +1,70 @@ +package com.fr.design.share.ui.config.table; + +import com.fr.design.share.effect.EffectItem; +import com.fr.design.share.effect.ListenerEffectItem; + +import javax.swing.table.AbstractTableModel; +import java.util.List; + +public class ConfigTableModel extends AbstractTableModel { + private Object[] columnNames; + private List effectItems; + + public ConfigTableModel(List effectItems, Object[] columnNames) { + this.effectItems = effectItems; + this.columnNames = columnNames; + } + @Override + public int getRowCount() { + return this.effectItems.size(); + } + + @Override + public int getColumnCount() { + return this.columnNames.length; + } + + @Override + public String getColumnName(int columnIndex) { + if (columnNames == null) { + return null; + } + return columnNames[columnIndex].toString(); + } + + @Override + public Class getColumnClass(int columnIndex) { + return ConfigTableModel.class; + } + + @Override + public boolean isCellEditable(int rowIndex, int columnIndex) { + EffectItem effectItem = effectItems.get(rowIndex); + return columnIndex == 1 && !(effectItem instanceof ListenerEffectItem); + } + + @Override + public Object getValueAt(int rowIndex, int columnIndex) { + if (rowIndex >= getRowCount() || columnIndex >= getColumnCount()) { + return null; + } + EffectItem effectItem = effectItems.get(rowIndex); + if (columnIndex == 0) { + return effectItem.getConfigPath(); + } else if (columnIndex == 1) { + return effectItem.getName(); + } + return null; + } + + @Override + public void setValueAt(Object aValue, int rowIndex, int columnIndex) { + if (rowIndex >= effectItems.size() || columnIndex >= getColumnCount()) { + return; + } + EffectItem effectItem = effectItems.get(rowIndex); + if (columnIndex == 1) { + effectItem.setName(aValue.toString()); + } + } +} diff --git a/designer-realize/src/main/java/com/fr/design/share/ui/config/table/ExpandEffectTable.java b/designer-realize/src/main/java/com/fr/design/share/ui/config/table/ExpandEffectTable.java new file mode 100644 index 000000000..1479d8437 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/ui/config/table/ExpandEffectTable.java @@ -0,0 +1,163 @@ +package com.fr.design.share.ui.config.table; + +import com.fr.design.dialog.DialogActionAdapter; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.layout.VerticalFlowLayout; +import com.fr.design.share.effect.EffectItem; +import com.fr.design.share.ui.effect.EffectControlUpdatePane; +import com.fr.design.share.ui.effect.EffectPopupEditDialog; +import com.fr.design.share.ui.table.EffectItemEditor; +import com.fr.design.share.utils.ShareDialogUtils; +import com.fr.general.IOUtils; +import com.fr.locale.InterProviderFactory; + +import javax.swing.BorderFactory; +import javax.swing.Icon; +import javax.swing.JPanel; +import javax.swing.JTable; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Toolkit; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseMotionAdapter; +import java.util.List; + +public class ExpandEffectTable extends JPanel { + private static final Icon downIcon = IOUtils.readIcon("com/fr/base/images/share/arrow_down.png"); + private static final Icon rightIcon = IOUtils.readIcon("com/fr/base/images/share/arrow_left.png"); + private static final int WIDTH = 460; + private List effectItems; + private String title; + private boolean expand; + private UILabel arrow; + private JPanel contentPane; + private EffectPopupEditDialog effectPopupEditDialog; + private EffectControlUpdatePane effectControlUpdatePane; + private JTable table; + + public ExpandEffectTable(List effectItems, String title) { + this.effectItems = effectItems; + this.title = title; + + initComponent(); + } + + private void initComponent() { + VerticalFlowLayout layout = new VerticalFlowLayout(VerticalFlowLayout.TOP, 0, 4); + this.setLayout(layout); + this.expand = true; + + JPanel headerPane = createHeader(); + contentPane = createContent(); + + this.add(headerPane); + this.add(contentPane); + + this.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + setExpand(!expand); + } + }); + } + + private JPanel createHeader() { + JPanel headerPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + headerPane.setPreferredSize(new Dimension(WIDTH, 24)); + headerPane.setBackground(new Color(232,232,232)); + UILabel headerTitle = new UILabel(this.title); + headerTitle.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0)); + + arrow = new UILabel(downIcon); + arrow.setOpaque(false); + arrow.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5)); + + headerPane.add(headerTitle, BorderLayout.WEST); + headerPane.add(arrow, BorderLayout.EAST); + return headerPane; + } + + + private JPanel createContent() { + JPanel content = FRGUIPaneFactory.createBorderLayout_S_Pane(); + + // 效果列表 + Object[] columnNames = { + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Share_From"), + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Share_Rename"), + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Share_Edit") + }; + ConfigTableModel tableModel = new ConfigTableModel(effectItems, columnNames); + table = new JTable(tableModel); + + table.setRowHeight(24); + table.getColumnModel().getColumn(0).setPreferredWidth(180); + table.getColumnModel().getColumn(1).setPreferredWidth(252); + table.getColumnModel().getColumn(2).setPreferredWidth(33); + + table.setDefaultEditor(ConfigTableModel.class, new EffectItemEditor(table)); + table.setDefaultRenderer(ConfigTableModel.class, new ConfigItemRender()); + table.getTableHeader().setResizingAllowed(false); + table.getTableHeader().setReorderingAllowed(false); + table.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + int selectColumn = table.getSelectedColumn(); + if (selectColumn == 2) { + int selectRow = table.getSelectedRow(); + EffectItem selectEffectItem = effectItems.get(selectRow); + + effectControlUpdatePane = EffectControlUpdatePane.newInstance(selectEffectItem); + effectControlUpdatePane.populate(); + effectPopupEditDialog = EffectPopupEditDialog.newInstance(ShareDialogUtils.getInstance().getConfigDialog(), effectControlUpdatePane); + effectPopupEditDialog.setTitle(selectEffectItem.getName()); + Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); + effectPopupEditDialog.setLocation((d.width - effectPopupEditDialog.getSize().width) / 2, (d.height - effectPopupEditDialog.getSize().height) / 2); + effectPopupEditDialog.setVisible(true); + effectPopupEditDialog.addDialogActionListener(new DialogActionAdapter() { + @Override + public void doOk() { + effectControlUpdatePane.update(); + } + }); + } + } + public void mouseExited(MouseEvent e) { + int row = table.rowAtPoint(e.getPoint()); + int col = table.columnAtPoint(e.getPoint()); + if ((e.getPoint().getY() < 0) || row < 0 || col < 0) { + table.clearSelection(); + } + } + }); + table.addMouseMotionListener(new MouseMotionAdapter() { + @Override + public void mouseMoved(MouseEvent e) { + int row = table.rowAtPoint(e.getPoint()); + int col = table.columnAtPoint(e.getPoint()); + table.setRowSelectionInterval(row, row); + table.setColumnSelectionInterval(col, col); + } + }); + content.add(table.getTableHeader(), BorderLayout.NORTH); + content.add(table,BorderLayout.CENTER); + return content; + } + + public void setExpand(boolean isExpand) { + this.expand = isExpand; + arrow.setIcon(isExpand ? downIcon : rightIcon); + contentPane.setVisible(isExpand); + } + + public JTable getTable() { + return table; + } + + public boolean isExpand() { + return expand; + } +} diff --git a/designer-realize/src/main/java/com/fr/design/share/ui/effect/EffectControlUpdatePane.java b/designer-realize/src/main/java/com/fr/design/share/ui/effect/EffectControlUpdatePane.java new file mode 100644 index 000000000..46a9de7fb --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/ui/effect/EffectControlUpdatePane.java @@ -0,0 +1,85 @@ +package com.fr.design.share.ui.effect; + +import com.fr.design.DesignerEnvManager; +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.env.DesignerWorkspaceInfo; +import com.fr.design.env.RemoteDesignerWorkspaceInfo; +import com.fr.design.gui.controlpane.NameableCreator; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.share.effect.EffectItem; +import com.fr.general.ComparatorUtils; +import com.fr.log.FineLoggerFactory; + +import javax.swing.JPanel; +import java.awt.BorderLayout; + +public class EffectControlUpdatePane extends JPanel { + private EffectItem effectItem; + private BasicBeanPane updatePane; + + private EffectControlUpdatePane(EffectItem effectItem) { + this.effectItem = effectItem; + initUpdatePane(); + } + + public static EffectControlUpdatePane newInstance(EffectItem effectItem) { + return new EffectControlUpdatePane(effectItem); + } + + private void initUpdatePane() { + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + NameableCreator creator = effectItem.creator(); + if (creator == null) { + return; + } else { + if (isMulti(creator.getUpdatePane()) || isTree(creator.getUpdatePane())) { + updatePane = effectItem.createPaneByCreators(creator, effectItem.getName()); + } else { + updatePane = effectItem.createPaneByCreators(creator); + } + this.add(updatePane, BorderLayout.CENTER); + } + } + + public void populate() { + try{ + updatePane.populateBean(effectItem.getPopulateBean()); + }catch (Exception e){ + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + } + + + 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() { + BasicBeanPane pane = updatePane; + if (pane != null && pane.isVisible()) { + Object bean = pane.updateBean(); + try { + if (bean instanceof RemoteDesignerWorkspaceInfo) { + DesignerWorkspaceInfo info = DesignerEnvManager.getEnvManager().getWorkspaceInfo(effectItem.getName()); + String remindTime = info.getRemindTime(); + ((RemoteDesignerWorkspaceInfo) bean).setRemindTime(remindTime); + } + }catch (Exception e){ + FineLoggerFactory.getLogger().info("remindTime is not exist"); + } + effectItem.updateBean(bean); + } + } + + public void checkValid() throws Exception { + updatePane.checkValid(); + } +} diff --git a/designer-realize/src/main/java/com/fr/design/share/ui/effect/EffectPopupEditDialog.java b/designer-realize/src/main/java/com/fr/design/share/ui/effect/EffectPopupEditDialog.java new file mode 100644 index 000000000..9abd9ba61 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/ui/effect/EffectPopupEditDialog.java @@ -0,0 +1,206 @@ +package com.fr.design.share.ui.effect; + +import com.fr.design.constants.UIConstants; +import com.fr.design.dialog.UIDialog; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.stable.StringUtils; + +import javax.swing.BorderFactory; +import javax.swing.JComponent; +import javax.swing.JDialog; +import javax.swing.JPanel; +import javax.swing.border.EmptyBorder; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Cursor; +import java.awt.Dialog; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Font; +import java.awt.GraphicsEnvironment; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Toolkit; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; + +public class EffectPopupEditDialog extends UIDialog { + private JComponent editPane; + private PopupToolPane popupToolPane; + private UIButton okButton; + private static final int WIDTH = 570; + private static final int HEIGHT = 510; + + public EffectPopupEditDialog(Dialog parent, JComponent pane) { + super(parent); + setUndecorated(true); + pane.setBorder(BorderFactory.createEmptyBorder(20, 10, 10, 10)); + + this.editPane = pane; + JPanel editPaneWrapper = new JPanel(new BorderLayout()); + popupToolPane = new PopupToolPane(this); + editPaneWrapper.add(popupToolPane, BorderLayout.NORTH); + editPaneWrapper.add(editPane, BorderLayout.CENTER); + editPaneWrapper.setBorder(BorderFactory.createLineBorder(UIConstants.POP_DIALOG_BORDER, 1)); + editPaneWrapper.add(this.createControlButtonPane(), BorderLayout.SOUTH); + this.getContentPane().add(editPaneWrapper, BorderLayout.CENTER); + + setSize(WIDTH, HEIGHT); +// pack(); + this.setVisible(false); + } + + public static EffectPopupEditDialog newInstance(Dialog parent, JComponent pane) { + return new EffectPopupEditDialog(parent, pane); + } + + + @Override + public void setTitle(String title) { + popupToolPane.setTitle(title); + } + + + @Override + public void checkValid() throws Exception { + + } + + // 移动弹出编辑面板的工具条 + private class PopupToolPane extends JPanel { + private JDialog parentDialog; // 如果不在对话框中,值为null + private Color originColor; // 初始背景 + private JPanel contentPane; + private UILabel titleLabel; + private Point mouseDownCompCoords; // 存储按下左键的位置,移动对话框时会用到 + + private static final int MIN_X = -150; + private static final int MAX_X_SHIFT = 50; + private static final int MAX_Y_SHIFT = 50; + + private MouseListener mouseListener = new MouseAdapter() { + @Override + public void mouseExited(MouseEvent e) { + setCursor(Cursor.getDefaultCursor()); + if (mouseDownCompCoords == null) { + contentPane.setBackground(originColor); + } + repaint(); + } + + @Override + public void mouseReleased(MouseEvent e) { + mouseDownCompCoords = null; + if (!getBounds().contains(e.getPoint())) { + contentPane.setBackground(originColor); + } + } + + @Override + public void mousePressed(MouseEvent e) { + mouseDownCompCoords = e.getPoint(); + } + }; + + private MouseMotionListener mouseMotionListener = new MouseMotionListener() { + @Override + public void mouseMoved(MouseEvent e) { + setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR)); + contentPane.setBackground(UIConstants.POPUP_TITLE_BACKGROUND); + repaint(); + } + + @Override + public void mouseDragged(MouseEvent e) { + if (mouseDownCompCoords != null) { + Point currCoords = e.getLocationOnScreen(); + int x = currCoords.x - mouseDownCompCoords.x; + int y = currCoords.y - mouseDownCompCoords.y; + //屏幕可用区域 + Rectangle screen = GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds(); + + int minY = screen.y; + int maxX = Toolkit.getDefaultToolkit().getScreenSize().width - MAX_X_SHIFT; + int maxY = Toolkit.getDefaultToolkit().getScreenSize().height - MAX_Y_SHIFT; + if (x < MIN_X) { + x = MIN_X; + } else if (x > maxX) { + x = maxX; + } + if (y < minY) { + y = minY; + } else if (y > maxY) { + y = maxY; + } + // 移动到屏幕边缘时,需要校正位置 + parentDialog.setLocation(x, y); + } + } + }; + + PopupToolPane(JDialog parentDialog) { + this(StringUtils.EMPTY, parentDialog); + } + + PopupToolPane(String title, JDialog parentDialog) { + super(); + this.parentDialog = parentDialog; + originColor = UIConstants.DIALOG_TITLEBAR_BACKGROUND; + + contentPane = new JPanel(); + contentPane.setBackground(originColor); + contentPane.setLayout(new BorderLayout()); + titleLabel = new UILabel(title); + Font font = new Font("SimSun", Font.PLAIN, 12); + titleLabel.setFont(font); + contentPane.add(titleLabel, BorderLayout.WEST); + contentPane.setBorder(new EmptyBorder(5, 14, 6, 0)); + + setLayout(new BorderLayout()); + add(contentPane, BorderLayout.CENTER); + setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, UIConstants.TOOLBAR_BORDER_COLOR)); + + addMouseListener(mouseListener); + addMouseMotionListener(mouseMotionListener); + } + + public void setTitle(String title) { + titleLabel.setText(title); + } + + @Override + public Dimension getPreferredSize() { + return new Dimension(super.getPreferredSize().width, 28); + } + } + + private JPanel createControlButtonPane() { + JPanel controlPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + + JPanel buttonsPane = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 5)); + controlPane.add(buttonsPane, BorderLayout.EAST); + + //确定 + addOkButton(buttonsPane); + + return controlPane; + } + + private void addOkButton(JPanel buttonsPane) { + okButton = new UIButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_OK")); + okButton.setName(OK_BUTTON); + okButton.setMnemonic('O'); + buttonsPane.add(okButton); + okButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt) { + doOK(); + } + }); + } +} diff --git a/designer-realize/src/main/java/com/fr/design/share/ui/effect/PreviewPane.java b/designer-realize/src/main/java/com/fr/design/share/ui/effect/PreviewPane.java new file mode 100644 index 000000000..68cd025e3 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/ui/effect/PreviewPane.java @@ -0,0 +1,356 @@ +package com.fr.design.share.ui.effect; + +import com.fr.base.BaseUtils; +import com.fr.base.DynamicUnitList; +import com.fr.base.ScreenResolution; +import com.fr.base.chart.BaseChartCollection; +import com.fr.base.chart.chartdata.CallbackEvent; +import com.fr.common.inputevent.InputEventBaseOnOS; +import com.fr.design.cell.bar.DynamicScrollBar; +import com.fr.design.designer.creator.XCreator; +import com.fr.design.file.HistoryTemplateListCache; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.ElementCasePane; +import com.fr.design.mainframe.FormSelection; +import com.fr.design.mainframe.JForm; +import com.fr.design.mainframe.JTemplate; +import com.fr.design.mainframe.form.FormElementCaseDesigner; +import com.fr.design.mainframe.share.ui.base.ChartIcon; +import com.fr.design.utils.DesignUtils; +import com.fr.form.main.Form; +import com.fr.form.ui.ChartEditor; +import com.fr.form.ui.ElementCaseEditor; +import com.fr.form.ui.Widget; +import com.fr.general.IOUtils; +import com.fr.grid.Grid; +import com.fr.grid.GridUtils; +import com.fr.grid.selection.CellSelection; +import com.fr.report.ReportHelper; +import com.fr.report.worksheet.FormElementCase; + +import javax.swing.BorderFactory; +import javax.swing.Icon; +import javax.swing.ImageIcon; +import javax.swing.JPanel; +import javax.swing.JScrollBar; +import javax.swing.SwingConstants; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Cursor; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Image; +import java.awt.Point; +import java.awt.Toolkit; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseEvent; +import java.awt.event.MouseMotionAdapter; +import java.awt.event.MouseWheelEvent; +import java.awt.event.MouseWheelListener; +import java.awt.image.BufferedImage; + +public class PreviewPane extends JPanel implements CallbackEvent{ + public static final Cursor SCALE_CURSOR = Toolkit.getDefaultToolkit().createCustomCursor( + IOUtils.readImage("com/fr/base/images/share/scale.png"), + new Point(16, 16), "ScaleCursor"); + private static final Icon PLUS_ICON = BaseUtils.readIcon("com/fr/base/images/share/add.png"); + private static final Icon PLUS_CLICK_ICON = BaseUtils.readIcon("com/fr/base/images/share/add_click.png"); + private static final Icon PLUS_HOVER_ICON = BaseUtils.readIcon("com/fr/base/images/share/add_hover.png"); + private static final Icon PLUS_DISABLED_ICON = BaseUtils.readIcon("com/fr/base/images/share/add_disabled.png"); + private static final Icon MINUS_CLICK_ICON = BaseUtils.readIcon("com/fr/base/images/share/minus_click.png"); + private static final Icon MINUS_HOVER_ICON = BaseUtils.readIcon("com/fr/base/images/share/minus_hover.png"); + private static final Icon MINUS_ICON = BaseUtils.readIcon("com/fr/base/images/share/minus.png"); + private static final Icon MINUS_DISABLED_ICON = BaseUtils.readIcon("com/fr/base/images/share/minus_disabled.png"); + private static final Dimension BUTTON_SIZE = new Dimension(20, 20); + private static final Dimension PREVIEW_SIZE = new Dimension(373, 310); + private static final int MAX = 400; + private static final int HUND = 100; + private static final int MIN = 10; + private static final int DIR = 10; + private static final double MIN_TIME = 0.4; + + private Widget widget; + private UIButton plusButton; + private UIButton minusButton; + private JPanel preview; + private int scaleValue = 100; + private ElementCasePane elementCasePane; + private Image previewImage; + private int resolution; + private Dimension previewSize; + private boolean enabled; + + public PreviewPane(Widget widget) { + this(widget, PREVIEW_SIZE, true); + } + + public PreviewPane(Widget widget, Dimension previewSize, boolean enabled) { + this.widget = widget; + + this.enabled = enabled; + this.previewSize = previewSize; + this.resolution = ScreenResolution.getScreenResolution(); + initComponent(); + } + + + private void initComponent() { + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + + if (enabled) { + this.add(createTopToolbarPane(), BorderLayout.NORTH); + } else { + this.add(createRightToolbarPane(), BorderLayout.EAST); + } + this.add(createViewPane(), BorderLayout.CENTER); + + } + + private JPanel createTopToolbarPane() { + JPanel toolbarPane = FRGUIPaneFactory.createRightFlowInnerContainer_S_Pane(); + FlowLayout layout = new FlowLayout(FlowLayout.RIGHT, 10 ,0); + toolbarPane.setLayout(layout); + toolbarPane.setPreferredSize(new Dimension(previewSize.width, 22)); + addScaleButton(toolbarPane); + return toolbarPane; + } + + private JPanel createRightToolbarPane() { + JPanel toolbarPane = FRGUIPaneFactory.createRightFlowInnerContainer_S_Pane(); + FlowLayout layout = new FlowLayout(FlowLayout.LEFT, 10 ,0); + toolbarPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 0, 0)); + toolbarPane.setLayout(layout); + addScaleButton(toolbarPane); + return toolbarPane; + } + + private void addScaleButton(JPanel toolbarPane) { + if (isElementCaseEditor()) { + plusButton = new UIButton(PLUS_ICON); + plusButton.setDisabledIcon(PLUS_DISABLED_ICON); + plusButton.setPressedIcon(PLUS_CLICK_ICON); + plusButton.setRolloverIcon(PLUS_HOVER_ICON); + plusButton.setPreferredSize(BUTTON_SIZE); + plusButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + addScale(10); + } + }); + + minusButton = new UIButton(MINUS_ICON); + minusButton.setDisabledIcon(MINUS_DISABLED_ICON); + minusButton.setPressedIcon(MINUS_CLICK_ICON); + minusButton.setRolloverIcon(MINUS_HOVER_ICON); + minusButton.setPreferredSize(BUTTON_SIZE); + minusButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + addScale(-10); + } + }); + + toolbarPane.add(minusButton); + toolbarPane.add(plusButton); + } + } + + private JPanel createViewPane() { + preview = FRGUIPaneFactory.createBorderLayout_S_Pane(); + preview.setBorder(BorderFactory.createEmptyBorder(5, 0 , 0 , 0)); + preview.setPreferredSize(this.previewSize); + preview.setSize(previewSize); + + if (isElementCaseEditor()) { + elementCasePreview(); + } else if (isChartEditor()) { + chartPreview(); + } else { + widgetPreview(); + } + + return preview; + } + + private void elementCasePreview() { + ElementCaseEditor editor = (ElementCaseEditor) widget; + FormElementCase elementCase = (FormElementCase) editor.getElementCase(); + FormElementCaseDesigner designer = new FormElementCaseDesigner(elementCase, new Form()); + designer.setForeground(Color.BLACK); + designer.setBackground(new Color(245, 245, 247)); + designer.setFont(DesignUtils.getDefaultGUIFont().applySize(12)); + elementCasePane = designer.getEditingElementCasePane(); + + elementCasePane.setPreferredSize(new Dimension(previewSize.width, getInnerPreviewSize().height)); + elementCasePane.setSelection(new CellSelection(0, 0, 0, 0)); + + Grid grid = elementCasePane.getGrid(); + grid.setEditable(false); + grid.removeMouseWheelListener(grid.getGridMouseAdapter()); + grid.removeMouseMotionListener(grid.getGridMouseAdapter()); + grid.removeMouseListener(grid.getGridMouseAdapter()); + + grid.addMouseWheelListener(new MouseWheelListener() { + @Override + public void mouseWheelMoved(MouseWheelEvent e) { + if (!InputEventBaseOnOS.isControlDown(e)) { + ElementCasePane reportPane = grid.getElementCasePane(); + if (reportPane.isVerticalScrollBarVisible()) { + JScrollBar scrollBar = reportPane.getVerticalScrollBar(); + int maxValue = scrollBar.getModel().getMaximum(); + int newValue = reportPane.getVerticalScrollBar().getValue() + e.getWheelRotation(); + int extendValue = GridUtils.getExtentValue(newValue, elementCase.getRowHeightList_DEC(), grid.getHeight(), getResolution()); + if (extendValue <= maxValue) { + reportPane.getVerticalScrollBar().setValue(newValue); + } + } + } else { + int dir = e.getWheelRotation(); + addScale( - dir * DIR); + grid.setCursor(SCALE_CURSOR); + } + } + }); + + grid.addMouseMotionListener(new MouseMotionAdapter() { + @Override + public void mouseMoved(MouseEvent e) { + grid.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + } + }); + + elementCasePane.getGridColumn().setEnabled(false); + elementCasePane.getGridRow().setEnabled(false); + + preview.add(designer, BorderLayout.CENTER); + preview.add(elementCasePane.getHorizontalScrollBar(), BorderLayout.SOUTH); + } + + private Dimension getInnerPreviewSize() { + if (isElementCaseEditor()) { + int width = previewSize.width - (enabled ? elementCasePane.getVerticalScrollBar().getPreferredSize().width : 0); + int height = previewSize.height - (enabled ? elementCasePane.getHorizontalScrollBar().getPreferredSize().height : 0); + return new Dimension(width, height); + } + return previewSize; + } + + private void chartPreview() { + ChartEditor editor = (ChartEditor) widget; + BaseChartCollection chartCollection = editor.getChartCollection(); + ChartIcon chartIcon = new ChartIcon(chartCollection, previewSize.width, previewSize.height); + chartIcon.registerCallBackEvent(PreviewPane.this); + UILabel label = new UILabel(chartIcon); + preview.add(label, BorderLayout.CENTER); + } + + private void widgetPreview(){ + JPanel widgetView = new JPanel(FRGUIPaneFactory.createBorderLayout()); + widgetView.setPreferredSize(previewSize); + widgetView.setBackground(Color.WHITE); + + XCreator xCreator = getWidgetXCreator(); + if (xCreator != null) { + previewImage = new BufferedImage(xCreator.getWidth(), xCreator.getHeight(), BufferedImage.TYPE_INT_RGB); + xCreator.paint(previewImage.getGraphics()); + Icon icon = new ImageIcon(previewImage); + UILabel label = new UILabel(icon); + label.setAlignmentY(SwingConstants.CENTER); + widgetView.add(label, BorderLayout.CENTER); + } + + preview.add(widgetView, BorderLayout.CENTER); + } + + private XCreator getWidgetXCreator() { + JTemplate jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + FormSelection selection = ((JForm) jt).getFormDesign().getSelectionModel().getSelection(); + XCreator[] xCreators = selection.getSelectedCreators(); + return getWidgetXCreator(xCreators, widget); + } + private XCreator getWidgetXCreator(Component[] components, Widget widget) { + for (Component component : components) { + if (component instanceof XCreator) { + XCreator xCreator = (XCreator) component; + if (xCreator.toData().getWidgetName() == widget.getWidgetName()) { + return xCreator; + } + XCreator subXCreator = getWidgetXCreator(xCreator.getComponents(), widget); + if (subXCreator != null) { + return subXCreator; + } + } + } + return null; + } + + @Override + public void callback() { + this.repaint(); + } + + private void setScale(int resolution) { + //网格线 + if (resolution < ScreenResolution.getScreenResolution() * MIN_TIME) { + elementCasePane.getGrid().setShowGridLine(false); + } else { + elementCasePane.getGrid().setShowGridLine(true); + } + elementCasePane.setResolution(resolution); + elementCasePane.getGrid().getGridMouseAdapter().setResolution(resolution); + elementCasePane.getGrid().setResolution(resolution); + //更新Grid + Grid grid = elementCasePane.getGrid(); + DynamicUnitList rowHeightList = ReportHelper.getRowHeightList(elementCasePane.getEditingElementCase()); + DynamicUnitList columnWidthList = ReportHelper.getColumnWidthList(elementCasePane.getEditingElementCase()); + grid.setVerticalExtent(GridUtils.getExtentValue(0, rowHeightList, grid.getHeight(), resolution)); + grid.setHorizontalExtent(GridUtils.getExtentValue(0, columnWidthList, grid.getWidth(), resolution)); + elementCasePane.getGrid().updateUI(); + //更新Column和Row + ((DynamicScrollBar) elementCasePane.getVerticalScrollBar()).setDpi(resolution); + ((DynamicScrollBar) elementCasePane.getHorizontalScrollBar()).setDpi(resolution); + elementCasePane.getGridColumn().setResolution(resolution); + elementCasePane.getGridColumn().updateUI(); + elementCasePane.getGridRow().setResolution(resolution); + elementCasePane.getGridRow().updateUI(); + elementCasePane.repaint(); + } + + private void addScale(int step) { + scaleValue += step; + scaleValue = fixedScale(scaleValue); + plusButton.setEnabled(scaleValue < MAX); + minusButton.setEnabled(scaleValue > MIN); + setScale(getResolution()); + } + + private int fixedScale(int value) { + if (value < MIN) { + value = MIN; + } + if (value > MAX) { + value = MAX; + } + return value; + } + + private int getResolution() { + return (int) (resolution * scaleValue / HUND); + } + + public boolean isElementCaseEditor() { + return widget instanceof ElementCaseEditor; + } + + public boolean isChartEditor() { + return widget instanceof ChartEditor; + } + + public ElementCasePane getElementCasePane() { + return elementCasePane; + } +} diff --git a/designer-realize/src/main/java/com/fr/design/share/ui/generate/CoverUploadPane.java b/designer-realize/src/main/java/com/fr/design/share/ui/generate/CoverUploadPane.java new file mode 100644 index 000000000..01d0c06a0 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/ui/generate/CoverUploadPane.java @@ -0,0 +1,59 @@ +package com.fr.design.share.ui.generate; + +import com.fr.base.background.ImageBackground; +import com.fr.design.beans.BasicBeanPane; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.share.ui.base.ImageBackgroundPane; +import com.fr.log.FineLoggerFactory; + +import javax.swing.BorderFactory; +import javax.swing.border.Border; +import javax.swing.border.MatteBorder; +import javax.swing.plaf.ColorUIResource; +import java.awt.BorderLayout; +import java.awt.Image; + +/** + * 上传封面的面板 + * Coder: zack + * Date: 2016/10/11 + * Time: 21:36 + */ +public class CoverUploadPane extends BasicBeanPane { + private static final ColorUIResource BORDER_COLOR = new ColorUIResource(168, 172, 180); + private static final Border DIALOG_BORDER = BorderFactory.createEmptyBorder(0, 6, 4, 6); + private ImageBackgroundPane backgroundPane; + + @Override + protected String title4PopupWindow() { + return Toolkit.i18nText("Fine-Design_Share_Select_Upload_Cover"); + } + + public CoverUploadPane() { + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + backgroundPane = new ImageBackgroundPane(); + backgroundPane.setBorder(new MatteBorder(1, 1, 1, 1, BORDER_COLOR)); + this.add(backgroundPane, BorderLayout.CENTER); + this.setBorder(DIALOG_BORDER); + } + + @Override + public void populateBean(Image ob) { + if (ob != null) { + backgroundPane.populate(new ImageBackground(ob)); + } + } + + @Override + public Image updateBean() { + ImageBackground imageBackground = new ImageBackground(); + try { + imageBackground = (ImageBackground) backgroundPane.update(); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + //返回原图 + return imageBackground.getImage(); + } +} diff --git a/designer-realize/src/main/java/com/fr/design/share/ui/generate/EffectContent.java b/designer-realize/src/main/java/com/fr/design/share/ui/generate/EffectContent.java new file mode 100644 index 000000000..63098ffd5 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/ui/generate/EffectContent.java @@ -0,0 +1,169 @@ +package com.fr.design.share.ui.generate; + +import com.fr.design.gui.icontainer.UIScrollPane; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.share.effect.EffectItem; +import com.fr.design.share.effect.EffectItemGroup; +import com.fr.design.share.ui.effect.PreviewPane; +import com.fr.design.share.ui.effect.EffectControlUpdatePane; +import com.fr.design.share.ui.effect.EffectPopupEditDialog; +import com.fr.design.share.ui.generate.table.EffectItemRender; +import com.fr.design.share.ui.generate.table.EffectTableModel; +import com.fr.design.share.ui.table.EffectItemEditor; +import com.fr.design.share.utils.ShareDialogUtils; +import com.fr.form.ui.Widget; +import com.fr.locale.InterProviderFactory; + +import javax.swing.BorderFactory; +import javax.swing.JComponent; +import javax.swing.JPanel; +import javax.swing.JTable; +import javax.swing.JTree; +import javax.swing.event.TreeSelectionListener; +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Toolkit; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseMotionAdapter; +import java.util.List; + +public class EffectContent extends JPanel { + static final private Dimension PREVIEW_SIZE = new Dimension(340, 120); + + private EffectItemGroup effectItemGroup; + private EffectPopupEditDialog effectPopupEditDialog; + private EffectControlUpdatePane effectControlUpdatePane; + + public EffectContent(EffectItemGroup effectItemGroup) { + this.effectItemGroup = effectItemGroup; + this.init(); + } + + private void init() { + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + + if (getEffectItems().size() > 0) { + // 预览图 + JPanel imageContainer = FRGUIPaneFactory.createLeftFlowZeroGapBorderPane(); + PreviewPane previewPane = new PreviewPane(getWidget(), PREVIEW_SIZE, false); + imageContainer.add(previewPane); + this.add(imageContainer, BorderLayout.NORTH); + + // 效果列表 + Object[] columnNames = {com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Share_From"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Share_Rename")}; + JTable table = new JTable(new EffectTableModel(effectItemGroup, columnNames)); + table.setRowHeight(25); + table.getColumnModel().getColumn(0).setPreferredWidth(235); + table.getColumnModel().getColumn(1).setPreferredWidth(325); + + + table.setDefaultEditor(EffectTableModel.class, new EffectItemEditor(table)); + table.setDefaultRenderer(EffectTableModel.class, new EffectItemRender()); + table.getTableHeader().setResizingAllowed(false); + table.getTableHeader().setReorderingAllowed(false); + table.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + int selectColumn = table.getSelectedColumn(); + if (selectColumn == 0) { + int selectRow = table.getSelectedRow(); + EffectItem selectEffectItem = getEffectItems().get(selectRow); + effectControlUpdatePane = EffectControlUpdatePane.newInstance(selectEffectItem); + effectControlUpdatePane.populate(); + setPaneDisabled(effectControlUpdatePane); + effectPopupEditDialog = EffectPopupEditDialog.newInstance(ShareDialogUtils.getInstance().getShareDialog(), effectControlUpdatePane); + effectPopupEditDialog.setTitle(selectEffectItem.getName()); + Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); + effectPopupEditDialog.setLocation((d.width - effectPopupEditDialog.getSize().width) / 2, (d.height - effectPopupEditDialog.getSize().height) / 2); + effectPopupEditDialog.setVisible(true); + } + } + public void mouseExited(MouseEvent e) { + int tableContentHeight = table.getParent().getHeight() - table.getTableHeader().getHeight(); + if ((e.getPoint().getY() < 0) || (e.getPoint().getY() > tableContentHeight)) { + table.clearSelection(); + } + int row = table.rowAtPoint(e.getPoint()); + int col = table.columnAtPoint(e.getPoint()); + if (row < 0 || col < 0) { + table.clearSelection(); + } + } + }); + table.addMouseMotionListener(new MouseMotionAdapter() { + @Override + public void mouseMoved(MouseEvent e) { + int row = table.rowAtPoint(e.getPoint()); + int col = table.columnAtPoint(e.getPoint()); + table.setRowSelectionInterval(row, row); + table.setColumnSelectionInterval(col, col); + } + }); + +// if (previewPane.isElementCaseEditor()) { +// table.getSelectionModel().addListSelectionListener(new ListSelectionListener() { +// @Override +// public void valueChanged(ListSelectionEvent e) { +// if (table.getSelectedRow() >= 0) { +// EffectItem effectItem= getEffectItems().get(table.getSelectedRow()); +// SourceNode cellSourceNode = SourceNodeUtils.getCellSourceNode(effectItem.getSourceNode()); +// if (cellSourceNode != null) { +// DefaultTemplateCellElement cellElement = (DefaultTemplateCellElement) cellSourceNode.getTarget(); +// previewPane.getElementCasePane().setSelection(new CellSelection(cellElement.getColumn(), cellElement.getRow(), cellElement.getColumnSpan(), cellElement.getRowSpan())); +// } +// } +// } +// }); +// } + + JPanel tableContainer = FRGUIPaneFactory.createBorderLayout_S_Pane(); + tableContainer.setBorder(BorderFactory.createEmptyBorder(10,0,5,0)); + if (getEffectItems().size() > 5) { + UIScrollPane scrollPane = new UIScrollPane(table); + scrollPane.setPreferredSize(new Dimension(550, 160)); + tableContainer.add(scrollPane, BorderLayout.CENTER); + } else { + JPanel tablePane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + tablePane.add(table.getTableHeader(), BorderLayout.NORTH); + tablePane.add(table, BorderLayout.CENTER); + tableContainer.add(tablePane, BorderLayout.CENTER); + } + this.add(tableContainer, BorderLayout.CENTER); + + } + } + + private List getEffectItems() { + return effectItemGroup.getEffectItems(); + } + + private Widget getWidget() { + return effectItemGroup.getWidget(); + } + + private void setPaneDisabled(Component component) { + if (component instanceof UIScrollPane) { + UIScrollPane pane = (UIScrollPane) component; + setPaneDisabled(pane.getViewport().getView()); + return; + } + if (component instanceof JTree) { + JTree tree = (JTree) component; + TreeSelectionListener[] treeSelectionListeners = tree.getTreeSelectionListeners(); + for (TreeSelectionListener treeSelectionListener : treeSelectionListeners) { + tree.removeTreeSelectionListener(treeSelectionListener); + } + return; + } + component.setEnabled(false); + if (component instanceof JComponent) { + Component[] components = ((JComponent) component).getComponents(); + for (Component co : components) { + setPaneDisabled(co); + } + } + } + +} diff --git a/designer-realize/src/main/java/com/fr/design/share/ui/generate/EffectPane.java b/designer-realize/src/main/java/com/fr/design/share/ui/generate/EffectPane.java new file mode 100644 index 000000000..f5ebd5edc --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/ui/generate/EffectPane.java @@ -0,0 +1,147 @@ +package com.fr.design.share.ui.generate; + +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.share.ui.base.PageableButton; +import com.fr.design.share.effect.EffectItemGroup; +import com.fr.form.ui.Widget; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.SwingConstants; +import javax.swing.plaf.basic.BasicArrowButton; +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.ArrayList; +import java.util.List; + + +public class EffectPane extends JPanel { + private List effectItemGroups; + private JPanel contentPane; + private int selectIndex = 0; + private BasicArrowButton previewButton; + private BasicArrowButton nextButton; + private UILabel nameLabel; + private List contents = new ArrayList<>(); + + + public EffectPane(List effectItemGroups) { + this.effectItemGroups = effectItemGroups; + if (effectItemGroups.size() > 0) { + initComponent(); + } + } + + private void initComponent() { + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + createContentPane(); + + JPanel rightPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + + JPanel headerPane = createHeaderPane(); + contentPane = createContentPane(); + addContent(); + rightPane.add(headerPane, BorderLayout.NORTH); + rightPane.add(contentPane, BorderLayout.CENTER); + this.add(rightPane, BorderLayout.CENTER); + } + + private JPanel createHeaderPane() { + JPanel headerPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + JPanel naviPane = createNaviPane(); + headerPane.add(naviPane, BorderLayout.EAST); + return headerPane; + } + + private JPanel createNaviPane() { + JPanel naviPane = new JPanel(FRGUIPaneFactory.createRightFlowLayout()); + nameLabel = new UILabel(""); + nameLabel.setPreferredSize(new Dimension(nameLabel.getFont().getSize() * 20, 15)); + nameLabel.setHorizontalAlignment(SwingConstants.RIGHT); + + previewButton = new PageableButton(SwingConstants.WEST) { + @Override + public Dimension getPreferredSize() { + return new Dimension(15, 15); + } + }; + previewButton.setEnabled(hasPreview()); + previewButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + selectIndex--; + EffectPane.this.TogglePage(); + } + }); + + nextButton = new PageableButton(SwingConstants.EAST) { + @Override + public Dimension getPreferredSize() { + return new Dimension(15, 15); + } + }; + nextButton.setEnabled(hasNext()); + nextButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + selectIndex++; + EffectPane.this.TogglePage(); + } + }); + + naviPane.add(nameLabel); + naviPane.add(previewButton); + naviPane.add(nextButton); + return naviPane; + } + + private JPanel createContentPane() { + JPanel contentPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + contentPane.setBorder(BorderFactory.createEmptyBorder(10, 0 , 0, 0)); + return contentPane; + } + + private void addContent() { + JPanel content = new EffectContent(getSelectEffectItemGroup()); + contents.add(selectIndex, content); + updateContent(); + } + + private Widget getSelectWidget() { + return getSelectEffectItemGroup().getWidget(); + } + + private EffectItemGroup getSelectEffectItemGroup() { + return effectItemGroups.get(selectIndex); + } + + private boolean hasPreview() { + return selectIndex > 0; + } + + private boolean hasNext() { + return selectIndex < effectItemGroups.size() - 1; + } + + private void TogglePage() { + previewButton.setEnabled(hasPreview()); + nextButton.setEnabled(hasNext()); + if (selectIndex < contents.size()) { + updateContent(); + } else { + addContent(); + } + } + + private void updateContent() { + // 添加contentPane + contentPane.removeAll(); + contentPane.add(contents.get(selectIndex)); + nameLabel.setText(getSelectWidget().getWidgetName()); + nameLabel.setToolTipText(getSelectWidget().getWidgetName()); + this.repaint(); + } +} diff --git a/designer-realize/src/main/java/com/fr/design/share/ui/generate/PriceExpectPane.java b/designer-realize/src/main/java/com/fr/design/share/ui/generate/PriceExpectPane.java new file mode 100644 index 000000000..7371c8e53 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/ui/generate/PriceExpectPane.java @@ -0,0 +1,87 @@ +package com.fr.design.share.ui.generate; + +import com.fr.design.gui.ibutton.UIRadioButton; +import com.fr.design.gui.itextfield.UITextField; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.stable.StringUtils; + +import javax.swing.ButtonGroup; +import javax.swing.JPanel; +import java.awt.Dimension; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/** + * Created by kerry on 2020-06-23 + */ +public class PriceExpectPane extends JPanel { + private static final int TEXT_FILED_WIDTH = 160; + private static final int TEXT_FILED_HEIGHT = 20; + private static final String FREE_PRICE = "0"; + private static final String PRICE_FORMAT = "%.2f"; + private UITextField priceFiled; + private UIRadioButton freeRadio; + private UIRadioButton chargeRadio; + + public PriceExpectPane() { + freeRadio = new UIRadioButton(Toolkit.i18nText("Fine-Design_Share_Price_Free")); + chargeRadio = new UIRadioButton(Toolkit.i18nText("Fine-Design_Share_Price_Charge")); + priceFiled = new UITextField(); + priceFiled.setPlaceholder(Toolkit.i18nText("Fine-Design_Share_Price_Charge_Tip")); + ButtonGroup radioGroup = new ButtonGroup(); + radioGroup.add(freeRadio); + radioGroup.add(chargeRadio); + this.setLayout(FRGUIPaneFactory.createBoxFlowLayout()); + this.add(freeRadio); + this.add(chargeRadio); + final JPanel panel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + panel.add(priceFiled); + this.add(panel); + panel.setPreferredSize(new Dimension(TEXT_FILED_WIDTH, TEXT_FILED_HEIGHT)); + panel.setVisible(false); + this.freeRadio.setSelected(true); + freeRadio.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + panel.setVisible(false); + + } + }); + chargeRadio.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + panel.setVisible(true); + } + }); + } + + public String getPrice() { + if (this.freeRadio.isSelected()) { + return FREE_PRICE; + } + float priceNumber = Float.parseFloat(this.priceFiled.getText()); + return String.format(PRICE_FORMAT, priceNumber); + } + + + public boolean check() { + if (freeRadio.isSelected()) { + return true; + } + String price = this.priceFiled.getText(); + if (StringUtils.isEmpty(price)) { + return false; + } + try { + float priceNumber = Float.parseFloat(price); + if (priceNumber <= 0) { + return false; + } + } catch (NumberFormatException e) { + return false; + } + return true; + } + +} diff --git a/designer-realize/src/main/java/com/fr/design/share/ui/generate/ShareGeneratePane.java b/designer-realize/src/main/java/com/fr/design/share/ui/generate/ShareGeneratePane.java new file mode 100644 index 000000000..d52cf1ef6 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/ui/generate/ShareGeneratePane.java @@ -0,0 +1,308 @@ +package com.fr.design.share.ui.generate; + +import com.fr.design.dialog.BasicDialog; +import com.fr.design.dialog.BasicPane; +import com.fr.design.dialog.DialogActionAdapter; +import com.fr.design.dialog.FineJOptionPane; +import com.fr.design.gui.icheckbox.UICheckBox; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.DesignerFrame; +import com.fr.design.mainframe.JTemplate; +import com.fr.design.mainframe.share.Bean.ComponentGenerateInfo; +import com.fr.design.mainframe.share.action.ShareUIAspect; +import com.fr.design.mainframe.share.collect.ComponentCollector; +import com.fr.design.mainframe.share.exception.LackOfValueException; +import com.fr.design.mainframe.share.generate.ComponentGeneratorCenter; +import com.fr.form.share.exception.NetWorkFailedException; +import com.fr.form.share.group.DefaultShareGroup; +import com.fr.design.mainframe.share.util.ShareUIUtils; +import com.fr.design.share.effect.EffectItemGroup; +import com.fr.design.share.utils.EffectItemUtils; +import com.fr.design.share.utils.ShareDialogUtils; +import com.fr.form.share.DefaultSharableWidget; +import com.fr.form.share.config.ComponentReuseConfigManager; +import com.fr.form.share.group.DefaultShareGroupManager; +import com.fr.form.share.Group; +import com.fr.form.share.record.ShareWidgetInfoManager; +import com.fr.form.ui.Widget; +import com.fr.log.FineLoggerFactory; +import com.fr.stable.StringUtils; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.SwingWorker; +import javax.swing.UIManager; +import javax.swing.border.Border; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import java.awt.BorderLayout; +import java.awt.CardLayout; +import java.awt.Dimension; +import java.awt.Image; +import java.awt.Rectangle; +import java.awt.event.ItemEvent; +import java.util.HashMap; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static javax.swing.JOptionPane.ERROR_MESSAGE; + +/** + * created by Harrison on 2020/04/20 + **/ +public class ShareGeneratePane extends BasicPane { + + private static final Dimension DIALOG_SIZE = new Dimension(670, 740); + private static final Dimension DIALOG_NORMAL_SIZE = new Dimension(660, 610); + private static final Border DIALOG_BORDER = BorderFactory.createEmptyBorder(0, 6, 4, 6); + + private JPanel mainPane = null; + private ShareMainPane uploadPane = null; + private ShareMainPane simplePane = null; + + private UICheckBox uploadCheckbox = null; + + private BasicDialog dialog; + + private final JTemplate jt; + //报表块控件 + private final Widget shareWidget; + //报表块数据集相关的参数 + private final HashMap paraMap; + + private List effectItemGroups; + + private final ShareUIAspect aspect; + + private final boolean supportUpload = ComponentReuseConfigManager.getInstance().supportUploadReu(); + + public ShareGeneratePane(JTemplate jt, Widget shareWidget, Rectangle rec, Image shareCover, HashMap paraMap, ShareUIAspect aspect) { + this.jt = jt; + this.shareWidget = shareWidget; + effectItemGroups = EffectItemUtils.getEffectItemGroupsByWidget(shareWidget); + this.paraMap = paraMap; + this.aspect = aspect; + + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + this.setBorder(DIALOG_BORDER); + this.setPreferredSize(getDialogSize()); + + JPanel guidePane = initGuidePane(shareCover, rec); + this.add(guidePane, BorderLayout.CENTER); + } + + private JPanel initGuidePane(Image shareCover, Rectangle rec) { + + JPanel pane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + + this.mainPane = FRGUIPaneFactory.createCardLayout_S_Pane(); + this.simplePane = new ShareMainPane(shareCover, rec, false, effectItemGroups); + this.uploadPane = new ShareMainPane(shareCover, rec, true, effectItemGroups); + //暂时换一下,目前不用上传 + this.mainPane.add(simplePane, ShareUIUtils.convertStateChange(ItemEvent.DESELECTED)); + this.mainPane.add(uploadPane, ShareUIUtils.convertStateChange(ItemEvent.SELECTED)); + + simplePane.getNameField().getDocument().addDocumentListener(new DocumentListener() { + + @Override + public void changedUpdate(DocumentEvent e) { + validInput(); + } + + @Override + public void insertUpdate(DocumentEvent e) { + validInput(); + } + + @Override + public void removeUpdate(DocumentEvent e) { + validInput(); + } + }); + + uploadPane.getNameField().getDocument().addDocumentListener(new DocumentListener() { + + @Override + public void changedUpdate(DocumentEvent e) { + validInput(); + } + + @Override + public void insertUpdate(DocumentEvent e) { + validInput(); + } + + @Override + public void removeUpdate(DocumentEvent e) { + validInput(); + } + }); + + //后面创建,因为需要依赖 mainPane 的创建 + JPanel uploadCheckBox = createUploadCheckBox(); + if (supportUpload) { + pane.add(uploadCheckBox, BorderLayout.NORTH); + } + pane.add(mainPane, BorderLayout.CENTER); + return pane; + } + + private void validInput() { + String userInput = getSelectMainPane().getNameField().getText().trim(); + + if (StringUtils.isEmpty(userInput)) { + dialog.setButtonEnabled(false); + } else { + dialog.setButtonEnabled(true); + } + } + + private JPanel createUploadCheckBox() { + + JPanel panel = FRGUIPaneFactory.createBoxFlowInnerContainer_S_Pane(); + String label = Toolkit.i18nText("Fine-Design_Share_Upload_Meanwhile"); + this.uploadCheckbox = new UICheckBox(label); + uploadCheckbox.addItemListener(e -> { + int stateChange = e.getStateChange(); + CardLayout cl = (CardLayout) (mainPane.getLayout()); + cl.show(mainPane, ShareUIUtils.convertStateChange(stateChange)); + repaint(); + }); + uploadCheckbox.setSelected(false); + + UILabel tipsLabel = ShareUIUtils.createTipsLabel(Toolkit.i18nText("Fine-Design_Share_Upload_Meanwhile_Tips")); + panel.add(uploadCheckbox); + panel.add(tipsLabel); + panel.setPreferredSize(new Dimension(585, 30)); + return panel; + } + + /* show 相关 */ + @Override + public void show() { + final DesignerFrame designerFrame = DesignerContext.getDesignerFrame(); + dialog = this.showWindowWithCustomSize(designerFrame, null, getDialogSize()); + dialog.setButtonEnabled(false); + ShareDialogUtils.getInstance().setShareDialog(dialog); + dialog.addDialogActionListener(new DialogActionAdapter() { + + @Override + public void doOk() { + ShareMainPane mainPane = getSelectMainPane(); + if (doCheck(mainPane)) { + dialog.setVisible(false); + doOk0(mainPane); + } else { + // 抛出,从而防止页面关闭 + throw new LackOfValueException(); + } + } + }); + dialog.setVisible(true); + } + + private ShareMainPane getSelectMainPane() { + + ShareMainPane mainPane; + if (uploadCheckbox.isSelected()) { + mainPane = uploadPane; + } else { + mainPane = simplePane; + } + return mainPane; + } + + private boolean doCheck(ShareMainPane mainPane) { + + return mainPane.check(); + } + + private void doOk0(final ShareMainPane mainPane) { + for(EffectItemGroup effectItemGroup : effectItemGroups) { + effectItemGroup.save(); + } + SwingWorker worker = new SwingWorker() { + @Override + protected Void doInBackground() throws Exception { + DefaultSharableWidget provider = mainPane.generate(); + Group selectGroup = mainPane.getSelectGroup(); + boolean success = false; + try { + success = generateModule(provider); + if (success) { + //先读文件然后移动到指定分组 + Group defaultGroup = DefaultShareGroupManager.getInstance().getGroup(DefaultShareGroup.GROUP_NAME); + if (defaultGroup != null) { + defaultGroup.loadModule(provider.getFileName()); + defaultGroup.moveModule(selectGroup, Stream.of(provider.getId()).collect(Collectors.toList())); + } + collect(provider); + ShareWidgetInfoManager.getInstance().addCompCreateInfo(provider); + } + } catch (NetWorkFailedException exception) { + FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), ShareUIUtils.formatWidthString(Toolkit.i18nText("Fine-Design_Share_NetWorkError"), 200), + Toolkit.i18nText("Fine-Design_Basic_Error"), ERROR_MESSAGE, UIManager.getIcon("OptionPane.errorIcon")); + return null; + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } finally { + //成功失败,都要处理 + aspect.afterOk(); + } + if (!success) { + FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Design_Share_Module_Failed"), + Toolkit.i18nText("Fine-Design_Basic_Error"), ERROR_MESSAGE, UIManager.getIcon("OptionPane.errorIcon")); + } + return null; + } + }; + worker.execute(); + } + + private void collect(DefaultSharableWidget provider) { + + ComponentCollector.getInstance().collectGenerateCmpNumber(); + ComponentCollector.getInstance().collectGenerateCmpRecord(provider); + if (uploadCheckbox.isSelected()) { + ComponentCollector.getInstance().collectUploadCmpNumber(); + } + } + + private boolean generateModule(DefaultSharableWidget info) throws Exception { + + DefaultSharableWidget transformInfo = transform(info); + ComponentGenerateInfo generateInfo = new ComponentGenerateInfo(uploadCheckbox.isSelected(), jt, paraMap, shareWidget, transformInfo); + ComponentGeneratorCenter center = new ComponentGeneratorCenter(generateInfo); + return center.generate(); + } + + private DefaultSharableWidget transform(DefaultSharableWidget info) { + + //先屏蔽 + //if (shareWidget instanceof AbstractBorderStyleWidget) { + // AbstractBorderStyleWidget styleWidget = (AbstractBorderStyleWidget) shareWidget; + // ExtendSharableAttrMark attrMark = styleWidget.getWidgetAttrMark(ExtendSharableAttrMark.XML_TAG); + // if (attrMark != null) { + // String shareId = attrMark.getShareId(); + // info.setId(shareId); + // } + //} + return info; + } + + + @Override + protected String title4PopupWindow() { + return Toolkit.i18nText("Fine-Design_Share_Module_Msg"); + } + + private Dimension getDialogSize() { + return effectItemGroups.size() > 0 ? DIALOG_SIZE : DIALOG_NORMAL_SIZE; + } + + +} diff --git a/designer-realize/src/main/java/com/fr/design/share/ui/generate/ShareLoginLabel.java b/designer-realize/src/main/java/com/fr/design/share/ui/generate/ShareLoginLabel.java new file mode 100644 index 000000000..14ad32415 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/ui/generate/ShareLoginLabel.java @@ -0,0 +1,50 @@ +package com.fr.design.share.ui.generate; + +import com.fr.config.MarketConfig; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.mainframe.bbs.UserInfoPane; +import com.fr.stable.StringUtils; + +import javax.swing.JPanel; + +/** + * created by Harrison on 2020/04/20 + **/ +public class ShareLoginLabel extends UILabel { + + private JPanel vendorPane; + + private UILabel unLoginLabel; + + private UILabel loginLabel; + + public ShareLoginLabel(JPanel vendorPane, UILabel unLoginLabel, UILabel loginLabel) { + this.vendorPane = vendorPane; + this.unLoginLabel = unLoginLabel; + this.loginLabel = loginLabel; + setVisible(false); + } + + @Override + public void setText(String text) { + super.setText(text); + if (StringUtils.isNotEmpty(text)) { + tryGetLogin(); + } + } + + private void tryGetLogin() { + + String bbsUsername = MarketConfig.getInstance().getBbsUsername(); + if (StringUtils.isNotEmpty(bbsUsername)) { + vendorPane.remove(unLoginLabel); + loginLabel.setText(bbsUsername); + vendorPane.add(loginLabel); + // 像这种 remove , 再 add 的, 需要 validate() + vendorPane.validate(); + vendorPane.repaint(); + //同步刷新页面 + UserInfoPane.getInstance().updateBBSUserInfo(); + } + } +} diff --git a/designer-realize/src/main/java/com/fr/design/share/ui/generate/ShareMainPane.java b/designer-realize/src/main/java/com/fr/design/share/ui/generate/ShareMainPane.java new file mode 100644 index 000000000..3cd865353 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/ui/generate/ShareMainPane.java @@ -0,0 +1,702 @@ +package com.fr.design.share.ui.generate; + +import com.fr.config.MarketConfig; +import com.fr.design.constants.LayoutConstants; +import com.fr.design.dialog.BasicDialog; +import com.fr.design.dialog.DialogActionAdapter; +import com.fr.design.dialog.FineJOptionPane; +import com.fr.design.extra.LoginWebBridge; +import com.fr.design.extra.WebViewDlgHelper; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.icheckbox.UICheckBox; +import com.fr.design.gui.icombobox.UIComboBox; +import com.fr.design.gui.icombocheckbox.UIComboCheckBox; +import com.fr.design.gui.icontainer.UIScrollPane; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.gui.itextfield.UITextField; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.layout.TableLayout; +import com.fr.design.layout.TableLayoutHelper; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.share.constants.ComponentType; +import com.fr.design.mainframe.share.constants.ComponentTypes; +import com.fr.design.mainframe.share.constants.DisplayDevice; +import com.fr.design.mainframe.share.constants.StyleTheme; +import com.fr.design.mainframe.share.ui.base.DictionaryComboCheckBox; +import com.fr.design.mainframe.share.ui.base.LeftWordsTextArea; +import com.fr.design.mainframe.share.ui.base.PlaceholderTextArea; +import com.fr.design.mainframe.share.ui.base.ui.PlaceHolderUI; +import com.fr.design.mainframe.share.util.ShareUIUtils; +import com.fr.design.share.effect.EffectItemGroup; +import com.fr.design.share.utils.ShareDialogUtils; +import com.fr.form.share.DefaultSharableWidget; +import com.fr.form.share.bean.StyleThemeBean; +import com.fr.form.share.constants.ShareComponentConstants; +import com.fr.form.share.group.DefaultShareGroupManager; +import com.fr.form.share.Group; +import com.fr.plugin.context.PluginContext; +import com.fr.plugin.manage.PluginFilter; +import com.fr.plugin.manage.PluginManager; +import com.fr.stable.ArrayUtils; +import com.fr.stable.ProductConstants; +import com.fr.stable.StringUtils; +import com.fr.stable.collections.combination.Pair; +import com.fr.stable.pinyin.PinyinHelper; +import org.jetbrains.annotations.NotNull; + +import javax.swing.BorderFactory; +import javax.swing.Icon; +import javax.swing.ImageIcon; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.UIManager; +import javax.swing.border.MatteBorder; +import javax.swing.text.AttributeSet; +import javax.swing.text.BadLocationException; +import javax.swing.text.PlainDocument; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dialog; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Image; +import java.awt.ItemSelectable; +import java.awt.Rectangle; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.LinkedList; +import java.util.List; +import java.util.UUID; + +import static javax.swing.JOptionPane.ERROR_MESSAGE; + +/** + * created by Harrison on 2020/04/20 + **/ +public class ShareMainPane extends JPanel { + + private static final int COLUMN_ITEM_SIZE = 60; + private static final int COLUMN_FIELD_WIDTH = 560; + private static final int TEXT_FIELD_WIDTH = 160; + private static final int TEXT_FIELD_HEIGHT = 21; + private static final int NAME_MAX_LENGTH = 50; + private static final int GROUP_WIDTH = 160; + private static final int COMBO_WIDTH = 90; + private static final int COMBO_WIDTH_PLUS = 150; + private static final int COMBO_HEIGHT = 20; + private static final int BTN_WIDTH = 70; + private static final int BTN_HEIGHT = 20; + private static final int BASEPANE_VERTICAL_GAP = 2; + + private UIScrollPane mainPane = null; + + private UICheckBox pluginCheckBox = new UICheckBox(Toolkit.i18nText("Fine-Design_Share_Make_Relate_To_Plugin")); + private PriceExpectPane priceExpectPane = null; + + private UIComboBox parentClassify = null; + private UIComboBox childClassify = null; + + private UIComboBox localGroup = null; + + private UILabel loginLabel = ShareUIUtils.createCenterRightUILabel(StringUtils.EMPTY); + + private UICheckBox pc = new UICheckBox(Toolkit.i18nText("Fine-Design_Share_PC_Device")); + private UICheckBox mobile = new UICheckBox(Toolkit.i18nText("Fine-Design_Share_Mobile_Device")); + + private UIComboCheckBox pluginComboCheckBox = null; + + private UIComboBox styleComboBox = null; + + private UITextField nameField = new UITextField(); + + private PlaceholderTextArea content = new LeftWordsTextArea(); + + private PlaceholderTextArea help = new PlaceholderTextArea(); + private UILabel cover; + private UIButton uploadBtn; + //控件的缩略图 + private Image shareCover; + private Rectangle rec; + private boolean upload; + + private List effectItemGroups; + + public ShareMainPane(Image shareCover, Rectangle rec, boolean upload, List effectItemGroups) { + + this.shareCover = shareCover; + this.rec = rec; + this.upload = upload; + this.effectItemGroups = effectItemGroups; + + initCover(shareCover); + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + this.setBorder(BorderFactory.createEmptyBorder()); + + this.mainPane = createMainPane(upload); + this.add(this.mainPane, BorderLayout.CENTER); + } + + private void initCover(Image shareCover) { + this.cover = new UILabel(getShowIcon(shareCover)); + MatteBorder matteBorder = BorderFactory.createMatteBorder(3, 3, 3, 3, Color.WHITE); + this.cover.setBorder(matteBorder); + this.cover.setHorizontalAlignment(JLabel.CENTER); + } + + private Icon getShowIcon(Image image) { + Image scaleImage = image.getScaledInstance(ShareComponentConstants.SHARE_THUMB_WIDTH, ShareComponentConstants.SHARE_THUMB_HEIGHT, Image.SCALE_SMOOTH); + return new ImageIcon(scaleImage); + } + + + @NotNull + private UIScrollPane createMainPane(boolean upload) { + JPanel mainPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + UIScrollPane scrollPane = new UIScrollPane(mainPane); + JPanel overviewPane = createOverviewPane(upload); + JPanel basePane = createBasePane(upload); + mainPane.add(basePane, BorderLayout.NORTH); + mainPane.add(overviewPane, BorderLayout.CENTER); + return scrollPane; + } + + private JPanel createOverviewPane(boolean upload) { + JPanel componentPane = createComponentOverviewPane(upload); + String title = Toolkit.i18nText("Fine-Design_Share_Overview"); + JPanel overviewPane = FRGUIPaneFactory.createTitledBorderPane(title); + overviewPane.add(componentPane, BorderLayout.CENTER); + + return overviewPane; + + } + + private JPanel createBasePane(boolean upload) { + // 提示 + UILabel tipsLabel = ShareUIUtils.createTipsLabel(Toolkit.i18nText("Fine-Design_Share_Generate_Help_Tips")); + tipsLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 10, 0)); + // 组件名称 + UILabel nameLabel = ShareUIUtils.createTopRightUILabel(Toolkit.i18nText("Fine-Design_Share_Name")); + JPanel symbolTextField = createNameFiledPane(); + //显示封面 + UILabel coverLabel = ShareUIUtils.createTopRightUILabel(Toolkit.i18nText("Fine-Design_Share_Show_Cover")); + JPanel coverImagePane = getCoverImagePane(); + //制作者 + UILabel vendorLabel = ShareUIUtils.createCenterRightUILabel(Toolkit.i18nText("Fine-Design_Share_Share_Vendor")); + JPanel vendorPane = createVendorPane(); + //适用终端 + UILabel deviceLabel = ShareUIUtils.createCenterRightUILabel(Toolkit.i18nText("Fine-Design_Share_Device")); + JPanel devicePane = createDevicePane(); + //组件分类 + UILabel classifyLabel = ShareUIUtils.createCenterRightUILabel(Toolkit.i18nText("Fine-Design_Share_Classify")); + JPanel classifyPane = createClassifyPane(); + + //样式风格 + UILabel styleThemeLabel = ShareUIUtils.createCenterRightUILabel(Toolkit.i18nText("Fine-Design_Share_Style_Theme")); + JPanel styleThemePane = createStyleThemePane(); + //本地分组 + UILabel localGroupLabel = ShareUIUtils.createCenterRightUILabel(Toolkit.i18nText("Fine-Design_Share_Local_Group")); + JPanel localGroupPane = createLocalGroupPane(); + //使用插件 + UILabel pluginLabel = ShareUIUtils.createCenterRightUILabel(Toolkit.i18nText("Fine-Design_Share_Use_Plugin")); + JPanel pluginPane = createPluginPane(); + //期望价格 + UILabel priceLabel = ShareUIUtils.createCenterRightUILabel(Toolkit.i18nText("Fine-Design_Share_Expect_Price")); + JPanel pricePane = createPricePane(); + + double p = TableLayout.PREFERRED; + + JPanel innerPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + JPanel infoPane; + if (upload) { + Component[][] components = new Component[][]{ + new Component[]{nameLabel, symbolTextField}, + new Component[]{coverLabel, coverImagePane}, + new Component[]{vendorLabel, vendorPane}, + new Component[]{deviceLabel, devicePane}, + new Component[]{classifyLabel, classifyPane}, + new Component[]{styleThemeLabel, styleThemePane}, + new Component[]{pluginLabel, pluginPane}, + new Component[]{priceLabel, pricePane}, + }; + double[] rowSize = {p, p, p, p, p, p, p, p}; + double[] columnSize = {COLUMN_ITEM_SIZE, p}; + int[][] rowCount = {{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1},{1, 1}, {1, 1}}; + infoPane = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, LayoutConstants.HGAP_SMALL, BASEPANE_VERTICAL_GAP); + } else { + Component[][] components = new Component[][]{ + new Component[]{nameLabel, symbolTextField}, + new Component[]{coverLabel, coverImagePane}, + new Component[]{deviceLabel, devicePane}, + new Component[]{classifyLabel, classifyPane}, + new Component[]{localGroupLabel, localGroupPane} + }; + double[] rowSize = {p, p, p, p, p}; + double[] columnSize = {COLUMN_ITEM_SIZE, p}; + int[][] rowCount = {{1, 1}, {1, 1}, {1, 1},{1, 1}, {1, 1}}; + infoPane = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, LayoutConstants.HGAP_SMALL, BASEPANE_VERTICAL_GAP); + } + + String title = Toolkit.i18nText("Fine-Design_Share_Base_Info"); + JPanel overviewPane = FRGUIPaneFactory.createTitledBorderPane(title); + + innerPane.add(tipsLabel, BorderLayout.NORTH); + innerPane.add(infoPane, BorderLayout.CENTER); + overviewPane.add(innerPane, BorderLayout.CENTER); + + return overviewPane; + } + + private JPanel createEffectPane(List effectItemGroups) { + return new EffectPane(effectItemGroups); + } + + private JPanel createPricePane() { + + JPanel pane = FRGUIPaneFactory.createBoxFlowInnerContainer_S_Pane(); + this.priceExpectPane = new PriceExpectPane(); + pane.add(priceExpectPane); + return pane; + } + + private JPanel createStyleThemePane() { + JPanel pane = FRGUIPaneFactory.createBoxFlowInnerContainer_S_Pane(); + PlaceHolderUI placeHolderUI = new PlaceHolderUI( + Toolkit.i18nText("Fine-Design_Share_Style_Theme_Place_Holder")) { + @Override + protected boolean validate(UIComboBox uiComboBox) { + return styleComboBox.getSelectedItem() != null; + } + }; + this.styleComboBox = ShareUIUtils.wrapUI(placeHolderUI, new UIComboBox()); + this.styleComboBox.refreshBoxItems(StyleTheme.getStyleThemeTypeInfo()); + styleComboBox.setPreferredSize(new Dimension(COMBO_WIDTH, COMBO_HEIGHT)); + pane.add(styleComboBox); + return pane; + } + + private JPanel createPluginPane() { + + JPanel pane = FRGUIPaneFactory.createBoxFlowInnerContainer_S_Pane(); + + List contexts = PluginManager.getContexts(new PluginFilter() { + @Override + public boolean accept(PluginContext pluginContext) { + + return pluginContext.isRunning(); + } + }); + String[] displays = new String[contexts.size()]; + String[] values = new String[contexts.size()]; + Pair[] pairs = new Pair[contexts.size()]; + for (int i = 0; i < contexts.size(); i++) { + PluginContext context = contexts.get(i); + String display = context.getName(); + String value = context.getID() + "-" + context.getVersion(); + pairs[i] = new Pair<>(display, value); + } + //按照顺序展示 + //转换一下中文为拼音 + Arrays.sort(pairs, new Comparator>() { + @Override + public int compare(Pair pair1, Pair pair2) { + String o1 = pair1.getFirst(); + String o2 = pair2.getFirst(); + String pinyin1 = PinyinHelper.getShortPinyin(o1); + String pinyin2 = PinyinHelper.getShortPinyin(o2); + return pinyin1.compareToIgnoreCase(pinyin2); + } + }); + for (int i = 0; i < pairs.length; i++) { + displays[i] = pairs[i].getFirst(); + values[i] = pairs[i].getSecond(); + } + this.pluginComboCheckBox = new DictionaryComboCheckBox(values, displays, "Fine-Design_Share_Select_Plugin"); + + pluginComboCheckBox.setPopupMaxDisplayNumber(10); + pluginComboCheckBox.setVisible(false); + + pluginCheckBox.addItemListener(new ItemListener() { + @Override + public void itemStateChanged(ItemEvent e) { + int stateChange = e.getStateChange(); + pluginComboCheckBox.setVisible(stateChange == ItemEvent.SELECTED); + pluginComboCheckBox.repaint(); + } + }); + + pane.add(pluginCheckBox); + pane.add(pluginComboCheckBox); + return pane; + } + + private JPanel createClassifyPane() { + + JPanel pane = new JPanel(); + //距离远一点 + pane.setLayout(new FlowLayout(FlowLayout.LEFT, 2, 5)); + this.parentClassify = new UIComboBox(ComponentTypes.values()); + this.parentClassify.setPreferredSize(new Dimension(COMBO_WIDTH, COMBO_HEIGHT)); + + List children = ComponentTypes.CHART.children(-1); + final String placeHolderText = Toolkit.i18nText("Fine-Design_Share_Select_Type"); + PlaceHolderUI placeHolderUI = new PlaceHolderUI(placeHolderText) { + @Override + protected boolean validate(UIComboBox comboBox) { + return childClassify.getSelectedItem() != null; + } + }; + this.childClassify = ShareUIUtils.wrapUI(placeHolderUI, new UIComboBox()); + this.childClassify.refreshBoxItems(children); + this.childClassify.setPreferredSize(new Dimension(COMBO_WIDTH_PLUS, COMBO_HEIGHT)); + this.childClassify.setBorder(BorderFactory.createEmptyBorder()); + + parentClassify.addItemListener(new ItemListener() { + + @Override + public void itemStateChanged(ItemEvent e) { + + ItemSelectable itemSelectable = e.getItemSelectable(); + ComponentType selectedItem = (ComponentType) ((UIComboBox) itemSelectable).getSelectedItem(); + if (selectedItem != null) { + int device = displayDevice(); + List children = selectedItem.children(device); + childClassify.clearBoxItems(); + childClassify.refreshBoxItems(children); + } + } + }); + + //设置默认值 + this.parentClassify.setSelectedItem(ComponentTypes.CHART); + + pane.add(parentClassify); + pane.add(childClassify); + return pane; + } + + private JPanel createLocalGroupPane() { + + JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT, 2, 2)); + this.localGroup = new UIComboBox(DefaultShareGroupManager.getInstance().getAllGroup()); + this.localGroup.setPreferredSize(new Dimension(GROUP_WIDTH, COMBO_HEIGHT)); + + panel.add(localGroup); + return panel; + } + + private JPanel createDevicePane() { + + JPanel pane = FRGUIPaneFactory.createBoxFlowInnerContainer_S_Pane(); + pc.setSelected(true); + mobile.setSelected(true); + + ItemListener parentClassifyRefresh = new ItemListener() { + @Override + public void itemStateChanged(ItemEvent e) { + parentClassify.setSelectedItem(ComponentTypes.CHART); + } + }; + + pc.addItemListener(parentClassifyRefresh); + + mobile.addItemListener(parentClassifyRefresh); + pane.add(pc); + pane.add(mobile); + return pane; + } + + @NotNull + private JPanel createVendorPane() { + + final JPanel vendorPane = FRGUIPaneFactory.createBoxFlowInnerContainer_S_Pane(); + + String bbsUsername = MarketConfig.getInstance().getBbsUsername(); + if (StringUtils.isEmpty(bbsUsername)) { + UILabel unLoginLabel = ShareUIUtils.createHyperlinkLabel(Toolkit.i18nText("Fine-Design_Share_Click_Login")); + + final UILabel hidden = new ShareLoginLabel(vendorPane, unLoginLabel, loginLabel); + + unLoginLabel.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + LoginWebBridge.getHelper().setUILabel(hidden); + Dialog shareDialog = ShareDialogUtils.getInstance().getShareDialog(); + //必须这样创建,不然窗口优先级不对 + WebViewDlgHelper.createLoginDialog(shareDialog); + } + }); + vendorPane.add(unLoginLabel); + } else { + loginLabel.setText(bbsUsername); + vendorPane.add(loginLabel); + } + + return vendorPane; + } + + @NotNull + private JPanel createComponentOverviewPane(boolean upload) { + //功能介绍 + UILabel effectLabel = ShareUIUtils.createTopRightUILabel(Toolkit.i18nText("Fine-Design_Share_Special_Effects")); + JPanel effectPane = createEffectPane(effectItemGroups); + + content.setDocument( + new LimitedDocument(200, 500) + ); + String contentTip = Toolkit.i18nText("Fine-Design_Share_Content_Introduction_Placeholder"); + content.setAutoscrolls(true); + content.setPlaceholder(contentTip); + UIScrollPane contentPane = new UIScrollPane(content); + contentPane.setPreferredSize(new Dimension(COLUMN_FIELD_WIDTH, 50)); + contentPane.setBorder(null); + + help.setDocument( + new LimitedDocument(1000) + ); + String helpTip = Toolkit.i18nText("Fine-Design_Share_Help_Msg_Placeholder"); + help.setPlaceholder(helpTip); + UIScrollPane helpPane = new UIScrollPane(help); + helpPane.setPreferredSize(new Dimension(COLUMN_FIELD_WIDTH, 50)); + helpPane.setBorder(null); + + UILabel helpLabel = ShareUIUtils.createTopRightUILabel(Toolkit.i18nText("Fine-Design_Share_Help_Msg")); + UILabel contentLabel = ShareUIUtils.createTopRightUILabel(Toolkit.i18nText("Fine-Design_Share_Content_Introduction")); + + + double p = TableLayout.PREFERRED; + int[] row = {1, 1}; + double[] columnSize = {COLUMN_ITEM_SIZE, p}; + List componentList= new LinkedList(); + List rowSizeList = new LinkedList(); + List rowCountList = new LinkedList(); + + if (effectItemGroups.size() > 0 ) { + componentList.add(new Component[]{effectLabel, effectPane}); + } + + componentList.add(new Component[]{helpLabel, helpPane}); + + if (upload) { + componentList.add(new Component[]{contentLabel, contentPane}); + } + for (int i = 0; i < componentList.size(); i++) { + rowSizeList.add(p); + rowCountList.add(row); + } + + return TableLayoutHelper.createGapTableLayoutPane( + componentList.toArray(new Component[componentList.size()][]), + ArrayUtils.toPrimitive(rowSizeList.toArray(new Double[rowSizeList.size()])), + columnSize, + rowCountList.toArray(new int[rowCountList.size()][]), + LayoutConstants.VGAP_MEDIUM, LayoutConstants.VGAP_MEDIUM); + } + + private JPanel createNameFiledPane() { + LimitedDocument nameLimited = new LimitedDocument(NAME_MAX_LENGTH); + nameField.setPlaceholder(Toolkit.i18nText("Fine-Design_Share_Name_Placeholder")); + nameField.setPreferredSize(new Dimension(TEXT_FIELD_WIDTH, TEXT_FIELD_HEIGHT)); + nameField.setDocument(nameLimited); + JPanel symbolTextFiled = FRGUIPaneFactory.createBorderLayout_S_Pane(); + UILabel validSymbol = new UILabel(" *"); + symbolTextFiled.add(nameField, BorderLayout.CENTER); + symbolTextFiled.add(validSymbol, BorderLayout.EAST); + + return symbolTextFiled; + } + + + private void initUploadCoverBtn() { + + this.uploadBtn = new UIButton(Toolkit.i18nText("Fine-Design_Share_Select_Upload_Cover")); + this.uploadBtn.setPreferredSize(new Dimension(BTN_WIDTH, BTN_HEIGHT)); + uploadBtn.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + final CoverUploadPane pane = new CoverUploadPane(); + BasicDialog basicDialog = pane.showWindow(DesignerContext.getDesignerFrame(), true); + pane.setSize(BasicDialog.MEDIUM); + pane.populateBean(shareCover); + basicDialog.addDialogActionListener(new DialogActionAdapter() { + @Override + public void doOk() { + shareCover = pane.updateBean(); + cover.setIcon(getShowIcon(shareCover)); + cover.repaint(); + } + }); + basicDialog.setVisible(true); + } + }); + } + + private JPanel getCoverImagePane() { + + initUploadCoverBtn(); + JPanel coverImagePane = FRGUIPaneFactory.createNormalFlowInnerContainer_S_Pane(); + cover.setPreferredSize(new Dimension(ShareComponentConstants.SHARE_THUMB_WIDTH, ShareComponentConstants.SHARE_THUMB_HEIGHT)); + coverImagePane.add(cover); + + JPanel uploadBtnPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + uploadBtnPane.setPreferredSize(new Dimension(BTN_WIDTH, ShareComponentConstants.SHARE_THUMB_HEIGHT)); + uploadBtnPane.add(uploadBtn, BorderLayout.SOUTH); + coverImagePane.add(uploadBtnPane); + + return coverImagePane; + + } + + /* 校验 */ + + public boolean check() { + + Dialog shareDialog = ShareDialogUtils.getInstance().getShareDialog(); + String name = nameField.getText(); + if (StringUtils.isEmpty(name)) { + FineJOptionPane.showMessageDialog(shareDialog, Toolkit.i18nText("Fine-Design_Share_Lack_Name"), + Toolkit.i18nText("Fine-Design_Basic_Error"), ERROR_MESSAGE, UIManager.getIcon("OptionPane.errorIcon")); + return false; + } + if (upload && StringUtils.isEmpty(content.getText())) { + FineJOptionPane.showMessageDialog(shareDialog, Toolkit.i18nText("Fine-Design_Share_Lack_Content"), + Toolkit.i18nText("Fine-Design_Basic_Error"), ERROR_MESSAGE, UIManager.getIcon("OptionPane.errorIcon")); + return false; + } + if (upload && StringUtils.isEmpty(loginLabel.getText())) { + FineJOptionPane.showMessageDialog(shareDialog, Toolkit.i18nText("Fine-Design_Share_Lack_Login"), + Toolkit.i18nText("Fine-Design_Basic_Error"), ERROR_MESSAGE, UIManager.getIcon("OptionPane.errorIcon")); + return false; + } + if (upload && styleComboBox.getSelectedItem() == null) { + FineJOptionPane.showMessageDialog(shareDialog, Toolkit.i18nText("Fine-Design_Share_Style_Theme_Tip"), + Toolkit.i18nText("Fine-Design_Basic_Error"), ERROR_MESSAGE, UIManager.getIcon("OptionPane.errorIcon")); + return false; + } + if (!pc.isSelected() && !mobile.isSelected()) { + FineJOptionPane.showMessageDialog(shareDialog, Toolkit.i18nText("Fine-Design_Share_Lack_Device"), + Toolkit.i18nText("Fine-Design_Basic_Error"), ERROR_MESSAGE, UIManager.getIcon("OptionPane.errorIcon")); + return false; + } + if (pluginCheckBox.isSelected() && ArrayUtils.isEmpty(pluginComboCheckBox.getSelectedValues())) { + FineJOptionPane.showMessageDialog(shareDialog, Toolkit.i18nText("Fine-Design_Share_Lack_Plugins"), + Toolkit.i18nText("Fine-Design_Basic_Error"), ERROR_MESSAGE, UIManager.getIcon("OptionPane.errorIcon")); + return false; + } + if (!priceExpectPane.check()) { + FineJOptionPane.showMessageDialog(shareDialog, Toolkit.i18nText("Fine-Design_Share_Lack_Price"), + Toolkit.i18nText("Fine-Design_Basic_Error"), ERROR_MESSAGE, UIManager.getIcon("OptionPane.errorIcon")); + return false; + } + return true; + } + + /* 生成 */ + + public DefaultSharableWidget generate() { + + String uuid = UUID.randomUUID().toString(); + DefaultSharableWidget provider = new DefaultSharableWidget(uuid, nameField.getText(), help.getText(), shareCover, rec.width, rec.height); + provider.setDisplayDevice(displayDevice()); + provider.setParentClassify(classify(parentClassify.getSelectedItem())); + provider.setChildClassify(classify(childClassify.getSelectedItem())); + provider.setDesignerVersion(ProductConstants.VERSION); + provider.setVendor(loginLabel.getText()); + provider.setFileName(provider.getNameWithID()); + + if (upload) { + provider.setSummary(content.getText()); + Object selectStyle = styleComboBox.getSelectedItem(); + provider.setStyleTheme(selectStyle == null ? null : ((StyleThemeBean) selectStyle).getId()); + provider.setInvolvePlugins(pluginComboCheckBox.getText()); + provider.setPriceExpect(priceExpectPane.getPrice()); + } + + return provider; + } + + public Group getSelectGroup() { + return (Group) localGroup.getSelectedItem(); + } + + public UITextField getNameField() { + return nameField; + } + + private String classify(Object classify) { + + return classify == null ? StringUtils.EMPTY : classify.toString(); + } + + private int displayDevice() { + + List types = new ArrayList<>(8); + if (pc.isSelected()) { + types.add(DisplayDevice.PC); + } + if (mobile.isSelected()) { + types.add(DisplayDevice.MOBILE); + } + return DisplayDevice.buildDevice(types); + } + + private class LimitedDocument extends PlainDocument { + private static final long serialVersionUID = 1L; + private int maxLength = -1;// 允许的最大长度 + private int errorLength = -1; + private int loop = 5; + private String allowCharAsString = null;// 允许的字符串格式(0123456789) + + public LimitedDocument(int maxLength) { + this(-1, maxLength); + } + + public LimitedDocument(int errorLength, int maxLength) { + super(); + this.errorLength = errorLength; + this.maxLength = maxLength; + } + + @Override + public void insertString(int offset, String str, AttributeSet attrSet) throws BadLocationException { + if (str == null) { + return; + } + if (allowCharAsString != null && str.length() == 1) { + if (allowCharAsString.indexOf(str) == -1) { + java.awt.Toolkit.getDefaultToolkit().beep();// 发出一个警告声 + return;// 不是所要求的字符格式,就直接返回,不进行下面的添加 + } + } + char[] charVal = str.toCharArray(); + String strOldValue = getText(0, getLength()); + char[] tmp = strOldValue.toCharArray(); + int currentLength = tmp.length + charVal.length; + if (errorLength != -1 && currentLength > errorLength && ++loop >= 5) { + this.loop = 0; + FineJOptionPane.showMessageDialog(ShareDialogUtils.getInstance().getShareDialog(), + ShareUIUtils.formatWidthString(Toolkit.i18nText("Fine-Design_Share_Input_Errors", String.valueOf(errorLength)), 200), + Toolkit.i18nText("Fine-Design_Basic_Error"), ERROR_MESSAGE, UIManager.getIcon("OptionPane.errorIcon")); + //只提示,不报错 + } + if (maxLength != -1 && (currentLength > maxLength)) { + java.awt.Toolkit.getDefaultToolkit().beep();// 发出一个警告声 + return;// 长度大于指定的长度maxLength,也直接返回,不进行下面的添加 + } + super.insertString(offset, str, attrSet); + } + + public void setAllowChar(String str) { + allowCharAsString = str; + } + } + +} diff --git a/designer-realize/src/main/java/com/fr/design/share/ui/generate/table/EffectItemRender.java b/designer-realize/src/main/java/com/fr/design/share/ui/generate/table/EffectItemRender.java new file mode 100644 index 000000000..f31169da1 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/ui/generate/table/EffectItemRender.java @@ -0,0 +1,117 @@ +package com.fr.design.share.ui.generate.table; + +import com.fr.base.BaseUtils; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.stable.StringUtils; + +import javax.swing.BorderFactory; +import javax.swing.ImageIcon; +import javax.swing.JPanel; +import javax.swing.JTable; +import javax.swing.border.Border; +import javax.swing.table.DefaultTableCellRenderer; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Cursor; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Image; +import java.awt.Rectangle; + +public class EffectItemRender extends DefaultTableCellRenderer { + static final private Color HEADER_COLOR = new Color(221, 221, 221); + static final private Color PLACEHOLDER_COLOR = new Color(193, 193, 193); + static final private Color NO_EDITABLE_BG = new Color(240, 240, 241); + static final private Border DEFAULT_NO_FOCUS_BORDER = BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(1, 5, 1, 5), BorderFactory.createEmptyBorder(0, 4, 0, 4)); + static final private Border SELECTED_BORDER = BorderFactory.createLineBorder(new Color(160,190,240)); + + private PreviewPanel preViewPanel; + + public EffectItemRender() { + setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 10)); + setLayout(new FlowLayout()); + preViewPanel = new PreviewPanel(StringUtils.EMPTY); + } + + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + setText(StringUtils.EMPTY); + setToolTipText(null); + setBorder(DEFAULT_NO_FOCUS_BORDER); + setBackground(null); + if (column > 0) { + if (StringUtils.isNotEmpty(value.toString())) { + setValue(value); + setToolTipText(value); + if (!table.isCellEditable(row, column)) { + setForeground(PLACEHOLDER_COLOR); + setBackground(NO_EDITABLE_BG); + setToolTipText(Toolkit.i18nText("Fine-Design_Share_Not_Support_Rename")); + } else { + setForeground(Color.black); + } + + if (table.getSelectedRow() == row && table.getSelectedColumn() == column && table.isCellEditable(row, column) ) { + setBorder(SELECTED_BORDER); + setBackground(null); + table.setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR)); + } else { + if (isSelected) { + setBackground(table.getSelectionBackground()); + } + + table.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + } + } else { + setValue(Toolkit.i18nText("Fine-Design_Share_Need_Rename")); + setForeground(PLACEHOLDER_COLOR); + } + return this; + } else { + Rectangle rect = table.getCellRect(row, column, false); + preViewPanel.populate(value.toString()); + preViewPanel.getTextLabel().setPreferredSize(new Dimension(rect.width - preViewPanel.ICON_SIZE - 20, rect.height)); + return preViewPanel; + } + } + + public void setValue(Object value) { + setText((value == null) ? "" : value.toString()); + } + + private void setToolTipText(Object value) { setToolTipText((value == null) ? "" : value.toString()); } + + private class PreviewPanel extends JPanel { + public static final int ICON_SIZE = 10; + private UILabel textLabel; + + public PreviewPanel(String text) { + init(text); + } + + private void init(String text) { + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + this.setBackground(HEADER_COLOR); + textLabel = new UILabel(text); + textLabel.setToolTipText(text); + textLabel.setBorder(BorderFactory.createEmptyBorder(0,5,0,0)); + Image image = BaseUtils.readImage("com/fr/base/images/share/view.png"); + image.getScaledInstance(ICON_SIZE, ICON_SIZE, Image.SCALE_DEFAULT); + UILabel imageLabel = new UILabel(new ImageIcon(image)); + imageLabel.setBorder(BorderFactory.createEmptyBorder(0,10,0,10)); + this.add(textLabel, BorderLayout.WEST); + this.add(imageLabel, BorderLayout.EAST); + } + + public UILabel getTextLabel() { + return textLabel; + } + + public void populate(String text) { + textLabel.setText(text); + this.setToolTipText(text); + } + } +} diff --git a/designer-realize/src/main/java/com/fr/design/share/ui/generate/table/EffectTableModel.java b/designer-realize/src/main/java/com/fr/design/share/ui/generate/table/EffectTableModel.java new file mode 100644 index 000000000..042159c69 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/ui/generate/table/EffectTableModel.java @@ -0,0 +1,76 @@ +package com.fr.design.share.ui.generate.table; + +import com.fr.design.share.effect.EffectItem; +import com.fr.design.share.effect.EffectItemGroup; +import com.fr.design.share.effect.ListenerEffectItem; + +import javax.swing.table.AbstractTableModel; +import java.util.List; + +public class EffectTableModel extends AbstractTableModel { + private Object[] columnNames; + private List effectItems; + + public EffectTableModel(EffectItemGroup itemGroup, Object[] columnNames) { + if (itemGroup == null) { + this.effectItems = new EffectItemGroup().getEffectItems(); + } else { + this.effectItems = itemGroup.getEffectItems(); + } + this.columnNames = columnNames; + } + @Override + public int getRowCount() { + return this.effectItems.size(); + } + + @Override + public int getColumnCount() { + return this.columnNames.length; + } + + @Override + public String getColumnName(int columnIndex) { + if (columnNames == null) { + return null; + } + return columnNames[columnIndex].toString(); + } + + @Override + public Class getColumnClass(int columnIndex) { + return EffectTableModel.class; + } + + @Override + public boolean isCellEditable(int rowIndex, int columnIndex) { + EffectItem effectItem = effectItems.get(rowIndex); + return columnIndex == 1 && !(effectItem instanceof ListenerEffectItem); + } + + @Override + public Object getValueAt(int rowIndex, int columnIndex) { + + if (rowIndex >= getRowCount() || columnIndex >= getColumnCount()) { + return null; + } + EffectItem effectItem = effectItems.get(rowIndex); + if (columnIndex == 0) { + return effectItem.getConfigPath(); + } else if (columnIndex == 1) { + return effectItem.getName(); + } + return null; + } + + @Override + public void setValueAt(Object aValue, int rowIndex, int columnIndex) { + if (rowIndex >= effectItems.size() || columnIndex >= getColumnCount()) { + return; + } + EffectItem effectItem = effectItems.get(rowIndex); + if (columnIndex == 1) { + effectItem.setName(aValue.toString()); + } + } +} diff --git a/designer-realize/src/main/java/com/fr/design/share/ui/table/EffectItemEditor.java b/designer-realize/src/main/java/com/fr/design/share/ui/table/EffectItemEditor.java new file mode 100644 index 000000000..8fc0464e2 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/ui/table/EffectItemEditor.java @@ -0,0 +1,65 @@ +package com.fr.design.share.ui.table; + +import com.fr.design.gui.itextfield.UITextField; + +import javax.swing.AbstractCellEditor; +import javax.swing.JTable; +import javax.swing.table.TableCellEditor; +import java.awt.Component; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseMotionAdapter; + +public class EffectItemEditor extends AbstractCellEditor implements TableCellEditor { + private UITextField textField; + + public EffectItemEditor(JTable table) { + textField = new UITextField(); + textField.addMouseListener(new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + table.setRowSelectionInterval(table.getEditingRow(), table.getEditingRow()); + table.setColumnSelectionInterval(table.getEditingColumn(), table.getEditingColumn()); + } + @Override + public void mouseExited(MouseEvent e) { + table.clearSelection(); + } + + }); + textField.addMouseMotionListener(new MouseMotionAdapter() { + @Override + public void mouseMoved(MouseEvent e) { + table.setRowSelectionInterval(table.getEditingRow(), table.getEditingRow()); + table.setColumnSelectionInterval(table.getEditingColumn(), table.getEditingColumn()); + } + }); + textField.addFocusListener(new FocusAdapter() { + public void focusGained(FocusEvent e) { + table.setRowSelectionInterval(table.getEditingRow(), table.getEditingRow()); + table.setColumnSelectionInterval(table.getEditingColumn(), table.getEditingColumn()); + } + @Override + public void focusLost(FocusEvent e) { + if ((table.getSelectedRow() < 0) || (table.getSelectedColumn() < 0)) { + table.getCellEditor().stopCellEditing(); + } + } + }); + } + @Override + public Object getCellEditorValue() { + return textField.getText(); + } + + private void setValue(Object value) { + textField.setText((value != null) ? value.toString() : ""); + } + + @Override + public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { + setValue(value); + return textField; + } +} diff --git a/designer-realize/src/main/java/com/fr/design/share/utils/EffectItemUtils.java b/designer-realize/src/main/java/com/fr/design/share/utils/EffectItemUtils.java new file mode 100644 index 000000000..010828cf1 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/utils/EffectItemUtils.java @@ -0,0 +1,22 @@ +package com.fr.design.share.utils; + +import com.fr.design.share.effect.EffectItemGroup; +import com.fr.form.share.utils.ShareUtils; +import com.fr.form.ui.Widget; + +import java.util.ArrayList; +import java.util.List; + +public class EffectItemUtils { + public static List getEffectItemGroupsByWidget(Widget widget) { + List widgetList = ShareUtils.getAllLeafWidget(widget); + List effectItemGroupList = new ArrayList(); + for (Widget w : widgetList) { + EffectItemGroup effectItemGroup = new EffectItemGroup(w); + if (effectItemGroup.getEffectItems().size() > 0) { + effectItemGroupList.add(effectItemGroup); + } + } + return effectItemGroupList; + } +} diff --git a/designer-realize/src/main/java/com/fr/design/share/utils/ShareDialogUtils.java b/designer-realize/src/main/java/com/fr/design/share/utils/ShareDialogUtils.java new file mode 100644 index 000000000..4b7cfb845 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/utils/ShareDialogUtils.java @@ -0,0 +1,36 @@ +package com.fr.design.share.utils; + +import java.awt.Dialog; + +public class ShareDialogUtils { + private static class InstanceHolder { + + private static ShareDialogUtils helper = new ShareDialogUtils(); + } + + public static ShareDialogUtils getInstance() { + + return InstanceHolder.helper; + } + + private Dialog shareDialog; + private Dialog ConfigDialog; + + public void setShareDialog(Dialog shareDialog) { + + this.shareDialog = shareDialog; + } + + public Dialog getShareDialog() { + + return this.shareDialog; + } + + public void setConfigDialog(Dialog configDialog) { + ConfigDialog = configDialog; + } + + public Dialog getConfigDialog() { + return ConfigDialog; + } +} diff --git a/designer-realize/src/main/java/com/fr/start/module/DesignerActivator.java b/designer-realize/src/main/java/com/fr/start/module/DesignerActivator.java index eb3f577cc..44d362896 100644 --- a/designer-realize/src/main/java/com/fr/start/module/DesignerActivator.java +++ b/designer-realize/src/main/java/com/fr/start/module/DesignerActivator.java @@ -54,12 +54,15 @@ import com.fr.design.mainframe.form.FormECDesignerProvider; import com.fr.design.mainframe.form.FormElementCaseDesigner; import com.fr.design.mainframe.form.FormReportComponentComposite; import com.fr.design.mainframe.loghandler.DesignerLogAppender; +import com.fr.design.mainframe.share.constants.ShareEntryKey; import com.fr.design.mainframe.socketio.DesignerSocketIO; import com.fr.design.module.DesignModuleFactory; import com.fr.design.os.impl.SupportOSImpl; import com.fr.design.parameter.FormParameterReader; import com.fr.design.parameter.ParameterPropertyPane; import com.fr.design.parameter.WorkBookParameterReader; +import com.fr.design.share.ui.config.ShareConfigPane; +import com.fr.design.share.ui.generate.ShareGeneratePane; import com.fr.design.update.actions.RecoverForDesigner; import com.fr.design.update.push.DesignerPushUpdateManager; import com.fr.design.widget.ui.btn.FormSubmitButtonDetailPane; @@ -382,6 +385,8 @@ public class DesignerActivator extends Activator { private static void registerData4Form() { StableFactory.registerMarkedClass(FormECDesignerProvider.XML_TAG, FormElementCaseDesigner.class); StableFactory.registerMarkedClass(FormECCompositeProvider.XML_TAG, FormReportComponentComposite.class); + StableFactory.registerMarkedClass(ShareEntryKey.SHARE_GENERATE, ShareGeneratePane.class); + StableFactory.registerMarkedClass(ShareEntryKey.SHARE_CONFIG, ShareConfigPane.class); DesignModuleFactory.registerParameterReader(new WorkBookParameterReader()); }