kuangshuai
4 years ago
152 changed files with 15471 additions and 1283 deletions
@ -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; |
||||
} |
||||
} |
||||
} |
@ -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)); |
||||
} |
||||
} |
||||
} |
@ -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(); |
||||
} |
@ -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<String, Object> paraMap; |
||||
|
||||
private Widget widget; |
||||
|
||||
private DefaultSharableWidget info; |
||||
|
||||
public ComponentGenerateInfo(boolean autoUpload, JTemplate<?, ?> jt, Map<String, Object> 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<String, Object> getParaMap() { |
||||
|
||||
return paraMap; |
||||
} |
||||
|
||||
public Widget getWidget() { |
||||
|
||||
return widget; |
||||
} |
||||
|
||||
public DefaultSharableWidget getInfo() { |
||||
|
||||
return info; |
||||
} |
||||
} |
@ -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<LinkageChangeBean, List<String>> 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<String> 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); |
||||
} |
||||
} |
@ -0,0 +1,400 @@
|
||||
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.form.FormECCompositeProvider; |
||||
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.locale.InterProviderFactory; |
||||
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<String, Object> parameterMap = new HashMap<>(); |
||||
private String[] widgetPara = new String[]{}; |
||||
|
||||
|
||||
public CreateComponentAction(ShareUIAspect aspect) { |
||||
this.putValue(Action.SMALL_ICON, null); |
||||
this.setName(Toolkit.i18nText("Fine-Plugin_Component_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<Widget, XCreator, Rectangle> sharedTriple = ComponentTransformerFactory.getInstance().transform(selection); |
||||
if (sharedTriple == null) { |
||||
FineJOptionPane.showMessageDialog(designerFrame, InterProviderFactory.getProvider().getLocText("Fine-Plugin_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<String, Class> compoClass = new HashMap<String, Class>(); |
||||
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, InterProviderFactory.getProvider().getLocText("Fine-Plugin_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<Parameter> tplPList = new ArrayList<Parameter>(); |
||||
//只弹出使用到参数,其他的不要
|
||||
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<Widget, XCreator, Rectangle> prepareImageArgs(Triple<Widget, XCreator, Rectangle> 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); |
||||
} |
||||
|
||||
/** |
||||
* 准备封面 |
||||
* <p> |
||||
* 操作可能会很耗时,所以加个时间限制 |
||||
*/ |
||||
private Image toCoverImage(final Form form, |
||||
final Triple<Widget, XCreator, Rectangle> triple, |
||||
final Map<String, Object> parameterMap, |
||||
Rectangle reportRec) { |
||||
|
||||
final Triple<Widget, XCreator, Rectangle> imageArgs = prepareImageArgs(triple, reportRec); |
||||
FutureTask<Image> task = new FutureTask<>(new Callable<Image>() { |
||||
@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<String, Object> 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<String> getTableDataName(FormElementCaseProvider el, CalculatorProvider ca) { |
||||
Iterator<DefaultTemplateCellElement> it = el.cellIterator(); |
||||
ArrayList<String> allECDepends = new ArrayList<String>(); |
||||
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<DefaultTemplateCellElement> it = formElementCase.cellIterator(); |
||||
ArrayList<String> allECDepends = new ArrayList<String>(); |
||||
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<String> removeRepeat = new HashSet<String>(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; |
||||
} |
||||
} |
@ -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-Plugin_Component_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<InstallBackInfo, Void>() { |
||||
@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<String> 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-Plugin_Component_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<String> 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<String> 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<String> failureInfo; |
||||
|
||||
public InstallBackInfo(boolean success, boolean needShowMessage, List<String> failureInfo) { |
||||
this.success = success; |
||||
this.needShowMessage = needShowMessage; |
||||
this.failureInfo = failureInfo; |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,9 @@
|
||||
package com.fr.design.mainframe.share.action; |
||||
|
||||
/** |
||||
* created by Harrison on 2020/04/22 |
||||
**/ |
||||
public interface ShareUIAspect { |
||||
|
||||
void afterOk(); |
||||
} |
@ -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; |
||||
} |
||||
|
||||
|
||||
} |
@ -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.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<Object> 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(); |
||||
} |
||||
} |
@ -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<String, Object> 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; |
||||
} |
||||
} |
@ -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<String> children(int device); |
||||
|
||||
/** |
||||
* 返回子类型所有 |
||||
* |
||||
* @return |
||||
*/ |
||||
List<String> types(); |
||||
} |
@ -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-Plugin_Component_Type_Basic_Element") { |
||||
@Override |
||||
public List<String> children(int device) { |
||||
|
||||
return ChartChildTypes.support(device); |
||||
} |
||||
|
||||
@Override |
||||
public List<String> types() { |
||||
List<String> list = new ArrayList<>(); |
||||
for (ChartChildTypes types : ChartChildTypes.values()) { |
||||
list.add(types.getLocText()); |
||||
} |
||||
return list; |
||||
} |
||||
}, |
||||
|
||||
REPORT("Fine-Plugin_Component_Type_Report") { |
||||
@Override |
||||
public List<String> children(int device) { |
||||
|
||||
if (DisplayDevice.supportMobile(device)) { |
||||
return ReportChildTypes.support(DisplayDevice.MOBILE.getType()); |
||||
} |
||||
return ReportChildTypes.support(DisplayDevice.PC.getType()); |
||||
} |
||||
|
||||
@Override |
||||
public List<String> types() { |
||||
List<String> list = new ArrayList<>(); |
||||
for (ReportChildTypes types : ReportChildTypes.values()) { |
||||
list.add(types.getLocText()); |
||||
} |
||||
return list; |
||||
} |
||||
}; |
||||
|
||||
/** |
||||
* 所有类型 |
||||
* |
||||
* @return |
||||
*/ |
||||
public static List<String> allTypes() { |
||||
List<String> allTypes = new ArrayList<>(); |
||||
Set<String> 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<String> allTypesByDevice(int device) { |
||||
List<String> allTypes = new ArrayList<>(); |
||||
for (ComponentTypes types : values()) { |
||||
allTypes.addAll(types.children(device)); |
||||
} |
||||
return allTypes; |
||||
} |
||||
|
||||
private enum ReportChildTypes { |
||||
|
||||
INDICATOR_CARD("Fine-Plugin_Component_Type_Indicator_Card"), |
||||
|
||||
TITLE("Fine-Plugin_Component_Type_Title"), |
||||
|
||||
DIMENSION_CHANGE("Fine-Plugin_Component_Type_Dimension_Change"), |
||||
|
||||
FILL("Fine-Plugin_Component_Type_Fill", DisplayDevice.MOBILE), |
||||
|
||||
Directory_Navigation("Fine-Plugin_Component_Type_Mobile_Directory_Navigation", DisplayDevice.MOBILE), |
||||
|
||||
|
||||
SPECIAL_CARD("Fine-Plugin_Component_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<String> support(int device) { |
||||
|
||||
List<String> 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("File-Plugin_Component_Type_Chart_Column"), |
||||
|
||||
PIE_CHART("Fine-Plugin_Component_Type_Chart_Pie"), |
||||
|
||||
FOLD_LINE_CHART("Fine-Plugin_Component_Type_Chart_Fold_Line"), |
||||
|
||||
COMBINE_CHART("Fine-Plugin_Component_Type_Chart_Combine"), |
||||
|
||||
METER_CHART("Fine-Plugin_Component_Type_Chart_Meter"), |
||||
|
||||
MAP_CHART("Fine-Plugin_Component_Type_Chart_Map"), |
||||
|
||||
OTHERS("Fine-Plugin_Component_Type_Chart_Other"), |
||||
|
||||
DETAIL_LIST("Fine-Plugin_Component_Type_Detail_List"), |
||||
|
||||
BASIC_WIDGET("Fine-Plugin_Component_Type_Basic_Widget"); |
||||
|
||||
private String locale; |
||||
|
||||
ChartChildTypes(String locale) { |
||||
this.locale = locale; |
||||
} |
||||
|
||||
public static List<String> support(int device) { |
||||
|
||||
List<String> 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(); |
||||
} |
||||
} |
@ -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<DisplayDevice> 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; |
||||
} |
||||
|
||||
} |
@ -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"; |
||||
} |
@ -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-Plugin_Component_Style_Theme_Simple", "1"), |
||||
BUSINESS_STABLE("Fine-Plugin_Component_Style_Theme_Business", "2"), |
||||
LIVE_GORGEOUS("Fine-Plugin_Component_Style_Theme_Live", "3"), |
||||
COOL_TECHNOLOGY("Fine-Plugin_Component_Style_Theme_Cool", "4"), |
||||
OTHER_THEME("Fine-Plugin_Component_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<StyleThemeBean> types() { |
||||
List<StyleThemeBean> list = new ArrayList<>(); |
||||
for (StyleTheme type : StyleTheme.values()) { |
||||
list.add(new StyleThemeBean(type.getId(), type.getLocText())); |
||||
} |
||||
return list; |
||||
} |
||||
|
||||
/** |
||||
* 获取样式风格属性list |
||||
* |
||||
* @return List |
||||
*/ |
||||
public static List<StyleThemeBean> getStyleThemeTypeInfo() { |
||||
List<WidgetFilterTypeInfo> 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<StyleThemeBean> resultList = new ArrayList<>(); |
||||
List<WidgetFilterInfo> filterInfoList = styleThemeFilterInfo.getFilterItems(); |
||||
Iterator<WidgetFilterInfo> 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; |
||||
} |
||||
|
||||
|
||||
} |
@ -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-Plugin_Lack_Val")); |
||||
} |
||||
} |
@ -0,0 +1,9 @@
|
||||
package com.fr.design.mainframe.share.generate; |
||||
|
||||
/** |
||||
* created by Harrison on 2020/04/23 |
||||
**/ |
||||
public abstract class AbstractComponentTask<T> implements ComponentTask<T> { |
||||
|
||||
|
||||
} |
@ -0,0 +1,14 @@
|
||||
package com.fr.design.mainframe.share.generate; |
||||
|
||||
/** |
||||
* created by Harrison on 2020/04/13 |
||||
**/ |
||||
public interface ComponentBanner { |
||||
|
||||
/** |
||||
* 加载文字 |
||||
* |
||||
* @return 加载 |
||||
*/ |
||||
String getLoadingText(); |
||||
} |
@ -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<String, Object> paraMap, Widget widget, DefaultSharableWidget info) throws Exception; |
||||
} |
@ -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(); |
||||
|
||||
} |
@ -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<Boolean> 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); |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,13 @@
|
||||
package com.fr.design.mainframe.share.generate; |
||||
|
||||
/** |
||||
* created by Harrison on 2020/04/23 |
||||
**/ |
||||
public interface ComponentTask<T> { |
||||
|
||||
T execute() throws Exception; |
||||
|
||||
double indicator(); |
||||
|
||||
String getLoadingText(); |
||||
} |
@ -0,0 +1,26 @@
|
||||
package com.fr.design.mainframe.share.generate; |
||||
|
||||
/** |
||||
* created by Harrison on 2020/04/23 |
||||
**/ |
||||
public abstract class ComponentTaskAdaptor<T> extends AbstractComponentTask<T> { |
||||
|
||||
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; |
||||
} |
||||
} |
@ -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; |
||||
} |
||||
|
||||
|
||||
} |
@ -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 |
||||
* <p> |
||||
* 则平均速度为 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> T execute(final ComponentTask<T> componentTask) throws InterruptedException, ExecutionException { |
||||
|
||||
final CyclicBarrier barrier = new CyclicBarrier(2); |
||||
Thread UIThread = new Thread(new FutureTask<Void>(new Callable<Void>() { |
||||
@Override |
||||
public Void call() throws Exception { |
||||
SwingWorker<Void, Boolean> worker = new SwingWorker<Void, Boolean>() { |
||||
@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<T> task = new FutureTask<>(new Callable<T>() { |
||||
@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; |
||||
} |
||||
|
||||
} |
@ -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<ComponentReuBean> createTest = new ComponentTaskAdaptor<ComponentReuBean>(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<Void> completeTask = new ComponentTaskAdaptor<Void>(1.0, complete.getLoadingText()) { |
||||
@Override |
||||
public Void execute() throws Exception { |
||||
complete.execute(); |
||||
return null; |
||||
} |
||||
}; |
||||
Void result = execute(completeTask); |
||||
return true; |
||||
} |
||||
|
||||
} |
@ -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<ComponentReuBean> createTask = new ComponentTaskAdaptor<ComponentReuBean>(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<Object> desensitizeTask = new ComponentTaskAdaptor<Object>(0.60, desensitize.getLoadingText()) { |
||||
@Override |
||||
public Object execute() throws Exception { |
||||
desensitize.execute(); |
||||
return null; |
||||
} |
||||
}; |
||||
execute(desensitizeTask); |
||||
|
||||
//加密
|
||||
ComponentTaskAdaptor<ComponentReuBean> encryptTask = new ComponentTaskAdaptor<ComponentReuBean>(0.85, encrypt.getLoadingText()) { |
||||
@Override |
||||
public ComponentReuBean execute() throws Exception { |
||||
return encrypt.execute(plainBean); |
||||
} |
||||
}; |
||||
final ComponentReuBean encryptBean = execute(encryptTask); |
||||
|
||||
//上传
|
||||
ComponentTaskAdaptor<Boolean> uploadTask = new ComponentTaskAdaptor<Boolean>(1.0, uploader.getLoadingText()) { |
||||
@Override |
||||
public Boolean execute() throws Exception { |
||||
return uploader.upload(encryptBean.getPath()); |
||||
} |
||||
}; |
||||
Boolean success = execute(uploadTask); |
||||
|
||||
//完成
|
||||
final ComponentTaskAdaptor<Boolean> completeTask = new ComponentTaskAdaptor<Boolean>(1.0, complete.getLoadingText()) { |
||||
@Override |
||||
public Boolean execute() throws Exception { |
||||
return complete.execute(); |
||||
} |
||||
}; |
||||
return success && execute(completeTask); |
||||
} |
||||
|
||||
} |
@ -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.EmbeddedConverter; |
||||
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<String, Object> 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-Plugin_Component_Generate_Ing"); |
||||
} |
||||
|
||||
/** |
||||
* 内置数据集处理 |
||||
* |
||||
* @return 返回 |
||||
*/ |
||||
protected Form embeddedForm(JTemplate<?, ?> jt, Map<String, Object> paraMap) throws Exception { |
||||
|
||||
jt.stopEditing(); |
||||
|
||||
Form tpl = null; |
||||
try { |
||||
tpl = (Form) jt.getTarget().clone(); |
||||
} catch (CloneNotSupportedException e) { |
||||
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||
} |
||||
|
||||
// //内置数据集
|
||||
EmbeddedConverter embeddedConverter = WorkContext.getCurrent().get(EmbeddedConverter.class); |
||||
embeddedConverter.convertToEmbeddedTableData(tpl, paraMap); |
||||
|
||||
return tpl; |
||||
} |
||||
|
||||
@NotNull |
||||
protected DefaultSharableEditor createSharableEditor(Form form, Map<String, Object> 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<String, Object>) paraMap); |
||||
} |
||||
|
||||
protected String generate(Widget editor, DefaultSharableWidget info) throws Exception { |
||||
|
||||
return ShareUtils.generateModule(editor, info); |
||||
} |
||||
} |
@ -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-Plugin_Component_Desensitize"); |
||||
} |
||||
} |
@ -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-Plugin_Component_Encrypt"); |
||||
} |
||||
} |
@ -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-Plugin_Component_Generate_Success"); |
||||
} |
||||
} |
@ -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-Plugin_Component_Upload_Success"); |
||||
} |
||||
} |
@ -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; |
||||
|
||||
/** |
||||
* 组件上传 |
||||
* <p> |
||||
* 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-Plugin_Component_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) |
||||
// 相当于<input type="file" name="file"/>
|
||||
.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<BasicNameValuePair> 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); |
||||
} |
||||
|
||||
} |
@ -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
|
||||
} |
||||
} |
@ -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-Plugin_Component_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-Plugin_Component_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); |
||||
} |
||||
} |
@ -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-Plugin_Component_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-Plugin_Component_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; |
||||
} |
||||
|
||||
} |
@ -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; |
||||
|
||||
/** |
||||
* 组件选择器 |
||||
* <p> |
||||
* created by Harrison on 2020/06/11 |
||||
**/ |
||||
public interface ComponentTransformer { |
||||
|
||||
/** |
||||
* 获取选择到组件 |
||||
* |
||||
* @return 组件相关信息 |
||||
*/ |
||||
Triple<Widget, XCreator, Rectangle> transform(FormSelection selection); |
||||
|
||||
} |
||||
|
@ -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<Widget, XCreator, Rectangle> 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<Widget, XCreator, Rectangle> transform(FormSelection selection) { |
||||
|
||||
if (selection == null) { |
||||
return null; |
||||
} |
||||
TransformerKey transformerKey = new TransformerKey(selection); |
||||
if (AssistUtils.equals(lastKey, transformerKey)) { |
||||
return lastCache; |
||||
} |
||||
Triple<Widget, XCreator, Rectangle> triple = transformer.transform(selection); |
||||
//缓存一下。
|
||||
cache(transformerKey, triple); |
||||
return triple; |
||||
} |
||||
|
||||
private void cache(TransformerKey transformerKey, Triple<Widget, XCreator, Rectangle> triple) { |
||||
|
||||
this.lastKey = transformerKey; |
||||
this.lastCache = triple; |
||||
} |
||||
} |
@ -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<Widget, XCreator, Rectangle> 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<Integer, Widget> widgetMap = new TreeMap<>( |
||||
new Comparator<Integer>() { |
||||
@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("FR-Plugin_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); |
||||
|
||||
} |
||||
} |
@ -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); |
||||
} |
||||
} |
||||
} |
@ -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<OnlineShareWidget> { |
||||
COMPOSITE { |
||||
@Override |
||||
public void sort(OnlineShareWidget[] widgetProviders) { |
||||
Map<String, SortParameter> parameterMap = ShareUtils.getCompositeSortPara(); |
||||
Arrays.sort(widgetProviders, new Comparator<OnlineShareWidget>() { |
||||
@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<String, SortParameter> 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<String, SortParameter> parameterMap) { |
||||
SortParameter sortParameter = parameterMap.get(parameter); |
||||
if (sortParameter == null) { |
||||
return 0.0D; |
||||
} |
||||
return sortParameter.getValue(); |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public String getDisplayName() { |
||||
return Toolkit.i18nText("Fine-Plugin_Component_Composite"); |
||||
} |
||||
}, |
||||
|
||||
|
||||
SALES { |
||||
@Override |
||||
public void sort(OnlineShareWidget[] widgetProviders) { |
||||
Arrays.sort(widgetProviders, new Comparator<OnlineShareWidget>() { |
||||
@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-Plugin_Component_Sale"); |
||||
} |
||||
}, |
||||
|
||||
NEW_PRODUCT { |
||||
@Override |
||||
public void sort(OnlineShareWidget[] widgetProviders) { |
||||
Arrays.sort(widgetProviders, new Comparator<OnlineShareWidget>() { |
||||
@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-Plugin_Component_New_Product"); |
||||
} |
||||
} |
||||
//现在不用,以后可能会用,先注释掉
|
||||
/*, |
||||
PRICE { |
||||
@Override |
||||
public void sort(OnlineShareWidget[] widgetProviders) { |
||||
Arrays.sort(widgetProviders, new Comparator<OnlineShareWidget>() { |
||||
@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-Plugin_Component_Price"); |
||||
} |
||||
};*/ |
||||
|
||||
} |
@ -0,0 +1,12 @@
|
||||
package com.fr.design.mainframe.share.sort; |
||||
|
||||
/** |
||||
* @Author: Yuan.Wang |
||||
* @Date: 2020/11/19 |
||||
*/ |
||||
public interface SortType<T> { |
||||
|
||||
void sort(T[] widgetProviders); |
||||
|
||||
String getDisplayName(); |
||||
} |
@ -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<SharableWidgetProvider> { |
||||
INSTALL_TIME { |
||||
@Override |
||||
public void sort(SharableWidgetProvider[] widgetProviders) { |
||||
Arrays.sort(widgetProviders, new Comparator<SharableWidgetProvider>() { |
||||
@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-Plugin_Component_Install_Time"); |
||||
} |
||||
}, |
||||
COMPONENT_NAME { |
||||
@Override |
||||
public void sort(SharableWidgetProvider[] widgetProviders) { |
||||
Arrays.sort(widgetProviders, new Comparator<SharableWidgetProvider>() { |
||||
@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-Plugin_Component_Sort_Name"); |
||||
} |
||||
} |
||||
} |
@ -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; |
||||
} |
||||
} |
@ -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<Object> 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; |
||||
} |
||||
} |
@ -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-Plugin_Component_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-Plugin_Component_Package_Downloading")), |
||||
INSTALLING(Toolkit.i18nText("Fine-Plugin_Component_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); |
||||
|
||||
} |
||||
} |
||||
|
||||
|
@ -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-Plugin_Component_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-Plugin_Component_Dialog_Message"); |
||||
} |
||||
|
||||
} |
@ -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<ChangeListener> changeListenerList = new ArrayList<>(); |
||||
private List<FocusListener> focusListeners = new ArrayList<>(); |
||||
private List<MouseListener> deleteIconMouseListener = new ArrayList<>(); |
||||
private List<DocumentListener> 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); |
||||
} |
||||
|
||||
|
||||
} |
@ -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))); |
||||
} |
||||
} |
||||
}; |
||||
} |
@ -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); |
||||
} |
||||
} |
||||
} |
@ -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<Double> 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<ImitationState> state = new AtomicReference<>(ImitationState.NEW); |
||||
|
||||
private final int num; |
||||
private final double initSpeed; |
||||
private int currentProgressRate = 0; |
||||
|
||||
public ImitationProgress(com.fr.design.extra.Process<Double> 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 |
||||
} |
||||
} |
@ -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); |
||||
} |
||||
} |
@ -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-Plugin_Component_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); |
||||
} |
||||
|
||||
} |
@ -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) { |
||||
|
||||
} |
||||
} |
@ -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-Plugin_Component_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); |
||||
} |
||||
} |
@ -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); |
||||
} |
||||
} |
@ -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> 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); |
||||
} |
||||
|
||||
} |
@ -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); |
||||
}} |
@ -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(); |
||||
} |
||||
|
||||
} |
@ -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)); |
||||
} |
||||
} |
@ -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<Void> lock; |
||||
|
||||
public void lock(int key, String loadingText) { |
||||
|
||||
this.limitKey = key; |
||||
this.limitText = loadingText; |
||||
this.lock = new FutureTask<>(new Callable<Void>() { |
||||
@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; |
||||
} |
||||
|
||||
|
||||
} |
||||
|
||||
} |
@ -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()); |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
|
||||
} |
@ -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<T extends JComponent> 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; |
||||
}; |
||||
|
||||
} |
@ -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()); |
||||
} |
||||
} |
||||
} |
@ -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<OnlineShareWidget> 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(); |
||||
} |
||||
|
||||
} |
@ -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; |
||||
} |
||||
} |
||||
} |
@ -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.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<DefaultSharableWidget> { |
||||
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-Plugin_Component_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-Plugin_Component_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-Plugin_Component_Group_Move_Fail_Message")); |
||||
} |
||||
} |
||||
|
||||
}; |
||||
} |
||||
} |
||||
|
||||
private class RemoveAction extends UpdateAction { |
||||
public RemoveAction() { |
||||
this.putValue(Action.SMALL_ICON, null); |
||||
this.setName(Toolkit.i18nText("Fine-Plugin_Component_Remove")); |
||||
} |
||||
|
||||
@Override |
||||
public void actionPerformed(ActionEvent e) { |
||||
int rv = FineJOptionPane.showConfirmDialog(DesignerContext.getDesignerFrame(), |
||||
Toolkit.i18nText("Fine-Plugin_Component_Remove_Info"), |
||||
Toolkit.i18nText("Fine-Plugin_Component_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-Plugin_Component_Remove_Failure")); |
||||
} |
||||
LocalWidgetRepoPane.getInstance().refreshShowPanel(getGroup()); |
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
@ -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.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-Plugin_Component_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<Boolean, Void>() { |
||||
|
||||
@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-Plugin_Component_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<Double> { |
||||
|
||||
@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)); |
||||
} |
||||
} |
||||
|
||||
} |
@ -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-Plugin_Component_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); |
||||
} |
||||
|
||||
} |
||||
|
||||
|
@ -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<T> 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); |
||||
} |
||||
} |
@ -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); |
||||
} |
||||
} |
@ -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.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<SharableWidgetProvider> 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-Plugin_Component_Group_Rename")); |
||||
} |
||||
|
||||
@Override |
||||
public void actionPerformed(ActionEvent e) { |
||||
new GroupFileDialog(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Plugin_Component_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-Plugin_Component_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-Plugin_Component_Group_Remove")); |
||||
} |
||||
|
||||
@Override |
||||
public void actionPerformed(ActionEvent e) { |
||||
int rv = FineJOptionPane.showConfirmDialog( |
||||
DesignerContext.getDesignerFrame(), |
||||
Toolkit.i18nText("Fine-Plugin_Component_Group_Remove_Info"), |
||||
Toolkit.i18nText("Fine-Plugin_Component_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-Plugin_Component_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); |
||||
} |
||||
} |
@ -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-Plugin_Component_Empty_First"), SwingConstants.CENTER); |
||||
topLabel.setForeground(Color.GRAY); |
||||
UILabel bottomLabel = new UILabel(Toolkit.i18nText("Fine-Plugin_Component_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-Plugin_Component_installing")); |
||||
} |
||||
}; |
||||
|
||||
public abstract JPanel getPanel(); |
||||
} |
@ -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.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<String, GroupPane> 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<Boolean, Void>() { |
||||
@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-Plugin_Component_Local_Widget"); |
||||
} |
||||
} |
@ -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.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(); |
||||
} |
||||
} |
@ -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.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("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("Manage"), |
||||
e -> replacePanel(true) |
||||
); |
||||
} |
||||
|
||||
/** |
||||
* 添加分组面板 |
||||
*/ |
||||
private UIButton createAddGroupButton() { |
||||
return createManageButton( |
||||
Toolkit.i18nText("Group_Add"), |
||||
e -> new GroupFileDialog(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Plugin_Component_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("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("Select_Remove"), |
||||
new Color(0xeb1d1f), |
||||
e -> { |
||||
int rv = FineJOptionPane.showConfirmDialog( |
||||
DesignerContext.getDesignerFrame(), |
||||
Toolkit.i18nText("Fine-Plugin_Component_Remove_Info"), |
||||
Toolkit.i18nText("Fine-Plugin_Component_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("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-Plugin_Component_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); |
||||
} |
||||
} |
@ -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-Plugin_Component_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-Plugin_Component_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; |
||||
} |
||||
|
||||
} |
@ -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.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<String, List<String>> 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())); |
||||
} |
||||
} |
@ -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; |
||||
} |
||||
} |
@ -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.mainframe.share.collect.ComponentCollector; |
||||
import com.fr.design.menu.MenuKeySet; |
||||
import com.fr.design.utils.BrowseUtils; |
||||
import com.fr.general.CloudCenter; |
||||
import com.fr.locale.InterProviderFactory; |
||||
|
||||
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 InterProviderFactory.getProvider().getLocText("Fine-Plugin_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); |
||||
} |
||||
} |
@ -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<OnlineShareWidget> 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<OnlineShareWidget> 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<String, Integer> recordMap; |
||||
private List<MouseListener> 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<Boolean, Void>() { |
||||
@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); |
||||
} |
||||
} |
||||
} |
@ -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.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<Group, Void> 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-Plugin_Component_Download_Cancel_Confirm"), Toolkit.i18nText("Fine-Plugin_Component_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<Double> downloadProcess = aDouble -> { |
||||
OnlineDownloadPackagePane.this.process = 0.8 * aDouble; |
||||
downloadProgressPane.updateProgress(process); |
||||
}; |
||||
final com.fr.design.extra.Process<Double> 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<Group, Void> 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<Group, Void> { |
||||
final com.fr.design.extra.Process<Double> installProcess; |
||||
final OnlineShareWidget onlineShareWidget; |
||||
|
||||
public DownLoadSwingWorker(com.fr.design.extra.Process<Double> installProcess, OnlineShareWidget onlineShareWidget) { |
||||
this.installProcess = installProcess; |
||||
this.onlineShareWidget = onlineShareWidget; |
||||
} |
||||
|
||||
@Override |
||||
@Nullable |
||||
protected Group doInBackground() { |
||||
final String filePath; |
||||
List<String> 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()); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
@ -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<Boolean,Void> swingWorker; |
||||
|
||||
private final List<ResourceLoader> 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<Boolean, Void>() { |
||||
@Override |
||||
protected Boolean doInBackground() { |
||||
for (ResourceLoader loader : loaderList) { |
||||
loader.load(); |
||||
} |
||||
return true; |
||||
} |
||||
}; |
||||
swingWorker.execute(); |
||||
|
||||
} |
||||
|
||||
|
||||
} |
@ -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-Plugin_Component_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<Boolean, Void>() { |
||||
@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<OnlineShareWidget> sharableWidgets = new ArrayList<>(); |
||||
List<OnlineShareWidget> 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-Plugin_Component_Internet_Connect_Failed")); |
||||
uiLabel.setForeground(Color.decode("#8F8F92")); |
||||
UILabel reloadLabel = tipLabel(Toolkit.i18nText("Fine-Plugin_Component_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-Plugin_Component_Internet_Connect_Failed_Tip1")); |
||||
tipLabel1.setForeground(Color.decode("#8F8F92")); |
||||
UILabel tipLabel2 = tipLabel(Toolkit.i18nText("Fine-Plugin_Component_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; |
||||
} |
||||
|
||||
} |
@ -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<OnlineShareWidget> 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<OnlineShareWidget> dataLoad, final int widgetsPerNum) { |
||||
this.widgetsPerNum = widgetsPerNum; |
||||
init(); |
||||
//异步获取组件信息
|
||||
new SwingWorker<PaneStatue, Void>() { |
||||
@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<PaneStatue, Void>() { |
||||
@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<OnlineShareWidget> 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<OnlineShareWidget> 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(); |
||||
} |
||||
} |
@ -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); |
||||
} |
||||
} |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue