Browse Source
# Conflicts: # designer-form/src/main/java/com/fr/design/designer/creator/XWAbsoluteLayout.java # designer-form/src/main/java/com/fr/design/mainframe/CoverReportPane.javaresearch/11.0
kuangshuai
4 years ago
165 changed files with 16254 additions and 1464 deletions
@ -0,0 +1,41 @@
|
||||
package com.fr.design.gui.controlpane; |
||||
|
||||
import com.fr.form.event.Listener; |
||||
import com.fr.general.NameObject; |
||||
import org.easymock.EasyMock; |
||||
import org.junit.Assert; |
||||
import org.junit.Test; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* Created by kerry on 5/17/21 |
||||
*/ |
||||
public class ListControlPaneHelperTest { |
||||
|
||||
@Test |
||||
public void testProcessCatalog() { |
||||
ListControlPaneHelper helper = ListControlPaneHelper.newInstance(EasyMock.mock(ListControlPaneProvider.class)); |
||||
List<NameObject> nameObjectList = new ArrayList<>(); |
||||
Listener listener1 = new Listener(); |
||||
listener1.setEventName("click"); |
||||
Listener listener2 = new Listener(); |
||||
listener2.setEventName("afterInit"); |
||||
Listener listener3 = new Listener(); |
||||
listener3.setEventName("click"); |
||||
Listener listener4 = new Listener(); |
||||
listener4.setEventName("afterInit"); |
||||
listener4.setName("test"); |
||||
nameObjectList.add(new NameObject("click", listener1)); |
||||
nameObjectList.add(new NameObject("afterInit", listener2)); |
||||
nameObjectList.add(new NameObject("click", listener3)); |
||||
nameObjectList.add(new NameObject("afterInit", listener4)); |
||||
Map<String, List<NameObject>> map = helper.processCatalog(nameObjectList); |
||||
Assert.assertEquals(2, map.size()); |
||||
Assert.assertEquals(2, map.get("afterInit").size()); |
||||
Assert.assertEquals(2, map.get("click").size()); |
||||
|
||||
} |
||||
} |
@ -0,0 +1,533 @@
|
||||
package com.fr.design.gui.controlpane; |
||||
|
||||
|
||||
import com.fr.design.beans.BasicBeanPane; |
||||
import com.fr.design.constants.UIConstants; |
||||
import com.fr.design.designer.creator.XCreator; |
||||
import com.fr.design.designer.properties.EventPropertyTable; |
||||
import com.fr.design.gui.icontainer.UIScrollPane; |
||||
import com.fr.design.gui.ilable.UILabel; |
||||
import com.fr.design.gui.ilist.JNameEdList; |
||||
import com.fr.design.gui.ilist.ListModelElement; |
||||
import com.fr.design.gui.ilist.ModNameActionListener; |
||||
import com.fr.design.gui.ilist.UINameEdList; |
||||
import com.fr.design.i18n.Toolkit; |
||||
import com.fr.design.layout.FRGUIPaneFactory; |
||||
import com.fr.design.mainframe.FormDesigner; |
||||
import com.fr.design.widget.EventCreator; |
||||
import com.fr.form.event.Listener; |
||||
import com.fr.form.ui.Widget; |
||||
import com.fr.general.NameObject; |
||||
import com.fr.report.web.util.ReportEngineEventMapping; |
||||
import com.fr.stable.ArrayUtils; |
||||
import com.fr.stable.Nameable; |
||||
import javax.swing.BorderFactory; |
||||
import javax.swing.DefaultListModel; |
||||
import javax.swing.JPanel; |
||||
import javax.swing.ListSelectionModel; |
||||
import javax.swing.event.ListDataEvent; |
||||
import javax.swing.event.ListDataListener; |
||||
import javax.swing.event.ListSelectionEvent; |
||||
import javax.swing.event.ListSelectionListener; |
||||
import java.awt.BorderLayout; |
||||
import java.awt.Color; |
||||
import java.awt.Dimension; |
||||
import java.awt.FlowLayout; |
||||
import java.awt.event.MouseAdapter; |
||||
import java.awt.event.MouseEvent; |
||||
import java.lang.reflect.Constructor; |
||||
import java.lang.reflect.InvocationTargetException; |
||||
import java.util.ArrayList; |
||||
import java.util.HashMap; |
||||
import java.util.Iterator; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* Created by kerry on 5/17/21 |
||||
*/ |
||||
public class EventPropertyPane extends UIControlPane implements ListControlPaneProvider { |
||||
private XCreator creator; |
||||
private boolean isPopulating = false; |
||||
private UINameEdList selectNameEdList; |
||||
|
||||
private Map<String, EventListWrapperPane> nameEdListMap = new HashMap<>(); |
||||
|
||||
private CommonShortCutHandlers commonHandlers; |
||||
|
||||
private ListControlPaneHelper helper; |
||||
|
||||
private JPanel contentPane; |
||||
|
||||
private FormDesigner designer; |
||||
|
||||
|
||||
private ListControlPaneHelper getHelper() { |
||||
if (helper == null) { |
||||
helper = ListControlPaneHelper.newInstance(this); |
||||
} |
||||
return helper; |
||||
} |
||||
|
||||
private CommonShortCutHandlers getCommonHandlers() { |
||||
if (commonHandlers == null) { |
||||
commonHandlers = CommonShortCutHandlers.newInstance(this); |
||||
} |
||||
return commonHandlers; |
||||
} |
||||
|
||||
|
||||
public EventPropertyPane(FormDesigner designer) { |
||||
super(); |
||||
this.designer = designer; |
||||
} |
||||
|
||||
|
||||
@Override |
||||
protected void initLeftPane(JPanel leftPane) { |
||||
leftPane.add(new UIScrollPane(contentPane = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, FlowLayout.LEADING, 0, 0)), BorderLayout.CENTER); |
||||
} |
||||
|
||||
/** |
||||
* 刷新 |
||||
*/ |
||||
public void refresh() { |
||||
int selectionSize = designer.getSelectionModel().getSelection().size(); |
||||
if (selectionSize == 0 || selectionSize == 1) { |
||||
this.creator = selectionSize == 0 ? designer.getRootComponent() : designer.getSelectionModel() |
||||
.getSelection().getSelectedCreator(); |
||||
} else { |
||||
this.creator = null; |
||||
contentPane.removeAll(); |
||||
checkButtonEnabled(); |
||||
return; |
||||
} |
||||
Widget widget = creator.toData(); |
||||
|
||||
refreshContentPane(widget.supportedEvents()); |
||||
refreshNameableCreator(EventCreator.createEventCreator(widget.supportedEvents(), EventPropertyTable.WidgetEventListenerUpdatePane.class)); |
||||
populateNameObjects(); |
||||
} |
||||
|
||||
|
||||
private void refreshContentPane(String[] supportedEvents) { |
||||
for (String event : supportedEvents) { |
||||
if (nameEdListMap.containsKey(event)) { |
||||
continue; |
||||
} |
||||
UINameEdList list = createJNameList(event); |
||||
EventListWrapperPane wrapperPane = new EventListWrapperPane(switchLang(event), list); |
||||
if (this.selectNameEdList == null) { |
||||
this.selectNameEdList = wrapperPane.getNameEdList(); |
||||
} |
||||
contentPane.add(wrapperPane); |
||||
nameEdListMap.put(event, wrapperPane); |
||||
} |
||||
} |
||||
|
||||
public void populateNameObjects() { |
||||
Widget widget = creator.toData(); |
||||
|
||||
ArrayList<NameObject> nameObjectList = new ArrayList<>(); |
||||
for (int i = 0, size = widget.getListenerSize(); i < size; i++) { |
||||
Listener listener = widget.getListener(i); |
||||
if (!listener.isDefault()) { |
||||
nameObjectList.add(i, new NameObject(switchLang(listener.getEventName()) + (i + 1), listener)); |
||||
} |
||||
} |
||||
populate(getHelper().processCatalog(nameObjectList)); |
||||
checkButtonEnabled(); |
||||
this.repaint(); |
||||
} |
||||
|
||||
public void populate(Map<String, List<NameObject>> map) { |
||||
isPopulating = true; // 加一个标识位,避免切换单元格时,触发 saveSettings
|
||||
Iterator<Map.Entry<String, List<NameObject>>> iterator = map.entrySet().iterator(); |
||||
while (iterator.hasNext()) { |
||||
Map.Entry<String, List<NameObject>> entry = iterator.next(); |
||||
List<NameObject> valueList = entry.getValue(); |
||||
EventListWrapperPane eventListWrapperPane = nameEdListMap.get(entry.getKey()); |
||||
populateChildNameList(eventListWrapperPane.getNameEdList(), valueList.toArray(new NameObject[valueList.size()])); |
||||
} |
||||
this.checkButtonEnabled(); |
||||
refreshEventListWrapperPane(); |
||||
isPopulating = false; |
||||
} |
||||
|
||||
private void refreshEventListWrapperPane() { |
||||
Iterator<Map.Entry<String, EventListWrapperPane>> iterator = nameEdListMap.entrySet().iterator(); |
||||
while (iterator.hasNext()) { |
||||
Map.Entry<String, EventListWrapperPane> entry = iterator.next(); |
||||
EventListWrapperPane eventListWrapperPane = entry.getValue(); |
||||
UINameEdList nameEdList = eventListWrapperPane.getNameEdList(); |
||||
int listSize = nameEdList.getModel().getSize(); |
||||
if (this.selectNameEdList.getModel().getSize() == 0 && listSize > 0) { |
||||
this.selectNameEdList = nameEdList; |
||||
} |
||||
eventListWrapperPane.setVisible(listSize > 0); |
||||
} |
||||
this.selectNameEdList.setSelectedIndex(0); |
||||
this.repaint(); |
||||
} |
||||
|
||||
|
||||
private void populateChildNameList(UINameEdList nameableList, Nameable[] nameableArray) { |
||||
nameableList.getCellEditor().stopCellEditing(); |
||||
DefaultListModel listModel = (DefaultListModel) nameableList.getModel(); |
||||
listModel.removeAllElements(); |
||||
if (ArrayUtils.isEmpty(nameableArray)) { |
||||
isPopulating = false; |
||||
return; |
||||
} |
||||
|
||||
listModel.setSize(nameableArray.length); |
||||
for (int i = 0; i < nameableArray.length; i++) { |
||||
listModel.set(i, new ListModelElement(nameableArray[i])); |
||||
} |
||||
|
||||
} |
||||
|
||||
|
||||
protected UINameEdList createJNameList(String text) { |
||||
UINameEdList nameEdList = new UINameEdList(new DefaultListModel()) { |
||||
@Override |
||||
protected void doAfterLostFocus() { |
||||
((JControlUpdatePane) controlUpdatePane).update(); |
||||
} |
||||
|
||||
@Override |
||||
protected void doAfterStopEditing() { |
||||
saveSettings(); |
||||
} |
||||
}; |
||||
|
||||
nameEdList.setCellRenderer(new UINameableListCellRenderer(true, this.creators)); |
||||
nameEdList.setName(text); |
||||
nameEdList.setSelectionBackground(UIConstants.ATTRIBUTE_PRESS); |
||||
nameEdList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); |
||||
nameEdList.addMouseListener(getHelper().getListMouseListener(nameEdList, this)); |
||||
nameEdList.addMouseListener(new MouseAdapter() { |
||||
@Override |
||||
public void mouseClicked(MouseEvent e) { |
||||
selectNameEdList = nameEdList; |
||||
updateUINameListSelect(); |
||||
} |
||||
}); |
||||
nameEdList.addModNameActionListener(new ModNameActionListener() { |
||||
@Override |
||||
public void nameModed(int index, String oldName, String newName) { |
||||
saveSettings(); |
||||
} |
||||
}); |
||||
nameEdList.addListSelectionListener(new ListSelectionListener() { |
||||
public void valueChanged(ListSelectionEvent evt) { |
||||
// richie:避免多次update和populate大大降低效率
|
||||
if (!evt.getValueIsAdjusting() && !isPopulating) { |
||||
// shoc 切换的时候加检验
|
||||
if (hasInvalid(false)) { |
||||
return; |
||||
} |
||||
((JControlUpdatePane) EventPropertyPane.this.controlUpdatePane).update(); |
||||
((JControlUpdatePane) EventPropertyPane.this.controlUpdatePane).populate(); |
||||
EventPropertyPane.this.checkButtonEnabled(); |
||||
} |
||||
} |
||||
}); |
||||
nameEdList.getModel().addListDataListener(new ListDataListener() { |
||||
@Override |
||||
public void intervalAdded(ListDataEvent e) { |
||||
saveSettings(); |
||||
} |
||||
|
||||
@Override |
||||
public void intervalRemoved(ListDataEvent e) { |
||||
saveSettings(); |
||||
} |
||||
|
||||
@Override |
||||
public void contentsChanged(ListDataEvent e) { |
||||
saveSettings(); |
||||
} |
||||
}); |
||||
return nameEdList; |
||||
} |
||||
|
||||
private void updateUINameListSelect() { |
||||
Iterator<Map.Entry<String, EventListWrapperPane>> iterator = nameEdListMap.entrySet().iterator(); |
||||
while (iterator.hasNext()) { |
||||
Map.Entry<String, EventListWrapperPane> entry = iterator.next(); |
||||
UINameEdList nameEdList = entry.getValue().getNameEdList(); |
||||
if (nameEdList != selectNameEdList) { |
||||
nameEdList.clearSelection(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void checkButtonEnabled() { |
||||
getHelper().checkButtonEnabled(); |
||||
} |
||||
|
||||
|
||||
|
||||
private String switchLang(String eventName) { |
||||
// 在 properties 文件中找到相应的 key 值
|
||||
String localeKey = ReportEngineEventMapping.getLocaleName(eventName); |
||||
return com.fr.design.i18n.Toolkit.i18nText(localeKey); |
||||
} |
||||
|
||||
/** |
||||
* 更新控件事件 |
||||
* |
||||
* @param creator 控件 |
||||
*/ |
||||
public void updateWidgetListener(XCreator creator) { |
||||
(creator.toData()).clearListeners(); |
||||
Nameable[] res = this.update(); |
||||
for (int i = 0; i < res.length; i++) { |
||||
NameObject nameObject = (NameObject) res[i]; |
||||
(creator.toData()).addListener((Listener) nameObject.getObject()); |
||||
} |
||||
|
||||
designer.fireTargetModified(); |
||||
checkButtonEnabled(); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* 生成不重复的名字 |
||||
* |
||||
* @param prefix 名字前缀 |
||||
* @return 名字 |
||||
*/ |
||||
@Override |
||||
public String createUnrepeatedName(String prefix) { |
||||
return getCommonHandlers().createUnrepeatedName(prefix); |
||||
} |
||||
|
||||
private void updateSelectedNameList(NameableCreator creator) { |
||||
String eventName = ((EventCreator) creator).getEventName(); |
||||
EventListWrapperPane wrapperPane = nameEdListMap.get(eventName); |
||||
wrapperPane.setVisible(true); |
||||
setSelectNameEdList(wrapperPane.getNameEdList()); |
||||
} |
||||
|
||||
private void setSelectNameEdList(UINameEdList nameEdList) { |
||||
if (this.selectNameEdList != null) { |
||||
this.selectNameEdList.clearSelection(); |
||||
} |
||||
this.selectNameEdList = nameEdList; |
||||
} |
||||
|
||||
@Override |
||||
public void onAddItem(NameableCreator creator) { |
||||
updateSelectedNameList(creator); |
||||
getCommonHandlers().onAddItem(creator); |
||||
} |
||||
|
||||
@Override |
||||
public void onRemoveItem() { |
||||
getCommonHandlers().onRemoveItem(); |
||||
refreshEventListWrapperPane(); |
||||
} |
||||
|
||||
@Override |
||||
public void onCopyItem() { |
||||
getCommonHandlers().onCopyItem(); |
||||
} |
||||
|
||||
@Override |
||||
public void onMoveUpItem() { |
||||
getCommonHandlers().onMoveUpItem(); |
||||
} |
||||
|
||||
@Override |
||||
public void onMoveDownItem() { |
||||
getCommonHandlers().onMoveDownItem(); |
||||
} |
||||
|
||||
@Override |
||||
public void onSortItem(boolean isAtoZ) { |
||||
Iterator<Map.Entry<String, EventListWrapperPane>> iterator = nameEdListMap.entrySet().iterator(); |
||||
while (iterator.hasNext()) { |
||||
Map.Entry<String, EventListWrapperPane> entry = iterator.next(); |
||||
UINameEdList nameEdList = entry.getValue().getNameEdList(); |
||||
getCommonHandlers().onSortItem(isAtoZ, nameEdList); |
||||
} |
||||
|
||||
} |
||||
|
||||
@Override |
||||
public boolean isItemSelected() { |
||||
return getModel().getSize() > 0 && getSelectedIndex() != -1; |
||||
} |
||||
|
||||
|
||||
@Override |
||||
protected JPanel createControlUpdatePane() { |
||||
return JControlUpdatePane.newInstance(this); |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public Nameable[] update() { |
||||
java.util.List<Nameable> res = new java.util.ArrayList<Nameable>(); |
||||
getControlUpdatePane().update(); |
||||
Iterator<Map.Entry<String, EventListWrapperPane>> iterator = nameEdListMap.entrySet().iterator(); |
||||
while (iterator.hasNext()) { |
||||
Map.Entry<String, EventListWrapperPane> entry = iterator.next(); |
||||
UINameEdList nameEdList = entry.getValue().getNameEdList(); |
||||
DefaultListModel listModel = (DefaultListModel) nameEdList.getModel(); |
||||
for (int i = 0, len = listModel.getSize(); i < len; i++) { |
||||
res.add(((ListModelElement) listModel.getElementAt(i)).wrapper); |
||||
} |
||||
} |
||||
return res.toArray(new Nameable[0]); |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public NameableCreator[] createNameableCreators() { |
||||
return new NameableCreator[]{ |
||||
new EventCreator(Widget.EVENT_STATECHANGE, EventPropertyTable.WidgetEventListenerUpdatePane.class) |
||||
}; |
||||
} |
||||
|
||||
@Override |
||||
public void saveSettings() { |
||||
if (isPopulating) { |
||||
return; |
||||
} |
||||
updateWidgetListener(creator); |
||||
} |
||||
|
||||
@Override |
||||
protected String title4PopupWindow() { |
||||
return "Event"; |
||||
} |
||||
|
||||
@Override |
||||
public String getAddItemText() { |
||||
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Add_Event"); |
||||
} |
||||
|
||||
public BasicBeanPane createPaneByCreators(NameableCreator creator) { |
||||
try { |
||||
return creator.getUpdatePane().newInstance(); |
||||
} catch (InstantiationException e) { |
||||
throw new RuntimeException(e); |
||||
} catch (IllegalAccessException e) { |
||||
throw new RuntimeException(e); |
||||
} |
||||
} |
||||
|
||||
public BasicBeanPane createPaneByCreators(NameableCreator creator, String string) { |
||||
Constructor constructor = null; |
||||
try { |
||||
constructor = creator.getUpdatePane().getDeclaredConstructor(new Class[]{String.class}); |
||||
constructor.setAccessible(true); |
||||
return (BasicBeanPane) constructor.newInstance(string); |
||||
} catch (NoSuchMethodException e) { |
||||
throw new RuntimeException(e); |
||||
} catch (InstantiationException e) { |
||||
throw new RuntimeException(e); |
||||
} catch (IllegalAccessException e) { |
||||
throw new RuntimeException(e); |
||||
} catch (InvocationTargetException e) { |
||||
throw new RuntimeException(e); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public DefaultListModel getModel() { |
||||
if (this.selectNameEdList == null) { |
||||
return new DefaultListModel(); |
||||
} |
||||
return (DefaultListModel) this.selectNameEdList.getModel(); |
||||
} |
||||
|
||||
/** |
||||
* 检查是否符合规范 |
||||
* |
||||
* @throws Exception |
||||
*/ |
||||
@Override |
||||
public void checkValid() throws Exception { |
||||
((JControlUpdatePane) this.controlUpdatePane).checkValid(); |
||||
} |
||||
|
||||
@Override |
||||
public boolean hasInvalid(boolean isAdd) { |
||||
return getHelper().hasInvalid(isAdd); |
||||
} |
||||
|
||||
public void addNameable(Nameable nameable, int index) { |
||||
getHelper().addNameable(nameable, index); |
||||
popupEditDialog(); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* 设置选中项 |
||||
* |
||||
* @param index 选中项的序列号 |
||||
*/ |
||||
public void setSelectedIndex(int index) { |
||||
if (this.selectNameEdList != null) { |
||||
this.selectNameEdList.setSelectedIndex(index); |
||||
|
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public int getSelectedIndex() { |
||||
if (this.selectNameEdList == null) { |
||||
return -1; |
||||
} |
||||
return this.selectNameEdList.getSelectedIndex(); |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public ListModelElement getSelectedValue() { |
||||
if (this.selectNameEdList == null) { |
||||
return null; |
||||
} |
||||
return (ListModelElement) this.selectNameEdList.getSelectedValue(); |
||||
} |
||||
|
||||
@Override |
||||
public JControlUpdatePane getControlUpdatePane() { |
||||
return (JControlUpdatePane) controlUpdatePane; |
||||
} |
||||
|
||||
@Override |
||||
public JNameEdList getNameableList() { |
||||
return this.selectNameEdList; |
||||
} |
||||
|
||||
private void popupEditDialog() { |
||||
getHelper().popupEditDialog(null, this.selectNameEdList, this); |
||||
} |
||||
|
||||
|
||||
private class EventListWrapperPane extends JPanel { |
||||
private UINameEdList nameEdList; |
||||
|
||||
public EventListWrapperPane(String labelText, UINameEdList nameEdList) { |
||||
this.setLayout(FRGUIPaneFactory.createBorderLayout()); |
||||
UILabel label = new UILabel(labelText + Toolkit.i18nText("Fine-Design_Report_Event")); |
||||
label.setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 0)); |
||||
label.setBackground(Color.decode("#FFFFFF")); |
||||
label.setPreferredSize(new Dimension(226, 26)); |
||||
this.nameEdList = nameEdList; |
||||
this.add(label, BorderLayout.NORTH); |
||||
this.add(this.nameEdList, BorderLayout.CENTER); |
||||
} |
||||
|
||||
public UINameEdList getNameEdList() { |
||||
return this.nameEdList; |
||||
} |
||||
|
||||
} |
||||
} |
@ -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,398 @@
|
||||
package com.fr.design.mainframe.share.action; |
||||
|
||||
import com.fr.base.Parameter; |
||||
import com.fr.base.ParameterMapNameSpace; |
||||
import com.fr.base.TableData; |
||||
import com.fr.chart.chartattr.Chart; |
||||
import com.fr.chart.chartattr.ChartCollection; |
||||
import com.fr.chart.chartdata.TableDataDefinition; |
||||
import com.fr.data.impl.NameTableData; |
||||
import com.fr.data.impl.TableDataDictionary; |
||||
import com.fr.design.actions.UpdateAction; |
||||
import com.fr.design.data.DesignTableDataManager; |
||||
import com.fr.design.designer.creator.XCreator; |
||||
import com.fr.design.dialog.BasicPane; |
||||
import com.fr.design.dialog.DialogActionAdapter; |
||||
import com.fr.design.dialog.FineJOptionPane; |
||||
import com.fr.design.file.HistoryTemplateListPane; |
||||
import com.fr.design.i18n.Toolkit; |
||||
import com.fr.design.mainframe.DesignerContext; |
||||
import com.fr.design.mainframe.DesignerFrame; |
||||
import com.fr.design.mainframe.FormSelection; |
||||
import com.fr.design.mainframe.JForm; |
||||
import com.fr.design.mainframe.JTemplate; |
||||
import com.fr.design.mainframe.share.constants.ShareEntryKey; |
||||
import com.fr.design.mainframe.share.select.ComponentTransformerFactory; |
||||
import com.fr.design.parameter.ParameterInputPane; |
||||
import com.fr.form.FormElementCaseProvider; |
||||
import com.fr.form.main.Form; |
||||
import com.fr.form.main.FormIO; |
||||
import com.fr.form.main.WidgetGather; |
||||
import com.fr.form.ui.BaseChartEditor; |
||||
import com.fr.form.ui.ChartEditor; |
||||
import com.fr.form.ui.DataControl; |
||||
import com.fr.form.ui.DictionaryContainer; |
||||
import com.fr.form.ui.ElementCaseEditor; |
||||
import com.fr.form.ui.Widget; |
||||
import com.fr.general.IOUtils; |
||||
import com.fr.log.FineLoggerFactory; |
||||
import com.fr.report.cell.DefaultTemplateCellElement; |
||||
import com.fr.report.cell.cellattr.core.group.DSColumn; |
||||
import com.fr.script.Calculator; |
||||
import com.fr.stable.ArrayUtils; |
||||
import com.fr.stable.Constants; |
||||
import com.fr.stable.CoreGraphHelper; |
||||
import com.fr.stable.DependenceProvider; |
||||
import com.fr.stable.ParameterProvider; |
||||
import com.fr.stable.StringUtils; |
||||
import com.fr.stable.bridge.StableFactory; |
||||
import com.fr.stable.script.CalculatorProvider; |
||||
import com.fr.stable.script.NameSpace; |
||||
import com.fr.third.guava.base.Preconditions; |
||||
import com.fr.third.org.apache.commons.lang3.tuple.ImmutableTriple; |
||||
import com.fr.third.org.apache.commons.lang3.tuple.Triple; |
||||
|
||||
import javax.swing.Action; |
||||
import javax.swing.UIManager; |
||||
import java.awt.Color; |
||||
import java.awt.Component; |
||||
import java.awt.Graphics2D; |
||||
import java.awt.Image; |
||||
import java.awt.Rectangle; |
||||
import java.awt.event.ActionEvent; |
||||
import java.awt.image.BufferedImage; |
||||
import java.io.InputStream; |
||||
import java.util.ArrayList; |
||||
import java.util.Arrays; |
||||
import java.util.HashMap; |
||||
import java.util.HashSet; |
||||
import java.util.Iterator; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
import java.util.concurrent.Callable; |
||||
import java.util.concurrent.FutureTask; |
||||
import java.util.concurrent.TimeUnit; |
||||
|
||||
import static javax.swing.JOptionPane.ERROR_MESSAGE; |
||||
|
||||
/** |
||||
* @Author: Yuan.Wang |
||||
* @Date: 2020/11/3 |
||||
* 创建组件事件 |
||||
*/ |
||||
public class CreateComponentAction extends UpdateAction { |
||||
ShareUIAspect aspect; |
||||
/** |
||||
* 等待时间 500 ms. |
||||
*/ |
||||
private static final int WAIT_TIME = 500; |
||||
|
||||
private final HashMap<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-Design_Share_Create")); |
||||
this.aspect = aspect; |
||||
} |
||||
|
||||
@Override |
||||
public void actionPerformed(ActionEvent event) { |
||||
DesignerFrame designerFrame = DesignerContext.getDesignerFrame(); |
||||
// 停止编辑
|
||||
JTemplate<?, ?> jt = HistoryTemplateListPane.getInstance().getCurrentEditingTemplate(); |
||||
jt.stopEditing(); |
||||
Form form = null; |
||||
try { |
||||
form = (Form) jt.getTarget().clone(); |
||||
} catch (CloneNotSupportedException e1) { |
||||
FineLoggerFactory.getLogger().error(e1.getMessage(), e1); |
||||
} |
||||
FormSelection selection = ((JForm) jt).getFormDesign().getSelectionModel().getSelection(); |
||||
|
||||
// 获取选中的组件
|
||||
Triple<Widget, XCreator, Rectangle> sharedTriple = ComponentTransformerFactory.getInstance().transform(selection); |
||||
if (sharedTriple == null) { |
||||
FineJOptionPane.showMessageDialog(designerFrame, Toolkit.i18nText("Fine-Design_Share_Select_Error_Tip"), |
||||
Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"), ERROR_MESSAGE, IOUtils.readIcon("/com/fr/base/images/share/Information_Icon_warning_normal_32x32.png")); |
||||
return; |
||||
} |
||||
|
||||
Widget widget = sharedTriple.getLeft(); |
||||
|
||||
try { |
||||
|
||||
if (form == null) { |
||||
throw new NullPointerException("tpl get failed"); |
||||
} |
||||
//准备参数
|
||||
prepareParameter(widget, designerFrame); |
||||
|
||||
//准备的封面大小
|
||||
//组件大小
|
||||
Rectangle reportRec = FormIO.getContentRect(form); |
||||
Image coverImage = toCoverImage(form, sharedTriple, parameterMap, reportRec); |
||||
|
||||
Object[] compositeArg = new Object[]{jt, widget, sharedTriple.getRight(), coverImage, parameterMap, (ShareUIAspect)aspect}; |
||||
HashMap<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, Toolkit.i18nText("Fine-Design_Share_Create_Share_Pane_Failed"), |
||||
Toolkit.i18nText("Fine-Design_Basic_Error"), ERROR_MESSAGE, UIManager.getIcon("OptionPane.errorIcon")); |
||||
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 准备参数 |
||||
*/ |
||||
private void prepareParameter(Widget widget, DesignerFrame designerFrame) { |
||||
|
||||
final Calculator ca = Calculator.createCalculator(); |
||||
Parameter[] tplParameters = ((Form)HistoryTemplateListPane.getInstance().getCurrentEditingTemplate().getTarget()).getParameters(); |
||||
widgetPara = new String[]{}; |
||||
calWidgetParameter(widget, ca); |
||||
List<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-Design_Share_Install")); |
||||
} |
||||
|
||||
@Override |
||||
public void actionPerformed(ActionEvent e) { |
||||
|
||||
if (SupportOSImpl.NATIVE_CHOOSER.support()) { |
||||
UINativeFileChooser nativeFileChooser = new UINativeFileChooser(); |
||||
nativeFileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); |
||||
nativeFileChooser.setMultiSelectionEnabled(true); |
||||
nativeFileChooser.setFileFilter(new FileNameExtensionFilter("reu reus", "reu", "reus")); |
||||
nativeFileChooser.setDialogTitle(Toolkit.i18nText("Fine-Design_Basic_Select")); |
||||
int returnValue = nativeFileChooser.showOpenDialog(new UILabel()); |
||||
installComponent(returnValue, nativeFileChooser.getSelectedFiles()); |
||||
} else { |
||||
JFileChooser fileChooser = new JFileChooser(); |
||||
fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); |
||||
fileChooser.setMultiSelectionEnabled(true); |
||||
fileChooser.setFileFilter(new FileNameExtensionFilter("reu reus", "reu", "reus")); |
||||
int returnValue = fileChooser.showDialog(new UILabel(), Toolkit.i18nText("Fine-Design_Basic_Select")); |
||||
installComponent(returnValue, fileChooser.getSelectedFiles()); |
||||
} |
||||
} |
||||
|
||||
private void installComponent(int returnValue, File[] selectedFiles) { |
||||
if (returnValue != JFileChooser.APPROVE_OPTION) { |
||||
return; |
||||
} |
||||
LocalWidgetRepoPane.getInstance().switch2InstallingPane(); |
||||
final File[] chosenFiles = selectedFiles; |
||||
new SwingWorker<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-Design_Share_Share_Module_Install_Error")); |
||||
} |
||||
} |
||||
|
||||
private boolean containRues(File[] chosenFiles) { |
||||
for (File file : chosenFiles) { |
||||
if (file.getName().endsWith(ReuxUtils.REUS_SUFFIX)) |
||||
return true; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
private String appendString(List<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; |
||||
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-Design_Share_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-Design_Share_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-Design_Share_Type_Indicator_Card"), |
||||
|
||||
TITLE("Fine-Design_Share_Type_Title"), |
||||
|
||||
DIMENSION_CHANGE("Fine-Design_Share_Type_Dimension_Change"), |
||||
|
||||
FILL("Fine-Design_Share_Type_Fill", DisplayDevice.MOBILE), |
||||
|
||||
Directory_Navigation("Fine-Design_Share_Type_Mobile_Directory_Navigation", DisplayDevice.MOBILE), |
||||
|
||||
|
||||
SPECIAL_CARD("Fine-Design_Share_Type_Special_Card"); |
||||
|
||||
private String locale; |
||||
|
||||
/** |
||||
* @see DisplayDevice |
||||
*/ |
||||
private int support; |
||||
|
||||
ReportChildTypes(String locale) { |
||||
this(locale, DisplayDevice.buildAll()); |
||||
} |
||||
|
||||
ReportChildTypes(String locale, DisplayDevice device) { |
||||
this(locale, device.getType()); |
||||
} |
||||
|
||||
ReportChildTypes(String locale, int support) { |
||||
this.locale = locale; |
||||
this.support = support; |
||||
} |
||||
|
||||
public static List<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("Fine-Design_Share_Type_Chart_Column"), |
||||
|
||||
PIE_CHART("Fine-Design_Share_Type_Chart_Pie"), |
||||
|
||||
FOLD_LINE_CHART("Fine-Design_Share_Type_Chart_Fold_Line"), |
||||
|
||||
COMBINE_CHART("Fine-Design_Share_Type_Chart_Combine"), |
||||
|
||||
METER_CHART("Fine-Design_Share_Type_Chart_Meter"), |
||||
|
||||
MAP_CHART("Fine-Design_Share_Type_Chart_Map"), |
||||
|
||||
OTHERS("Fine-Design_Share_Type_Chart_Other"), |
||||
|
||||
DETAIL_LIST("Fine-Design_Share_Type_Detail_List"), |
||||
|
||||
BASIC_WIDGET("Fine-Design_Share_Type_Basic_Widget"); |
||||
|
||||
private String locale; |
||||
|
||||
ChartChildTypes(String locale) { |
||||
this.locale = locale; |
||||
} |
||||
|
||||
public static List<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-Design_Share_Style_Theme_Simple", "1"), |
||||
BUSINESS_STABLE("Fine-Design_Share_Style_Theme_Business", "2"), |
||||
LIVE_GORGEOUS("Fine-Design_Share_Style_Theme_Live", "3"), |
||||
COOL_TECHNOLOGY("Fine-Design_Share_Style_Theme_Cool", "4"), |
||||
OTHER_THEME("Fine-Design_Share_Style_Theme_Other", "5"); |
||||
|
||||
|
||||
private final String local; |
||||
private final String id; |
||||
|
||||
StyleTheme(String name, String id) { |
||||
this.local = name; |
||||
this.id = id; |
||||
} |
||||
|
||||
public String getLocText() { |
||||
return Toolkit.i18nText(this.local); |
||||
} |
||||
|
||||
public String getId() { |
||||
return this.id; |
||||
} |
||||
|
||||
private static List<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-Design_Share_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.ShareEmbeddedConverter; |
||||
import com.fr.form.share.bean.ComponentReuBean; |
||||
import com.fr.form.share.editor.DefaultSharableEditor; |
||||
import com.fr.form.share.editor.PlainSharableEditor; |
||||
import com.fr.form.share.utils.ShareUtils; |
||||
import com.fr.form.ui.AbstractBorderStyleWidget; |
||||
import com.fr.form.ui.Widget; |
||||
import com.fr.log.FineLoggerFactory; |
||||
import com.fr.stable.fun.IOFileAttrMark; |
||||
import com.fr.workspace.WorkContext; |
||||
import org.jetbrains.annotations.NotNull; |
||||
|
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* created by Harrison on 2020/04/13 |
||||
**/ |
||||
public class ComponentCreator extends AbstractComponentCreatorProcessor { |
||||
|
||||
/** |
||||
* 生成组件 |
||||
* 返回组件的路径 |
||||
* |
||||
* @return 路径 |
||||
*/ |
||||
@Override |
||||
public ComponentReuBean create(JTemplate<?, ?> jt, Map<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-Design_Share_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); |
||||
} |
||||
|
||||
// //内置数据集
|
||||
ShareEmbeddedConverter embeddedConverter = WorkContext.getCurrent().get(ShareEmbeddedConverter.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-Design_Share_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-Design_Share_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-Design_Share_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-Design_Share_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-Design_Share_Encrypt"); |
||||
} |
||||
|
||||
private boolean upload0(String path) throws Exception { |
||||
|
||||
CloseableHttpClient client = createClient(); |
||||
if (login(client)) { |
||||
HttpPost uploadRequest = new HttpPost(URL_MARKET_REU_FILE_UPLOAD); |
||||
byte[] bytes = WorkContext.getWorkResource().readFully(path); |
||||
String fileName = ResourceIOUtils.getName(path); |
||||
HttpEntity reqEntity = MultipartEntityBuilder.create() |
||||
.setCharset(StandardCharsets.UTF_8) |
||||
.setMode(HttpMultipartMode.BROWSER_COMPATIBLE) |
||||
// 相当于<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-Design_Share_Group_Repeat_Name_Info")); |
||||
warnLabel.setVisible(true); |
||||
confirmButton.setEnabled(false); |
||||
} else { |
||||
warnLabel.setVisible(false); |
||||
confirmButton.setEnabled(true); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 点击确定后的处理方法 |
||||
*/ |
||||
abstract protected void confirmClose(); |
||||
|
||||
/** |
||||
* 是否重名 |
||||
*/ |
||||
abstract protected boolean isDuplicate(String fileName); |
||||
|
||||
|
||||
private UILabel creteNewNameLabel() { |
||||
// 输入框前提示
|
||||
UILabel newNameLabel = new UILabel(Toolkit.i18nText("Fine-Design_Share_Group_Enter_New_Folder_Name")); |
||||
newNameLabel.setHorizontalAlignment(SwingConstants.RIGHT); |
||||
newNameLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 10)); |
||||
newNameLabel.setPreferredSize(new Dimension(84, 16)); |
||||
return newNameLabel; |
||||
} |
||||
|
||||
private void createNameField(String name) { |
||||
// 文件名输入框
|
||||
nameField = new UITextField(name); |
||||
nameField.getDocument().addDocumentListener(new DocumentListener() { |
||||
|
||||
public void changedUpdate(DocumentEvent e) { |
||||
validInput(); |
||||
} |
||||
|
||||
public void insertUpdate(DocumentEvent e) { |
||||
validInput(); |
||||
} |
||||
|
||||
public void removeUpdate(DocumentEvent e) { |
||||
validInput(); |
||||
} |
||||
}); |
||||
nameField.selectAll(); |
||||
nameField.setPreferredSize(new Dimension(200, 20)); |
||||
// 增加enter以及esc快捷键的支持
|
||||
nameField.addKeyListener(new KeyAdapter() { |
||||
@Override |
||||
public void keyPressed(KeyEvent e) { |
||||
if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { |
||||
dispose(); |
||||
} else if (e.getKeyCode() == KeyEvent.VK_ENTER) { |
||||
if (confirmButton.isEnabled()) { |
||||
confirmClose(); |
||||
} |
||||
} |
||||
} |
||||
}); |
||||
} |
||||
|
||||
private void createWarnLabel() { |
||||
warnLabel = new UILabel(); |
||||
warnLabel.setPreferredSize(new Dimension(300, 30)); |
||||
warnLabel.setHorizontalAlignment(SwingConstants.LEFT); |
||||
warnLabel.setForeground(Color.RED); |
||||
warnLabel.setVisible(false); |
||||
} |
||||
} |
@ -0,0 +1,79 @@
|
||||
package com.fr.design.mainframe.share.group.ui; |
||||
|
||||
import com.fr.design.gui.ibutton.UIButton; |
||||
import com.fr.design.gui.icombobox.UIComboBox; |
||||
import com.fr.design.gui.ilable.UILabel; |
||||
import com.fr.design.i18n.Toolkit; |
||||
import com.fr.form.share.group.DefaultShareGroupManager; |
||||
|
||||
import javax.swing.BorderFactory; |
||||
import javax.swing.JPanel; |
||||
import javax.swing.SwingConstants; |
||||
import java.awt.BorderLayout; |
||||
import java.awt.Dimension; |
||||
import java.awt.FlowLayout; |
||||
import java.awt.Frame; |
||||
|
||||
/** |
||||
* @Author: Yuan.Wang |
||||
* @Date: 2020/12/9 |
||||
*/ |
||||
abstract public class GroupMoveDialog extends BaseGroupDialog { |
||||
private UIComboBox selectGroupBox; |
||||
|
||||
public GroupMoveDialog(Frame frame) { |
||||
super(frame); |
||||
this.setLayout(new BorderLayout()); |
||||
this.setModal(true); |
||||
|
||||
setTitle(Toolkit.i18nText("Fine-Design_Share_Group_Move")); |
||||
// 标签
|
||||
UILabel newNameLabel = creteNewNameLabel(); |
||||
// 输入框
|
||||
createSwitchGroupBox(); |
||||
|
||||
// 确认按钮
|
||||
UIButton confirmButton = createConfirmButton(); |
||||
confirmButton.setEnabled(true); |
||||
// 取消按钮
|
||||
UIButton cancelButton = createCancelButton(); |
||||
|
||||
JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 5)); |
||||
topPanel.setBorder(BorderFactory.createEmptyBorder(15, 15, 0, 15)); |
||||
topPanel.add(newNameLabel); |
||||
topPanel.add(selectGroupBox); |
||||
|
||||
JPanel bottomPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); |
||||
bottomPanel.setBorder(BorderFactory.createEmptyBorder(0, 15, 0, 15)); |
||||
bottomPanel.setPreferredSize(new Dimension(340, 45)); |
||||
bottomPanel.add(confirmButton); |
||||
bottomPanel.add(cancelButton); |
||||
this.add(topPanel, BorderLayout.CENTER); |
||||
this.add(bottomPanel, BorderLayout.SOUTH); |
||||
|
||||
initStyle(); |
||||
|
||||
|
||||
} |
||||
|
||||
private void createSwitchGroupBox() { |
||||
// 文件名输入框
|
||||
selectGroupBox = new UIComboBox(DefaultShareGroupManager.getInstance().getAllGroup()); |
||||
selectGroupBox.setPreferredSize(new Dimension(225, 20)); |
||||
} |
||||
|
||||
|
||||
private UILabel creteNewNameLabel() { |
||||
// 输入框前提示
|
||||
UILabel newNameLabel = new UILabel(Toolkit.i18nText("Fine-Design_Share_Group_Select")); |
||||
newNameLabel.setHorizontalAlignment(SwingConstants.RIGHT); |
||||
newNameLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 10)); |
||||
newNameLabel.setPreferredSize(new Dimension(60, 16)); |
||||
return newNameLabel; |
||||
} |
||||
|
||||
protected UIComboBox getSelectGroupBox() { |
||||
return selectGroupBox; |
||||
} |
||||
|
||||
} |
@ -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("Fine-Design_Share_Module_Failed")); |
||||
} |
||||
return new ImmutableTriple<>(selectedWidget, selectedCreator, selectedTriple); |
||||
} |
||||
|
||||
//先从body中找,如果找不到再从参数面板中找
|
||||
@Nullable |
||||
private WLayout getParentLayout(Form form, Widget innerWidget) { |
||||
WLayout bodyLayout = (WLayout) ((WBorderLayout) form.getContainer()).getLayoutWidget(WBorderLayout.CENTER); |
||||
WLayout paraLayout = (WLayout) ((WBorderLayout) form.getContainer()).getLayoutWidget(WBorderLayout.NORTH); |
||||
WLayout parentLayout = FormCompVisibleUtils.findFitLayout(bodyLayout, innerWidget); |
||||
if (parentLayout == null && paraLayout != null) { |
||||
parentLayout = FormCompVisibleUtils.findFitLayout(paraLayout, innerWidget); |
||||
} |
||||
return parentLayout; |
||||
} |
||||
|
||||
//组件集合产生绝对布局的时候,子组件的bounds需要去掉主框架的xy值,保证边界和绝对布局对齐
|
||||
private static void adaptBounds(CRBoundsWidget cRBoundsWidget, Rectangle delRec) { |
||||
Rectangle rec = cRBoundsWidget.getBounds(); |
||||
int originX = rec.x; |
||||
int originY = rec.y; |
||||
int delX = delRec.x; |
||||
int delY = delRec.y; |
||||
cRBoundsWidget.setBounds(new Rectangle(originX - delX, originY - delY, rec.width, rec.height)); |
||||
} |
||||
|
||||
private static boolean supportShared(Widget widget) { |
||||
|
||||
return notBody(widget) && notForm(widget); |
||||
} |
||||
|
||||
private static boolean notBody(Widget widget) { |
||||
return !(widget instanceof WAbsoluteBodyLayout || widget instanceof WFitLayout || widget instanceof WParameterLayout); |
||||
} |
||||
|
||||
private static boolean notForm(Widget widget) { |
||||
if (!(widget instanceof WBorderLayout)) { |
||||
return true; |
||||
} |
||||
Widget centerWidget = ((WBorderLayout) widget).getLayoutWidget(WBorderLayout.CENTER); |
||||
return notBody(centerWidget); |
||||
|
||||
} |
||||
} |
@ -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-Design_Share_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-Design_Share_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-Design_Share_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-Design_Share_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-Design_Share_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-Design_Share_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-Design_Share_Package_Downloading_Tip")); |
||||
downloadTipLabel.setPreferredSize(new Dimension(240, 90)); |
||||
downloadTipLabel.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5)); |
||||
downloadTipLabel.setForeground(Color.WHITE); |
||||
downloadTipLabel.setHorizontalTextPosition(UILabel.CENTER); |
||||
|
||||
|
||||
JPanel centerPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||
centerPane.setPreferredSize(new Dimension(240, 138)); |
||||
centerPane.add(labelPane, BorderLayout.NORTH); |
||||
centerPane.add(panel, BorderLayout.CENTER); |
||||
centerPane.add(downloadTipLabel, BorderLayout.SOUTH); |
||||
centerPane.setOpaque(false); |
||||
|
||||
this.add(centerPane, BorderLayout.NORTH); |
||||
this.setSize(new Dimension(240, 800)); |
||||
this.setBackground(new Color(0, 0, 0, 0)); |
||||
this.setOpaque(false); |
||||
} |
||||
|
||||
private UILabel createTipLabel() { |
||||
UILabel label = new UILabel(ProcessState.DOWNLOADING.tip); |
||||
label.setPreferredSize(new Dimension(200, 20)); |
||||
label.setHorizontalAlignment(UILabel.CENTER); |
||||
label.setOpaque(false); |
||||
label.setForeground(Color.WHITE); |
||||
return label; |
||||
} |
||||
|
||||
private JProgressBar createProgressBar() { |
||||
JProgressBar jProgressBar = new JProgressBar(); |
||||
jProgressBar.setUI(new ModernUIProgressBarUI()); |
||||
jProgressBar.setBorderPainted(false); |
||||
jProgressBar.setOpaque(false); |
||||
jProgressBar.setBorder(null); |
||||
jProgressBar.setMaximum(MAX_NUM); |
||||
return jProgressBar; |
||||
} |
||||
|
||||
public void changeState() { |
||||
tipLabel.setText(ProcessState.INSTALLING.tip); |
||||
closeLabel.setVisible(false); |
||||
this.validate(); |
||||
this.repaint(); |
||||
} |
||||
|
||||
public void updateProgress(double process) { |
||||
if (process < 0 || process > 1) { |
||||
throw new IllegalArgumentException(); |
||||
} |
||||
processBar.setValue((int) (process * MAX_NUM)); |
||||
} |
||||
|
||||
|
||||
private enum ProcessState { |
||||
DOWNLOADING(Toolkit.i18nText("Fine-Design_Share_Package_Downloading")), |
||||
INSTALLING(Toolkit.i18nText("Fine-Design_Share_Package_Installing")); |
||||
|
||||
private final String tip; |
||||
|
||||
ProcessState(String tip) { |
||||
this.tip = tip; |
||||
} |
||||
} |
||||
|
||||
public static void main(String[] args) { |
||||
JFrame frame = new JFrame(); |
||||
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); |
||||
frame.setBounds(600, 200, 240, 500); |
||||
|
||||
DownloadProgressPane pane = new DownloadProgressPane(null); |
||||
pane.updateProgress(0.5); |
||||
frame.add(pane); |
||||
frame.setVisible(true); |
||||
|
||||
} |
||||
} |
||||
|
||||
|
@ -0,0 +1,58 @@
|
||||
package com.fr.design.mainframe.share.ui.base; |
||||
|
||||
import com.fr.design.dialog.BasicPane; |
||||
import com.fr.design.gui.frpane.UITextPane; |
||||
import com.fr.design.gui.icontainer.UIScrollPane; |
||||
import com.fr.design.gui.ilable.UILabel; |
||||
import com.fr.design.i18n.Toolkit; |
||||
import com.fr.general.IOUtils; |
||||
|
||||
import javax.swing.BorderFactory; |
||||
import javax.swing.JPanel; |
||||
import javax.swing.text.Style; |
||||
import javax.swing.text.StyleConstants; |
||||
import javax.swing.text.StyleContext; |
||||
import java.awt.BorderLayout; |
||||
import java.awt.FlowLayout; |
||||
|
||||
/** |
||||
* @Author: Yuan.Wang |
||||
* @Date: 2020/9/14 |
||||
*/ |
||||
public class FailureMessagePane extends BasicPane { |
||||
public FailureMessagePane(String str) { |
||||
UILabel imageLabel = new UILabel(IOUtils.readIcon("/com/fr/base/images/share/error_icon.png")); |
||||
UILabel label = new UILabel(Toolkit.i18nText("Fine-Design_Share_Share_Modules_Error")); |
||||
UITextPane textPane = new UITextPane(); |
||||
UIScrollPane jScrollPane = new UIScrollPane(textPane); |
||||
JPanel panel = new JPanel(); |
||||
|
||||
Style style = new StyleContext().new NamedStyle(); |
||||
StyleConstants.setLineSpacing(style, 0.1f); |
||||
StyleConstants.setFontSize(style, 12); |
||||
textPane.setLogicalStyle(style); |
||||
textPane.setText(str); |
||||
textPane.setCaretPosition(0); |
||||
textPane.setEditable(false); |
||||
textPane.setBorder(BorderFactory.createEmptyBorder(3, 5, 3, 5)); |
||||
|
||||
jScrollPane.setBorder(BorderFactory.createEmptyBorder()); |
||||
label.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0)); |
||||
|
||||
setLayout(new BorderLayout()); |
||||
setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 8)); |
||||
|
||||
panel.add(imageLabel); |
||||
panel.add(label); |
||||
panel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0)); |
||||
panel.setBorder(BorderFactory.createEmptyBorder(4, 0, 4, 0)); |
||||
add(panel, BorderLayout.NORTH); |
||||
add(jScrollPane, BorderLayout.CENTER); |
||||
} |
||||
|
||||
@Override |
||||
protected String title4PopupWindow() { |
||||
return Toolkit.i18nText("Fine-Design_Share_Dialog_Message"); |
||||
} |
||||
|
||||
} |
@ -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-Design_Share_Online_Loading")); |
||||
} |
||||
|
||||
public LoadingPane(String message) { |
||||
JPanel panel = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||
JPanel borderPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||
borderPane.setPreferredSize(new Dimension(120, 120)); |
||||
ImagePanel imagePanel = new ImagePanel("/com/fr/base/images/share/loading.gif"); |
||||
imagePanel.setPreferredSize(new Dimension(45, 45)); |
||||
borderPane.setBorder(BorderFactory.createEmptyBorder(150, 95, 5, 75)); |
||||
borderPane.add(imagePanel); |
||||
|
||||
panel.add(borderPane, BorderLayout.CENTER); |
||||
|
||||
JPanel labelPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||
UILabel topLabel = new UILabel(Toolkit.i18nText(message), SwingConstants.CENTER); |
||||
topLabel.setForeground(Color.GRAY); |
||||
labelPanel.add(topLabel, BorderLayout.CENTER); |
||||
labelPanel.setPreferredSize(new Dimension(240, 20)); |
||||
panel.add(labelPanel, BorderLayout.SOUTH); |
||||
|
||||
panel.setPreferredSize(new Dimension(240, 230)); |
||||
|
||||
|
||||
this.setLayout(FRGUIPaneFactory.createBorderLayout()); |
||||
this.setBorder(BorderFactory.createEmptyBorder(100, 0, 0, 0)); |
||||
this.add(panel, BorderLayout.NORTH); |
||||
} |
||||
|
||||
} |
@ -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-Design_Share_No_Match_Result"), SwingConstants.CENTER); |
||||
label.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0)); |
||||
label.setForeground(Color.gray); |
||||
label.setPreferredSize(new Dimension(240, 20)); |
||||
label.setHorizontalAlignment(SwingConstants.CENTER); |
||||
panel.add(picLabel); |
||||
panel.add(label); |
||||
panel.setBorder(BorderFactory.createEmptyBorder(250, 0, 0, 0)); |
||||
this.setLayout(new BorderLayout()); |
||||
this.add(panel, BorderLayout.CENTER); |
||||
} |
||||
} |
@ -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; |
||||
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-Design_Share_Drag_Error_Info")); |
||||
return; |
||||
} |
||||
creatorSource.setWidgetID(UUID.randomUUID().toString()); |
||||
((AbstractBorderStyleWidget) creatorSource).addWidgetAttrMark(new SharableAttrMark(true)); |
||||
//tab布局WCardMainBorderLayout通过反射出来的大小是960*480
|
||||
XCreator xCreator = ShareComponentUtils.createXCreator(creatorSource, shareId, no.getBindInfo()); |
||||
WidgetToolBarPane.getTarget().startDraggingBean(xCreator); |
||||
lastPressEvent = null; |
||||
this.setBorder(null); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void paint(Graphics g) { |
||||
super.paint(g); |
||||
//绘制删除标志
|
||||
if (isEdit) { |
||||
Icon icon = isMarked ? markedMode : unMarkedMode; |
||||
icon.paintIcon(this, g, MARK_START_X, 0); |
||||
} |
||||
if (ComparatorUtils.equals(this, this.parentPane.getSelectedBlock()) || this.mouseHover) { |
||||
g.setColor(XCreatorConstants.FORM_BORDER_COLOR); |
||||
Rectangle rectangle = new Rectangle(); |
||||
rectangle.width = this.getWidth(); |
||||
rectangle.height = this.getHeight(); |
||||
GraphHelper.draw(g, rectangle, Constants.LINE_LARGE); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 由鼠标释放时调用该方法来触发左键点击事件 |
||||
*/ |
||||
private void dealClickAction(MouseEvent e) { |
||||
this.parentPane.setSelectBlock(this); |
||||
if (e.getButton() == MouseEvent.BUTTON1) { |
||||
if (isEdit) { |
||||
if (isMarked) { |
||||
WidgetSelectedManager.getInstance().removeSelect(getGroup().getGroupName(), this.getWidget().getId()); |
||||
isMarked = false; |
||||
} else { |
||||
WidgetSelectedManager.getInstance().addSelect(getGroup().getGroupName(), this.getWidget().getId()); |
||||
isMarked = true; |
||||
} |
||||
} |
||||
//没有组件被选择则禁用按钮
|
||||
LocalWidgetRepoPane.getInstance().setManageButtonEnable(hasComponentSelected()); |
||||
repaint(); |
||||
} |
||||
} |
||||
|
||||
private Group getGroup() { |
||||
return parentPane.getGroup(); |
||||
} |
||||
|
||||
private boolean hasComponentSelected() { |
||||
return !WidgetSelectedManager.getInstance().isSelectEmpty(); |
||||
} |
||||
|
||||
private class MoveGroupAction extends UpdateAction { |
||||
public MoveGroupAction() { |
||||
this.putValue(Action.SMALL_ICON, null); |
||||
this.setName(Toolkit.i18nText("Fine-Design_Share_Group_Move")); |
||||
} |
||||
|
||||
@Override |
||||
public void actionPerformed(ActionEvent e) { |
||||
new GroupMoveDialog(DesignerContext.getDesignerFrame()) { |
||||
@Override |
||||
protected void confirmClose() { |
||||
this.dispose(); |
||||
Group group = (Group) getSelectGroupBox().getSelectedItem(); |
||||
assert group != null; |
||||
if (WidgetSelectedManager.getInstance().moveSelect(getGroup().getGroupName(), group.getGroupName(), getWidget().getId())) { |
||||
ShareWidgetInfoManager.getInstance().saveXmlInfo(); |
||||
LocalWidgetRepoPane.getInstance().refreshShowPanel(false); |
||||
} else { |
||||
ShareUIUtils.showErrorMessageDialog(Toolkit.i18nText("Fine-Design_Share_Group_Move_Fail_Message")); |
||||
} |
||||
} |
||||
|
||||
}; |
||||
} |
||||
} |
||||
|
||||
private class RemoveAction extends UpdateAction { |
||||
public RemoveAction() { |
||||
this.putValue(Action.SMALL_ICON, null); |
||||
this.setName(Toolkit.i18nText("Fine-Design_Share_Remove")); |
||||
} |
||||
|
||||
@Override |
||||
public void actionPerformed(ActionEvent e) { |
||||
int rv = FineJOptionPane.showConfirmDialog(DesignerContext.getDesignerFrame(), |
||||
Toolkit.i18nText("Fine-Design_Share_Remove_Info"), |
||||
Toolkit.i18nText("Fine-Design_Share_Group_Confirm"), |
||||
FineJOptionPane.YES_NO_OPTION |
||||
); |
||||
if (rv == FineJOptionPane.YES_OPTION) { |
||||
if (!WidgetSelectedManager.getInstance().unInstallSelect(getGroup().getGroupName(), getWidget().getId())) { |
||||
FineJOptionPane.showMessageDialog(null, Toolkit.i18nText("Fine-Design_Share_Remove_Failure")); |
||||
} |
||||
LocalWidgetRepoPane.getInstance().refreshShowPanel(getGroup()); |
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,303 @@
|
||||
package com.fr.design.mainframe.share.ui.block; |
||||
|
||||
import com.fr.base.iofile.attr.SharableAttrMark; |
||||
import com.fr.config.MarketConfig; |
||||
import com.fr.design.base.mode.DesignModeContext; |
||||
import com.fr.design.designer.creator.XCreator; |
||||
import com.fr.design.extra.WebViewDlgHelper; |
||||
import com.fr.design.form.util.XCreatorConstants; |
||||
import com.fr.design.gui.ilable.UILabel; |
||||
import com.fr.design.i18n.Toolkit; |
||||
import com.fr.design.layout.FRGUIPaneFactory; |
||||
import com.fr.design.mainframe.WidgetToolBarPane; |
||||
import com.fr.design.mainframe.share.collect.ComponentCollector; |
||||
import com.fr.form.share.group.DefaultShareGroup; |
||||
import com.fr.design.mainframe.share.ui.local.LocalWidgetRepoPane; |
||||
import com.fr.design.mainframe.share.ui.online.OnlineWidgetRepoPane; |
||||
import com.fr.design.mainframe.share.ui.online.OnlineWidgetSelectPane; |
||||
import com.fr.design.mainframe.share.util.DownloadUtils; |
||||
import com.fr.design.mainframe.share.util.ShareComponentUtils; |
||||
import com.fr.design.mainframe.share.util.ShareUIUtils; |
||||
import com.fr.design.ui.util.UIUtil; |
||||
import com.fr.form.share.SharableWidgetProvider; |
||||
import com.fr.form.share.bean.OnlineShareWidget; |
||||
import com.fr.form.share.constants.ShareComponentConstants; |
||||
import com.fr.form.share.group.DefaultShareGroupManager; |
||||
import com.fr.form.share.Group; |
||||
import com.fr.form.share.utils.ShareUtils; |
||||
import com.fr.form.ui.AbstractBorderStyleWidget; |
||||
import com.fr.form.ui.Widget; |
||||
import com.fr.general.IOUtils; |
||||
import com.fr.log.FineLoggerFactory; |
||||
import com.fr.stable.StableUtils; |
||||
import com.fr.stable.StringUtils; |
||||
|
||||
import javax.swing.JPanel; |
||||
import javax.swing.SwingConstants; |
||||
import javax.swing.SwingWorker; |
||||
import java.awt.AlphaComposite; |
||||
import java.awt.BorderLayout; |
||||
import java.awt.Color; |
||||
import java.awt.Composite; |
||||
import java.awt.Cursor; |
||||
import java.awt.Dimension; |
||||
import java.awt.Graphics; |
||||
import java.awt.Graphics2D; |
||||
import java.awt.Rectangle; |
||||
import java.awt.RenderingHints; |
||||
import java.awt.Stroke; |
||||
import java.awt.dnd.DnDConstants; |
||||
import java.awt.event.MouseEvent; |
||||
import java.awt.image.BufferedImage; |
||||
import java.io.File; |
||||
import java.io.IOException; |
||||
import java.util.UUID; |
||||
import java.util.concurrent.ExecutionException; |
||||
|
||||
/** |
||||
* Created by kerry on 2020-10-19 |
||||
* 商城组件块 |
||||
*/ |
||||
public class OnlineWidgetBlock extends AbstractOnlineWidgetBlock { |
||||
private boolean isMouseEnter = false; |
||||
private boolean downloading = false; |
||||
private static final Color COVER_COLOR = Color.decode("#333334"); |
||||
protected MouseEvent lastPressEvent; |
||||
private double process = 0D; |
||||
private static final BufferedImage WIDGET_INSTALLED_ICON = IOUtils.readImage("/com/fr/base/images/share/widget_installed.png"); |
||||
private static final BufferedImage WIDGET_DOWNLOAD_ICON = IOUtils.readImage("/com/fr/base/images/share/download.png"); |
||||
private static final BufferedImage WIDGET_DOWNLOADING_ICON = IOUtils.readImage("/com/fr/base/images/share/downloading.png"); |
||||
|
||||
public OnlineWidgetBlock(OnlineShareWidget widget, OnlineWidgetSelectPane parentPane) { |
||||
super(widget, parentPane); |
||||
this.add(createSouthPane(widget), BorderLayout.SOUTH); |
||||
new DragAndDropDragGestureListener(this, DnDConstants.ACTION_COPY_OR_MOVE); |
||||
} |
||||
|
||||
protected JPanel createSouthPane(OnlineShareWidget widget) { |
||||
JPanel southPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||
UILabel label = new UILabel(widget.getName(), UILabel.CENTER); |
||||
label.setToolTipText(widget.getName()); |
||||
label.setHorizontalTextPosition(SwingConstants.LEFT); |
||||
southPane.add(label, BorderLayout.CENTER); |
||||
UILabel emptyLabel = new UILabel(); |
||||
emptyLabel.setPreferredSize(new Dimension(25, 20)); |
||||
southPane.add(emptyLabel, BorderLayout.EAST); |
||||
southPane.setBackground(Color.WHITE); |
||||
return southPane; |
||||
} |
||||
|
||||
@Override |
||||
public void mouseEntered(MouseEvent e) { |
||||
super.mouseEntered(e); |
||||
this.isMouseEnter = true; |
||||
this.repaint(); |
||||
} |
||||
|
||||
@Override |
||||
public void mouseExited(MouseEvent e) { |
||||
super.mouseExited(e); |
||||
this.isMouseEnter = false; |
||||
this.repaint(); |
||||
} |
||||
|
||||
@Override |
||||
public void mousePressed(MouseEvent e) { |
||||
super.mousePressed(e); |
||||
this.lastPressEvent = e; |
||||
} |
||||
|
||||
@Override |
||||
public void mouseClicked(MouseEvent e) { |
||||
super.mouseClicked(e); |
||||
if (!checkWidgetInstalled() && getDownloadIconRec().contains(e.getX(), e.getY())) { |
||||
downLoadWidget(); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void mouseDragged(MouseEvent e) { |
||||
if (DesignModeContext.isAuthorityEditing() || !checkWidgetInstalled()) { |
||||
return; |
||||
} |
||||
if (lastPressEvent == null) { |
||||
return; |
||||
} |
||||
Object source = e.getSource(); |
||||
Widget creatorSource; |
||||
String shareId; |
||||
if (source instanceof OnlineWidgetBlock) { |
||||
OnlineWidgetBlock no = (OnlineWidgetBlock) e.getSource(); |
||||
if (no == null) { |
||||
return; |
||||
} |
||||
shareId = widget.getUuid(); |
||||
creatorSource = ShareUtils.getElCaseEditorById(shareId); |
||||
if (creatorSource == null) { |
||||
ShareUIUtils.showErrorMessageDialog(Toolkit.i18nText("Fine-Design_Share_Drag_Error_Info")); |
||||
return; |
||||
} |
||||
creatorSource.setWidgetID(UUID.randomUUID().toString()); |
||||
((AbstractBorderStyleWidget) creatorSource).addWidgetAttrMark(new SharableAttrMark(true)); |
||||
SharableWidgetProvider bindInfo = ShareUtils.getElCaseBindInfoById(shareId); |
||||
//tab布局WCardMainBorderLayout通过反射出来的大小是960*480
|
||||
XCreator xCreator = ShareComponentUtils.createXCreator(creatorSource, shareId, bindInfo); |
||||
WidgetToolBarPane.getTarget().startDraggingBean(xCreator); |
||||
lastPressEvent = null; |
||||
this.setBorder(null); |
||||
} |
||||
} |
||||
|
||||
private void downLoadWidget() { |
||||
if (OnlineWidgetRepoPane.getInstance().isShowPackagePanel()) { |
||||
ComponentCollector.getInstance().collectDownloadPktNum(); |
||||
} |
||||
final WidgetDownloadProcess process = new WidgetDownloadProcess(); |
||||
downloading = true; |
||||
process.process(0.0D); |
||||
String userName = MarketConfig.getInstance().getBbsUsername(); |
||||
if (StringUtils.isEmpty(userName)) { |
||||
WebViewDlgHelper.createLoginDialog(); |
||||
downloading = false; |
||||
return; |
||||
} |
||||
|
||||
new SwingWorker<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-Design_Share_Download_Failed")); |
||||
} |
||||
} catch (InterruptedException e) { |
||||
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||
Thread.currentThread().interrupt(); |
||||
} catch (ExecutionException e) { |
||||
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||
} |
||||
} |
||||
}.execute(); |
||||
|
||||
|
||||
} |
||||
|
||||
|
||||
@Override |
||||
public void mouseMoved(MouseEvent e) { |
||||
super.mouseMoved(e); |
||||
if (checkWidgetInstalled()) { |
||||
this.setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR)); |
||||
} else if (getDownloadIconRec().contains(e.getX(), e.getY())) { |
||||
this.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); |
||||
} else { |
||||
this.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); |
||||
} |
||||
} |
||||
|
||||
private Rectangle getDownloadIconRec() { |
||||
return new Rectangle(ShareComponentConstants.SHARE_THUMB_WIDTH / 2 - 12, ShareComponentConstants.SHARE_BLOCK_HEIGHT / 2 - 16, 24, 24); |
||||
} |
||||
|
||||
private boolean checkWidgetInstalled() { |
||||
return ShareUtils.getElCaseBindInfoById(widget.getUuid()) != null; |
||||
} |
||||
|
||||
private Group getDefaultGroup() { |
||||
return DefaultShareGroupManager.getInstance().getGroup(DefaultShareGroup.GROUP_NAME); |
||||
} |
||||
|
||||
public void paint(Graphics g) { |
||||
super.paint(g); |
||||
((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); |
||||
((Graphics2D) g).setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB); |
||||
int x = 0; |
||||
int y = 0; |
||||
int w = getWidth(); |
||||
int h = getHeight(); |
||||
if (process == 1 || checkWidgetInstalled()) { |
||||
Graphics2D g2d = (Graphics2D) g; |
||||
g2d.drawImage( |
||||
WIDGET_INSTALLED_ICON, |
||||
w - 20, |
||||
h - 20, |
||||
WIDGET_INSTALLED_ICON.getWidth(), |
||||
WIDGET_INSTALLED_ICON.getHeight(), |
||||
null, |
||||
this |
||||
); |
||||
return; |
||||
} |
||||
//如果鼠标移动到布局内且布局不可编辑,画出编辑蒙层
|
||||
if (isMouseEnter || downloading) { |
||||
Graphics2D g2d = (Graphics2D) g; |
||||
Composite oldComposite = g2d.getComposite(); |
||||
//画白色的编辑层
|
||||
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 20 / 100.0F)); |
||||
g2d.setColor(COVER_COLOR); |
||||
g2d.fillRect(x, y, w, h); |
||||
g2d.setComposite(oldComposite); |
||||
//画编辑按钮图标
|
||||
BufferedImage image = (process > 0 || downloading) ? WIDGET_DOWNLOADING_ICON : WIDGET_DOWNLOAD_ICON; |
||||
g2d.drawImage( |
||||
image, |
||||
(x + w / 2 - 12), |
||||
(y + h / 2 - 16), |
||||
image.getWidth(), |
||||
image.getHeight(), |
||||
null, |
||||
this |
||||
); |
||||
Stroke oldStroke = g2d.getStroke(); |
||||
g2d.setStroke(XCreatorConstants.STROKE); |
||||
g2d.setColor(Color.decode("#419BF9")); |
||||
double arcAngle = downloading ? (36 + 360 * 0.9 * process) : 0.0; |
||||
g2d.drawArc(x + w / 2 - 12, y + h / 2 - 16, 24, 24, 90, -(int) arcAngle); |
||||
g2d.setColor(Color.WHITE); |
||||
g2d.setStroke(oldStroke); |
||||
} |
||||
} |
||||
|
||||
|
||||
class WidgetDownloadProcess implements com.fr.design.extra.Process<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-Design_Share_Online_Package_Detail")); |
||||
detailLabel.setForeground(TEXT_COLOR); |
||||
detailLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); |
||||
detailLabel.addMouseListener(new MouseClickListener() { |
||||
@Override |
||||
public void mouseClicked(MouseEvent e) { |
||||
parentPane.showWidgetDetailPane(widget.getId()); |
||||
} |
||||
}); |
||||
southPane.add(detailLabel, BorderLayout.EAST); |
||||
return southPane; |
||||
} |
||||
|
||||
protected Dimension getCoverDimension() { |
||||
return new Dimension(ShareComponentConstants.SHARE_PACKAGE_BLOCK_WIDTH, IMAGE_HEIGHT); |
||||
} |
||||
|
||||
public OnlineWidgetPackageBlock(OnlineShareWidget widget, OnlineWidgetPackageSelectPane parentPane) { |
||||
super(widget, parentPane); |
||||
this.setPreferredSize(new Dimension(ShareComponentConstants.SHARE_PACKAGE_BLOCK_WIDTH, ShareComponentConstants.SHARE_PACKAGE_BLOCK_HEIGHT)); |
||||
this.add(createSouthPane(widget, parentPane), BorderLayout.SOUTH); |
||||
} |
||||
|
||||
} |
||||
|
||||
|
@ -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; |
||||
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-Design_Share_Group_Rename")); |
||||
} |
||||
|
||||
@Override |
||||
public void actionPerformed(ActionEvent e) { |
||||
new GroupFileDialog(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Design_Share_Group_Rename", group.getGroupName())) { |
||||
@Override |
||||
protected void confirmClose() { |
||||
this.dispose(); |
||||
String groupName = getFileName().replaceAll("[\\\\/:*?\"<>|]", StringUtils.EMPTY); |
||||
if (DefaultShareGroupManager.getInstance().renameGroup(group, groupName)) { |
||||
titleLabel.setText(groupName); |
||||
repaint(); |
||||
} else { |
||||
ShareUIUtils.showErrorMessageDialog(Toolkit.i18nText("Fine-Design_Share_Group_Rename_Failure")); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
protected boolean isDuplicate(String fileName) { |
||||
return DefaultShareGroupManager.getInstance().exist(fileName); |
||||
} |
||||
}; |
||||
|
||||
} |
||||
} |
||||
|
||||
private class RemoveAction extends UpdateAction { |
||||
public RemoveAction() { |
||||
this.putValue(Action.SMALL_ICON, null); |
||||
this.setName(Toolkit.i18nText("Fine-Design_Share_Group_Remove")); |
||||
} |
||||
|
||||
@Override |
||||
public void actionPerformed(ActionEvent e) { |
||||
int rv = FineJOptionPane.showConfirmDialog( |
||||
DesignerContext.getDesignerFrame(), |
||||
Toolkit.i18nText("Fine-Design_Share_Group_Remove_Info"), |
||||
Toolkit.i18nText("Fine-Design_Share_Group_Confirm"), |
||||
FineJOptionPane.YES_NO_OPTION |
||||
); |
||||
if (rv == FineJOptionPane.YES_OPTION) { |
||||
if (DefaultShareGroupManager.getInstance().removeGroup(group)) { |
||||
LocalWidgetRepoPane.getInstance().removeGroup(group.getGroupName()); |
||||
} else { |
||||
ShareUIUtils.showErrorMessageDialog(Toolkit.i18nText("Fine-Design_Share_Group_Remove_Failure")); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
public enum GroupCreateStrategy { |
||||
DEFAULT { |
||||
@Override |
||||
public GroupPane creteGroupPane(Group group) { |
||||
return new GroupPane(group); |
||||
} |
||||
}, |
||||
CLOSURE { |
||||
@Override |
||||
public GroupPane creteGroupPane(Group group) { |
||||
return new GroupPane(group, false); |
||||
} |
||||
}; |
||||
|
||||
abstract public GroupPane creteGroupPane(Group group); |
||||
} |
||||
} |
@ -0,0 +1,87 @@
|
||||
package com.fr.design.mainframe.share.ui.local; |
||||
|
||||
import com.fr.base.BaseUtils; |
||||
import com.fr.design.gui.ilable.UILabel; |
||||
import com.fr.design.i18n.Toolkit; |
||||
import com.fr.design.layout.FRGUIPaneFactory; |
||||
import com.fr.design.mainframe.share.ui.base.LoadingPane; |
||||
import com.fr.design.mainframe.share.ui.base.NoMatchPane; |
||||
|
||||
import javax.swing.BorderFactory; |
||||
import javax.swing.JPanel; |
||||
import javax.swing.SwingConstants; |
||||
import java.awt.BorderLayout; |
||||
import java.awt.Color; |
||||
import java.awt.Dimension; |
||||
|
||||
/** |
||||
* @Author: Yuan.Wang |
||||
* @Date: 2020/12/1 |
||||
*/ |
||||
enum LocalPaneStatus { |
||||
|
||||
//无匹配
|
||||
NO_MATCH { |
||||
@Override |
||||
public JPanel getPanel() { |
||||
return new NoMatchPane(); |
||||
} |
||||
}, |
||||
|
||||
//正常
|
||||
NORMAL { |
||||
@Override |
||||
public JPanel getPanel() { |
||||
return new JPanel(); |
||||
} |
||||
}, |
||||
|
||||
//空
|
||||
EMPTY { |
||||
@Override |
||||
public JPanel getPanel() { |
||||
JPanel panel = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||
UILabel picLabel = new UILabel(); |
||||
picLabel.setIcon(BaseUtils.readIcon("com/fr/base/images/share/empty.png")); |
||||
picLabel.setHorizontalAlignment(SwingConstants.CENTER); |
||||
|
||||
panel.add(picLabel, BorderLayout.CENTER); |
||||
|
||||
JPanel labelPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||
UILabel topLabel = new UILabel(Toolkit.i18nText("Fine-Design_Share_Empty_First"), SwingConstants.CENTER); |
||||
topLabel.setForeground(Color.GRAY); |
||||
UILabel bottomLabel = new UILabel(Toolkit.i18nText("Fine-Design_Share_Empty_Second"), SwingConstants.CENTER); |
||||
bottomLabel.setForeground(Color.GRAY); |
||||
labelPanel.add(topLabel, BorderLayout.CENTER); |
||||
labelPanel.add(bottomLabel, BorderLayout.SOUTH); |
||||
labelPanel.setPreferredSize(new Dimension(240, 40)); |
||||
panel.add(labelPanel, BorderLayout.SOUTH); |
||||
|
||||
panel.setPreferredSize(new Dimension(240, 180)); |
||||
|
||||
|
||||
JPanel emptyPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||
emptyPanel.setBorder(BorderFactory.createEmptyBorder(100, 0, 0, 0)); |
||||
emptyPanel.add(panel, BorderLayout.NORTH); |
||||
return emptyPanel; |
||||
} |
||||
}, |
||||
|
||||
//加载
|
||||
LOADING { |
||||
@Override |
||||
public JPanel getPanel() { |
||||
return new LoadingPane(); |
||||
} |
||||
}, |
||||
|
||||
//安装
|
||||
INSTALLING { |
||||
@Override |
||||
public JPanel getPanel() { |
||||
return new LoadingPane(Toolkit.i18nText("Fine-Design_Share_installing")); |
||||
} |
||||
}; |
||||
|
||||
public abstract JPanel getPanel(); |
||||
} |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue